QGIS API Documentation 3.29.0-Master (8c80f25a4f)
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"
25#include "qgssettings.h"
26#include "qgsmapcanvas.h"
27#include "qgsgui.h"
28#include "qgsapplication.h"
29#include "qgsmaplayerutils.h"
30#include <QMessageBox>
31#include <QFileDialog>
32#include <QTextCodec>
33#include <QSpinBox>
34#include <QRegularExpression>
35#include "gdal.h"
36#include "qgsdatums.h"
37#include "qgsiconutils.h"
38#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]( QgsWkbTypes::Type type )
147 {
148 mGeometryTypeComboBox->addItem( QgsIconUtils::iconForWkbType( type ), QgsWkbTypes::translatedDisplayString( type ), type );
149 };
150
151 //add geometry types to combobox
152 mGeometryTypeComboBox->addItem( tr( "Automatic" ), -1 );
153 addGeomItem( QgsWkbTypes::Point );
154 addGeomItem( QgsWkbTypes::LineString );
155 addGeomItem( QgsWkbTypes::Polygon );
157 addGeomItem( QgsWkbTypes::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->setValue( opt->defaultValue );
250 control = sb;
251 }
252 break;
253 }
254
256 {
257 QgsVectorFileWriter::SetOption *opt = dynamic_cast<QgsVectorFileWriter::SetOption *>( option );
258 if ( opt )
259 {
260 QComboBox *cb = new QComboBox();
261 cb->setObjectName( it.key() );
262 for ( const QString &val : std::as_const( opt->values ) )
263 {
264 cb->addItem( val, val );
265 }
266 if ( opt->allowNone )
267 cb->addItem( tr( "<Default>" ), QVariant( QVariant::String ) );
268 int idx = cb->findText( opt->defaultValue );
269 if ( idx == -1 )
270 idx = cb->findData( QVariant( QVariant::String ) );
271 cb->setCurrentIndex( idx );
272 control = cb;
273 }
274 break;
275 }
276
278 {
280 if ( opt )
281 {
282 QLineEdit *le = new QLineEdit( opt->defaultValue );
283 le->setObjectName( it.key() );
284 control = le;
285 }
286 break;
287 }
288
290 control = nullptr;
291 break;
292 }
293
294 if ( control )
295 {
296 // Pack the tooltip in some html element, so it gets linebreaks.
297 label->setToolTip( QStringLiteral( "<p>%1</p>" ).arg( option->docString.toHtmlEscaped() ) );
298 control->setToolTip( QStringLiteral( "<p>%1</p>" ).arg( option->docString.toHtmlEscaped() ) );
299
300 controls << QPair<QLabel *, QWidget *>( label, control );
301 }
302 }
303
304 return controls;
305}
306
307void QgsVectorLayerSaveAsDialog::accept()
308{
309 if ( QFile::exists( filename() ) )
310 {
311 QgsVectorFileWriter::EditionCapabilities caps =
314 layername() );
315 QMessageBox msgBox;
316 msgBox.setIcon( QMessageBox::Question );
317 msgBox.setWindowTitle( tr( "Save Vector Layer As" ) );
318 QPushButton *overwriteFileButton = msgBox.addButton( tr( "Overwrite File" ), QMessageBox::ActionRole );
319 QPushButton *overwriteLayerButton = msgBox.addButton( tr( "Overwrite Layer" ), QMessageBox::ActionRole );
320 QPushButton *appendToLayerButton = msgBox.addButton( tr( "Append to Layer" ), QMessageBox::ActionRole );
321 msgBox.setStandardButtons( QMessageBox::Cancel );
322 msgBox.setDefaultButton( QMessageBox::Cancel );
323 overwriteFileButton->hide();
324 overwriteLayerButton->hide();
325 appendToLayerButton->hide();
326 if ( layerExists )
327 {
331 {
332 msgBox.setText( tr( "The layer already exists. Do you want to overwrite the whole file or overwrite the layer?" ) );
333 overwriteFileButton->setVisible( true );
334 overwriteLayerButton->setVisible( true );
335 }
337 {
338 msgBox.setText( tr( "The file already exists. Do you want to overwrite it?" ) );
339 overwriteFileButton->setVisible( true );
340 }
341 else if ( ( caps & QgsVectorFileWriter::CanDeleteLayer ) &&
343 {
344 msgBox.setText( tr( "The layer already exists. Do you want to overwrite the whole file, overwrite the layer or append features to the layer?" ) );
345 appendToLayerButton->setVisible( true );
346 overwriteFileButton->setVisible( true );
347 overwriteLayerButton->setVisible( true );
348 }
349 else
350 {
351 msgBox.setText( tr( "The layer already exists. Do you want to overwrite the whole file or append features to the layer?" ) );
352 appendToLayerButton->setVisible( true );
353 overwriteFileButton->setVisible( true );
354 }
355
356 int ret = msgBox.exec();
357 if ( ret == QMessageBox::Cancel )
358 return;
359 if ( msgBox.clickedButton() == overwriteFileButton )
360 mActionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteFile;
361 else if ( msgBox.clickedButton() == overwriteLayerButton )
362 mActionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteLayer;
363 else if ( msgBox.clickedButton() == appendToLayerButton )
364 mActionOnExistingFile = QgsVectorFileWriter::AppendToLayerNoNewFields;
365 }
366 else // !layerExists
367 {
369 {
370 mActionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteLayer;
371 }
372 else
373 {
374 // should not reach here, layer does not exist and cannot add new layer
375 if ( QMessageBox::question( this,
376 tr( "Save Vector Layer As" ),
377 tr( "The file already exists. Do you want to overwrite it?" ) ) == QMessageBox::NoButton )
378 {
379 return;
380 }
381 mActionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteFile;
382 }
383 }
384 }
385
386 if ( mActionOnExistingFile == QgsVectorFileWriter::AppendToLayerNoNewFields )
387 {
389 {
390 if ( QMessageBox::question( this,
391 tr( "Save Vector Layer As" ),
392 tr( "The existing layer has additional fields. Do you want to add the missing fields to the layer?" ) ) == QMessageBox::Yes )
393 {
394 mActionOnExistingFile = QgsVectorFileWriter::AppendToLayerAddFields;
395 }
396 }
397 }
398 else if ( mActionOnExistingFile == QgsVectorFileWriter::CreateOrOverwriteFile && QFile::exists( filename() ) )
399 {
400 const QList<QgsProviderSublayerDetails> sublayers = QgsProviderRegistry::instance()->querySublayers( filename() );
401 QStringList layerList;
402 layerList.reserve( sublayers.size() );
403 for ( const QgsProviderSublayerDetails &sublayer : sublayers )
404 {
405 layerList.append( sublayer.name() );
406 }
407 if ( layerList.length() > 1 )
408 {
409 layerList.sort( Qt::CaseInsensitive );
410 QMessageBox msgBox;
411 msgBox.setIcon( QMessageBox::Warning );
412 msgBox.setWindowTitle( tr( "Overwrite File" ) );
413 msgBox.setText( tr( "This file contains %1 layers that will be lost!\n" ).arg( QLocale().toString( layerList.length() ) ) );
414 msgBox.setDetailedText( tr( "The following layers will be permanently lost:\n\n%1" ).arg( layerList.join( "\n" ) ) );
415 msgBox.setStandardButtons( QMessageBox::Ok | QMessageBox::Cancel );
416 if ( msgBox.exec() == QMessageBox::Cancel )
417 return;
418 }
419 }
420
421 QgsSettings settings;
422 settings.setValue( QStringLiteral( "UI/lastVectorFileFilterDir" ), QFileInfo( filename() ).absolutePath() );
423 settings.setValue( QStringLiteral( "UI/lastVectorFormat" ), format() );
424 settings.setValue( QStringLiteral( "UI/encoding" ), encoding() );
425 QDialog::accept();
426}
427
428void QgsVectorLayerSaveAsDialog::mFormatComboBox_currentIndexChanged( int idx )
429{
430 Q_UNUSED( idx )
431
432 mFilename->setEnabled( true );
433 mFilename->setFilter( QgsVectorFileWriter::filterForDriver( format() ) );
434
435 // if output filename already defined we need to replace old suffix
436 // to avoid double extensions like .gpkg.shp
437 if ( !mFilename->filePath().isEmpty() )
438 {
439 QRegularExpression rx( "\\.(.*?)[\\s]" );
440 QString ext;
441 ext = rx.match( QgsVectorFileWriter::filterForDriver( format() ) ).captured( 1 );
442 if ( !ext.isEmpty() )
443 {
444 QFileInfo fi( mFilename->filePath() );
445 mFilename->setFilePath( QStringLiteral( "%1/%2.%3" ).arg( fi.path() ).arg( fi.baseName() ).arg( ext ) );
446 }
447 }
448
449 bool selectAllFields = true;
450
451 // Is it a format for which fields that have attached widgets of types
452 // ValueMap, ValueRelation, etc. should be by default exported with their displayed
453 // values
454 bool isFormatForFieldsAsDisplayedValues = false;
455
456 const QString sFormat( format() );
457 if ( sFormat == QLatin1String( "DXF" ) || sFormat == QLatin1String( "DGN" ) )
458 {
459 mAttributesSelection->setVisible( false );
460 selectAllFields = false;
461 }
462 else
463 {
464 if ( mOptions & Fields )
465 {
466 mAttributesSelection->setVisible( true );
467 isFormatForFieldsAsDisplayedValues = ( sFormat == QLatin1String( "CSV" ) ||
468 sFormat == QLatin1String( "XLS" ) ||
469 sFormat == QLatin1String( "XLSX" ) ||
470 sFormat == QLatin1String( "ODS" ) );
471 }
472 }
473
474 // Show symbology options only for some formats
475 if ( QgsVectorFileWriter::supportsFeatureStyles( sFormat ) && ( mOptions & Symbology ) )
476 {
477 mSymbologyExportLabel->setVisible( true );
478 mSymbologyExportComboBox->setVisible( true );
479 mScaleLabel->setVisible( true );
480 mScaleWidget->setVisible( true );
481 }
482 else
483 {
484 mSymbologyExportLabel->hide();
485 mSymbologyExportComboBox->hide();
486 mScaleLabel->hide();
487 mScaleWidget->hide();
488 }
489
490 leLayername->setEnabled( sFormat == QLatin1String( "KML" ) ||
491 sFormat == QLatin1String( "GPKG" ) ||
492 sFormat == QLatin1String( "XLSX" ) ||
493 sFormat == QLatin1String( "ODS" ) ||
494 sFormat == QLatin1String( "FileGDB" ) ||
495 sFormat == QLatin1String( "SQLite" ) ||
496 sFormat == QLatin1String( "SpatiaLite" ) );
497
498 if ( sFormat == QLatin1String( "XLSX" ) )
499 leLayername->setMaxLength( 31 );
500 else if ( leLayername->isEnabled() )
501 leLayername->setMaxLength( 32767 ); // default length
502
503 if ( !leLayername->isEnabled() )
504 leLayername->setText( QString() );
505 else if ( leLayername->text().isEmpty() )
506 {
507 QString layerName = mDefaultOutputLayerNameFromInputLayerName;
508 if ( layerName.isEmpty() && !mFilename->filePath().isEmpty() )
509 {
510 layerName = QFileInfo( mFilename->filePath() ).baseName();
511 leLayername->setDefaultValue( layerName );
512 }
513 if ( layerName.isEmpty() )
514 layerName = tr( "new_layer" );
515 leLayername->setText( layerName );
516 }
517
518 if ( mLayer )
519 {
520 mAttributeTable->setRowCount( mLayer->fields().count() );
521
522 QStringList horizontalHeaders = QStringList() << tr( "Name" ) << tr( "Export name" ) << tr( "Type" ) << tr( "Replace with displayed values" );
523 mAttributeTable->setColumnCount( horizontalHeaders.size() );
524 mAttributeTable->setHorizontalHeaderLabels( horizontalHeaders );
525
526 bool foundFieldThatCanBeExportedAsDisplayedValue = false;
527 for ( int i = 0; i < mLayer->fields().size(); ++i )
528 {
529 const QgsEditorWidgetSetup setup = QgsGui::editorWidgetRegistry()->findBest( mLayer, mLayer->fields()[i].name() );
530 if ( setup.type() != QLatin1String( "TextEdit" ) &&
531 QgsGui::editorWidgetRegistry()->factory( setup.type() ) )
532 {
533 foundFieldThatCanBeExportedAsDisplayedValue = true;
534 break;
535 }
536 }
537 mAttributeTable->setColumnHidden( static_cast<int>( ColumnIndex::ExportAsDisplayedValue ),
538 ! foundFieldThatCanBeExportedAsDisplayedValue );
539
540 bool checkReplaceRawFieldValues = selectAllFields && isFormatForFieldsAsDisplayedValues;
541 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
542 {
543 for ( int i = 0; i < mLayer->fields().size(); ++i )
544 {
545 QgsField fld = mLayer->fields().at( i );
546 Qt::ItemFlags flags = mLayer->providerType() != QLatin1String( "oracle" ) || !fld.typeName().contains( QLatin1String( "SDO_GEOMETRY" ) ) ? Qt::ItemIsEnabled : Qt::NoItemFlags;
547 QTableWidgetItem *item = nullptr;
548 item = new QTableWidgetItem( fld.name() );
549 item->setFlags( flags | Qt::ItemIsUserCheckable );
550 item->setCheckState( ( selectAllFields ) ? Qt::Checked : Qt::Unchecked );
551 mAttributeTable->setItem( i, static_cast<int>( ColumnIndex::Name ), item );
552
553 item = new QTableWidgetItem( fld.name() );
554 item->setFlags( flags | Qt::ItemIsEditable );
555 item->setData( Qt::UserRole, fld.displayName() );
556 mAttributeTable->setItem( i, static_cast<int>( ColumnIndex::ExportName ), item );
557
558 item = new QTableWidgetItem( fld.typeName() );
559 item->setFlags( flags );
560 mAttributeTable->setItem( i, static_cast<int>( ColumnIndex::Type ), item );
561
562 if ( foundFieldThatCanBeExportedAsDisplayedValue )
563 {
564 const QgsEditorWidgetSetup setup = QgsGui::editorWidgetRegistry()->findBest( mLayer, mLayer->fields()[i].name() );
565 QgsEditorWidgetFactory *factory = nullptr;
566 const QString widgetId( setup.type() );
567 if ( flags == Qt::ItemIsEnabled &&
568 widgetId != QLatin1String( "TextEdit" ) &&
569 ( factory = QgsGui::editorWidgetRegistry()->factory( widgetId ) ) )
570 {
571 item = new QTableWidgetItem( tr( "Use %1" ).arg( factory->name() ) );
572 item->setFlags( ( selectAllFields ) ? ( Qt::ItemIsEnabled | Qt::ItemIsUserCheckable ) : Qt::ItemIsUserCheckable );
573 const bool checkItem = ( selectAllFields && isFormatForFieldsAsDisplayedValues &&
574 ( widgetId == QLatin1String( "ValueMap" ) ||
575 widgetId == QLatin1String( "ValueRelation" ) ||
576 widgetId == QLatin1String( "CheckBox" ) ||
577 widgetId == QLatin1String( "RelationReference" ) ) );
578 checkReplaceRawFieldValues &= checkItem;
579 item->setCheckState( checkItem ?
580 Qt::Checked : Qt::Unchecked );
581 mAttributeTable->setItem( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ), item );
582 }
583 else
584 {
585 item = new QTableWidgetItem();
586 item->setFlags( Qt::NoItemFlags );
587 mAttributeTable->setItem( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ), item );
588 }
589 }
590 }
591 }
592
593 whileBlocking( mReplaceRawFieldValues )->setChecked( checkReplaceRawFieldValues );
594 mReplaceRawFieldValues->setEnabled( selectAllFields );
595 mReplaceRawFieldValues->setVisible( foundFieldThatCanBeExportedAsDisplayedValue );
596
597 mAttributeTable->resizeColumnsToContents();
598 }
599
600 QgsVectorFileWriter::MetaData driverMetaData;
601
602 while ( mDatasourceOptionsGroupBox->layout()->count() )
603 {
604 QLayoutItem *item = mDatasourceOptionsGroupBox->layout()->takeAt( 0 );
605 delete item->widget();
606 delete item;
607 }
608
609 while ( mLayerOptionsGroupBox->layout()->count() )
610 {
611 QLayoutItem *item = mLayerOptionsGroupBox->layout()->takeAt( 0 );
612 delete item->widget();
613 delete item;
614 }
615
616 typedef QPair<QLabel *, QWidget *> LabelControlPair;
617
618 if ( QgsVectorFileWriter::driverMetadata( format(), driverMetaData ) )
619 {
620 if ( !driverMetaData.driverOptions.empty() )
621 {
622 mDatasourceOptionsGroupBox->setVisible( true );
623 QList<QPair<QLabel *, QWidget *> > controls = createControls( driverMetaData.driverOptions );
624
625 QFormLayout *datasourceLayout = dynamic_cast<QFormLayout *>( mDatasourceOptionsGroupBox->layout() );
626
627 const auto constControls = controls;
628 for ( LabelControlPair control : constControls )
629 {
630 datasourceLayout->addRow( control.first, control.second );
631 }
632 }
633 else
634 {
635 mDatasourceOptionsGroupBox->setVisible( false );
636 }
637
638 if ( !driverMetaData.layerOptions.empty() )
639 {
640 mLayerOptionsGroupBox->setVisible( true );
641 QList<QPair<QLabel *, QWidget *> > controls = createControls( driverMetaData.layerOptions );
642
643 QFormLayout *layerOptionsLayout = dynamic_cast<QFormLayout *>( mLayerOptionsGroupBox->layout() );
644
645 const auto constControls = controls;
646 for ( LabelControlPair control : constControls )
647 {
648 layerOptionsLayout->addRow( control.first, control.second );
649 }
650 }
651 else
652 {
653 mLayerOptionsGroupBox->setVisible( false );
654 }
655
656 if ( driverMetaData.compulsoryEncoding.isEmpty() )
657 {
658 mEncodingComboBox->setEnabled( true );
659 }
660 else
661 {
662 int idx = mEncodingComboBox->findText( driverMetaData.compulsoryEncoding );
663 if ( idx >= 0 )
664 {
665 mEncodingComboBox->setCurrentIndex( idx );
666 mEncodingComboBox->setDisabled( true );
667 }
668 else
669 {
670 mEncodingComboBox->setEnabled( true );
671 }
672 }
673
674 }
675 else
676 {
677 mEncodingComboBox->setEnabled( true );
678 }
679
680 GDALDriverH hDriver = GDALGetDriverByName( format().toUtf8().constData() );
681 if ( hDriver )
682 {
683 mAddToCanvas->setEnabled( GDALGetMetadataItem( hDriver, GDAL_DCAP_OPEN, nullptr ) != nullptr );
684 }
685}
686
687void QgsVectorLayerSaveAsDialog::mUseAliasesForExportedName_stateChanged( int state )
688{
689 const QSignalBlocker signalBlocker( mAttributeTable );
690
691 switch ( state )
692 {
693 case Qt::Unchecked:
694 {
695 // Check for modified entries
696 bool modifiedEntries = false;
697 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
698 {
699 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportName ) )->text()
700 != mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportName ) )->data( Qt::UserRole ).toString() )
701 {
702 modifiedEntries = true;
703 break;
704 }
705 }
706
707 if ( modifiedEntries )
708 {
709 if ( QMessageBox::question( this,
710 tr( "Modified names" ),
711 tr( "Some names were modified and will be overridden. Do you want to continue?" ) )
712 == QMessageBox::No )
713 {
714 whileBlocking( mUseAliasesForExportedName )->setCheckState( Qt::PartiallyChecked );
715 return;
716 }
717 }
718
719 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
720 {
721 mUseAliasesForExportedName->setTristate( false );
722 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportName ) )->setText( mAttributeTable->item( i, static_cast<int>( ColumnIndex::Name ) )->text() );
723 }
724 }
725 break;
726 case Qt::Checked:
727 {
728 // Check for modified entries
729 bool modifiedEntries = false;
730 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
731 {
732 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportName ) )->text()
733 != mAttributeTable->item( i, static_cast<int>( ColumnIndex::Name ) )->text() )
734 modifiedEntries = true;
735 }
736
737 if ( modifiedEntries )
738 {
739 if ( QMessageBox::question( this,
740 tr( "Modified names" ),
741 tr( "Some names were modified and will be overridden. Do you want to continue?" ) )
742 == QMessageBox::No )
743 {
744 whileBlocking( mUseAliasesForExportedName )->setCheckState( Qt::PartiallyChecked );
745 return;
746 }
747 }
748
749 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
750 {
751 mUseAliasesForExportedName->setTristate( false );
752 const QString alias = mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportName ) )->data( Qt::UserRole ).toString();
753 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportName ) )->setText( alias );
754 }
755 }
756 break;
757 case Qt::PartiallyChecked:
758 // Do nothing
759 break;
760 }
761}
762
763void QgsVectorLayerSaveAsDialog::mReplaceRawFieldValues_stateChanged( int )
764{
765 if ( mAttributeTable->isColumnHidden( static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
766 return;
767
768 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
769 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
770
771 if ( mReplaceRawFieldValues->checkState() != Qt::PartiallyChecked )
772 {
773 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
774 {
775 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::Name ) )->checkState() == Qt::Checked &&
776 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
777 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsEnabled )
778 {
779 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( mReplaceRawFieldValues->checkState() );
780 }
781 }
782 }
783 mReplaceRawFieldValues->setTristate( false );
784}
785
786void QgsVectorLayerSaveAsDialog::mAttributeTable_itemChanged( QTableWidgetItem *item )
787{
788 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
789 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
790
791 int row = item->row();
792 int column = item->column();
793
794 switch ( static_cast<ColumnIndex>( column ) )
795 {
796 case ColumnIndex::Name:
797 {
798 if ( mAttributeTable->isColumnHidden( static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) ||
799 ! mAttributeTable->item( row, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) ||
800 !( mAttributeTable->item( row, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsUserCheckable ) )
801 return;
802
803 if ( mAttributeTable->item( row, column )->checkState() == Qt::Unchecked )
804 {
805 mAttributeTable->item( row, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( Qt::Unchecked );
806 mAttributeTable->item( row, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable );
807 bool checkBoxEnabled = false;
808 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
809 {
810 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
811 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsEnabled )
812 {
813 checkBoxEnabled = true;
814 break;
815 }
816 }
817 mReplaceRawFieldValues->setEnabled( checkBoxEnabled );
818 if ( !checkBoxEnabled )
819 mReplaceRawFieldValues->setCheckState( Qt::Unchecked );
820 }
821 else if ( mAttributeTable->item( row, column )->checkState() == Qt::Checked )
822 {
823 mAttributeTable->item( row, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsEnabled );
824 mReplaceRawFieldValues->setEnabled( true );
825 }
826 }
827 break;
828 case ColumnIndex::ExportName:
829 {
830 // Check empty export name
831 if ( item->text().isEmpty() )
832 {
833 QMessageBox::warning( this,
834 tr( "Empty export name" ),
835 tr( "Empty export name are not allowed." ) );
836 return;
837 }
838
839 // Rename eventually duplicated names
840 QStringList names = attributesExportNames();
841 while ( names.count( item->text() ) > 1 )
842 item->setText( QString( "%1_2" ).arg( item->text() ) );
843
844 mUseAliasesForExportedName->setCheckState( Qt::PartiallyChecked );
845 }
846 break;
847 case ColumnIndex::Type:
848 // Nothing to do
849 break;
850 case ColumnIndex::ExportAsDisplayedValue:
851 {
852 if ( mAttributeTable->item( row, column )->flags() & Qt::ItemIsUserCheckable )
853 {
854 bool allChecked = true;
855 bool allUnchecked = true;
856 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
857 {
858 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
859 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsEnabled )
860 {
861 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->checkState() == Qt::Unchecked )
862 allChecked = false;
863 else
864 allUnchecked = false;
865 }
866 }
867 mReplaceRawFieldValues->setCheckState( ( !allChecked && !allUnchecked ) ? Qt::PartiallyChecked : ( allChecked ) ? Qt::Checked : Qt::Unchecked );
868 }
869 }
870 break;
871 }
872}
873
874void QgsVectorLayerSaveAsDialog::mCrsSelector_crsChanged( const QgsCoordinateReferenceSystem &crs )
875{
876 mSelectedCrs = crs;
877 mExtentGroupBox->setOutputCrs( mSelectedCrs );
878}
879
881{
882 return mFilename->filePath();
883}
884
886{
887 return leLayername->text();
888}
889
891{
892 return mEncodingComboBox->currentText();
893}
894
896{
897 return mFormatComboBox->currentData().toString();
898}
899
901{
902 return mSelectedCrs.srsid();
903}
904
906{
907 return mSelectedCrs;
908}
909
911{
912 QStringList options;
913
914 QgsVectorFileWriter::MetaData driverMetaData;
915
916 if ( QgsVectorFileWriter::driverMetadata( format(), driverMetaData ) )
917 {
918 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
919
920 for ( it = driverMetaData.driverOptions.constBegin(); it != driverMetaData.driverOptions.constEnd(); ++it )
921 {
922 switch ( it.value()->type )
923 {
925 {
927 QSpinBox *sb = mDatasourceOptionsGroupBox->findChild<QSpinBox *>( it.key() );
928 if ( opt && sb && sb->value() != opt->defaultValue )
929 options << QStringLiteral( "%1=%2" ).arg( it.key() ).arg( sb->value() );
930 break;
931 }
932
934 {
936 QComboBox *cb = mDatasourceOptionsGroupBox->findChild<QComboBox *>( it.key() );
937 if ( opt && cb && cb->itemData( cb->currentIndex() ) != opt->defaultValue )
938 options << QStringLiteral( "%1=%2" ).arg( it.key(), cb->currentText() );
939 break;
940 }
941
943 {
945 QLineEdit *le = mDatasourceOptionsGroupBox->findChild<QLineEdit *>( it.key() );
946 if ( opt && le && le->text() != opt->defaultValue )
947 options << QStringLiteral( "%1=%2" ).arg( it.key(), le->text() );
948 break;
949 }
950
952 {
954 dynamic_cast<QgsVectorFileWriter::HiddenOption *>( it.value() );
955 options << QStringLiteral( "%1=%2" ).arg( it.key(), opt->mValue );
956 break;
957 }
958 }
959 }
960 }
961
962 QString plainText = mOgrDatasourceOptions->toPlainText().trimmed();
963 if ( !plainText.isEmpty() )
964 options += plainText.split( '\n' );
965
966 return options;
967}
968
970{
971 QStringList options;
972
973 QgsVectorFileWriter::MetaData driverMetaData;
974
975 if ( QgsVectorFileWriter::driverMetadata( format(), driverMetaData ) )
976 {
977 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
978
979 for ( it = driverMetaData.layerOptions.constBegin(); it != driverMetaData.layerOptions.constEnd(); ++it )
980 {
981 switch ( it.value()->type )
982 {
984 {
986 QSpinBox *sb = mLayerOptionsGroupBox->findChild<QSpinBox *>( it.key() );
987 if ( opt && sb && sb->value() != opt->defaultValue )
988 options << QStringLiteral( "%1=%2" ).arg( it.key() ).arg( sb->value() );
989 break;
990 }
991
993 {
995 QComboBox *cb = mLayerOptionsGroupBox->findChild<QComboBox *>( it.key() );
996 if ( opt && cb && cb->itemData( cb->currentIndex() ) != opt->defaultValue )
997 options << QStringLiteral( "%1=%2" ).arg( it.key(), cb->currentText() );
998 break;
999 }
1000
1002 {
1004 QLineEdit *le = mLayerOptionsGroupBox->findChild<QLineEdit *>( it.key() );
1005 if ( opt && le && le->text() != opt->defaultValue )
1006 options << QStringLiteral( "%1=%2" ).arg( it.key(), le->text() );
1007 break;
1008 }
1009
1011 {
1013 dynamic_cast<QgsVectorFileWriter::HiddenOption *>( it.value() );
1014 options << QStringLiteral( "%1=%2" ).arg( it.key(), opt->mValue );
1015 break;
1016 }
1017 }
1018 }
1019 }
1020
1021 QString plainText = mOgrLayerOptions->toPlainText().trimmed();
1022 if ( !plainText.isEmpty() )
1023 options += plainText.split( '\n' );
1024
1025 return options;
1026}
1027
1029{
1030 QgsAttributeList attributes;
1031
1032 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
1033 {
1034 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::Name ) )->checkState() == Qt::Checked )
1035 {
1036 attributes.append( i );
1037 }
1038 }
1039
1040 return attributes;
1041}
1042
1044{
1045 QgsAttributeList attributes;
1046
1047 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
1048 {
1049 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::Name ) )->checkState() == Qt::Checked &&
1050 ! mAttributeTable->isColumnHidden( static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
1051 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->checkState() == Qt::Checked )
1052 {
1053 attributes.append( i );
1054 }
1055 }
1056
1057 return attributes;
1058}
1059
1061{
1062 QStringList exportNames;
1063 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
1064 exportNames.append( mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportName ) )->text() );
1065
1066 return exportNames;
1067}
1068
1070{
1071 return mAddToCanvas->isChecked() && mAddToCanvas->isEnabled();
1072}
1073
1075{
1076 mAddToCanvas->setChecked( enabled );
1077}
1078
1080{
1081 return mSymbologyExportComboBox->currentData().toInt();
1082}
1083
1085{
1086 return mScaleWidget->scale();
1087}
1088
1090{
1091 mMapCanvas = canvas;
1092 mScaleWidget->setMapCanvas( canvas );
1093 mScaleWidget->setShowCurrentScaleButton( true );
1094 mExtentGroupBox->setCurrentExtent( canvas->mapSettings().visibleExtent(), canvas->mapSettings().destinationCrs() );
1095}
1096
1098{
1099 return mExtentGroupBox->isChecked();
1100}
1101
1103{
1104 return mExtentGroupBox->outputExtent();
1105}
1106
1108{
1109 mSelectedOnly->setChecked( onlySelected );
1110}
1111
1113{
1114 return mSelectedOnly->isChecked();
1115}
1116
1118{
1119 return mCheckPersistMetadata->isChecked();
1120}
1121
1123{
1124 int currentIndexData = mGeometryTypeComboBox->currentData().toInt();
1125 if ( currentIndexData == -1 )
1126 {
1127 //automatic
1128 return QgsWkbTypes::Unknown;
1129 }
1130
1131 return static_cast< QgsWkbTypes::Type >( currentIndexData );
1132}
1133
1135{
1136 int currentIndexData = mGeometryTypeComboBox->currentData().toInt();
1137 return currentIndexData == -1;
1138}
1139
1141{
1142 return mForceMultiCheckBox->isChecked();
1143}
1144
1146{
1147 mForceMultiCheckBox->setChecked( checked );
1148}
1149
1151{
1152 return mIncludeZCheckBox->isChecked();
1153}
1154
1156{
1157 return mActionOnExistingFile;
1158}
1159
1161{
1162 mIncludeZCheckBox->setChecked( checked );
1163}
1164
1165void QgsVectorLayerSaveAsDialog::mSymbologyExportComboBox_currentIndexChanged( const QString &text )
1166{
1167 bool scaleEnabled = true;
1168 if ( text == tr( "No symbology" ) )
1169 {
1170 scaleEnabled = false;
1171 }
1172 mScaleWidget->setEnabled( scaleEnabled );
1173 mScaleLabel->setEnabled( scaleEnabled );
1174}
1175
1176void QgsVectorLayerSaveAsDialog::mGeometryTypeComboBox_currentIndexChanged( int index )
1177{
1178 int currentIndexData = mGeometryTypeComboBox->itemData( index ).toInt();
1179
1180 if ( currentIndexData != -1 && currentIndexData != QgsWkbTypes::NoGeometry )
1181 {
1182 mForceMultiCheckBox->setEnabled( true );
1183 mIncludeZCheckBox->setEnabled( true );
1184 }
1185 else
1186 {
1187 mForceMultiCheckBox->setEnabled( false );
1188 mForceMultiCheckBox->setChecked( false );
1189 mIncludeZCheckBox->setEnabled( false );
1190 mIncludeZCheckBox->setChecked( false );
1191 }
1192}
1193
1194void QgsVectorLayerSaveAsDialog::mSelectAllAttributes_clicked()
1195{
1196 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
1197 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
1198
1199 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
1200 {
1201 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::Name ) )->flags() & Qt::ItemIsEnabled )
1202 {
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 | Qt::ItemIsEnabled );
1207 }
1208 mAttributeTable->item( i, static_cast<int>( ColumnIndex::Name ) )->setCheckState( Qt::Checked );
1209 }
1210 }
1211 if ( ! mAttributeTable->isColumnHidden( static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
1212 {
1213 mReplaceRawFieldValues->setEnabled( true );
1214 }
1215}
1216
1217void QgsVectorLayerSaveAsDialog::mDeselectAllAttributes_clicked()
1218{
1219 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
1220 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
1221
1222 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
1223 {
1224 mAttributeTable->item( i, static_cast<int>( ColumnIndex::Name ) )->setCheckState( Qt::Unchecked );
1225 if ( ! mAttributeTable->isColumnHidden( static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
1226 ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsUserCheckable ) )
1227 {
1228 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable );
1229 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( Qt::Unchecked );
1230 }
1231 }
1232 if ( ! mAttributeTable->isColumnHidden( static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
1233 {
1234 mReplaceRawFieldValues->setCheckState( Qt::Unchecked );
1235 mReplaceRawFieldValues->setEnabled( false );
1236 }
1237}
1238
1239void QgsVectorLayerSaveAsDialog::showHelp()
1240{
1241 QgsHelp::openHelp( QStringLiteral( "managing_data_source/create_layers.html#creating-new-layers-from-an-existing-layer" ) );
1242}
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:140
QString name
Definition: qgsfield.h:60
QString displayName() const
Returns the name to use when displaying this field.
Definition: qgsfield.cpp:90
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(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.
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: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:2841
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,...