QGIS API Documentation 3.32.0-Lima (311a8cb8a6)
•All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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, QgsVectorLayerSaveAsDialog::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 & Option::Symbology ) )
72 {
73 mSymbologyExportLabel->hide();
74 mSymbologyExportComboBox->hide();
75 mScaleLabel->hide();
76 mScaleWidget->hide();
77 }
78
79 if ( !( mOptions & Option::DestinationCrs ) )
80 {
81 mCrsLabel->hide();
82 mCrsSelector->hide();
83 }
84 if ( !( mOptions & Option::Fields ) )
85 mAttributesSelection->hide();
86
87 if ( !( mOptions & Option::SelectedOnly ) )
88 mSelectedOnly->hide();
89
90 if ( !( mOptions & Option::AddToCanvas ) )
91 mAddToCanvas->hide();
92
93 if ( !( mOptions & Option::GeometryType ) )
94 mGeometryGroupBox->hide();
95
96 if ( !( mOptions & Option::Extent ) )
97 mExtentGroupBox->hide();
98
99 if ( !( mOptions & Option::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" ), QVariant::fromValue( Qgis::FeatureSymbologyExport::NoSymbology ) );
180 mSymbologyExportComboBox->addItem( tr( "Feature Symbology" ), QVariant::fromValue( Qgis::FeatureSymbologyExport::PerFeature ) );
181 mSymbologyExportComboBox->addItem( tr( "Symbol Layer Symbology" ), QVariant::fromValue( Qgis::FeatureSymbologyExport::PerSymbolLayer ) );
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
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 const thread_local QRegularExpression rx( "\\.(.*?)[\\s]" );
441 const QString 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(), fi.baseName(), 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 & Option::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 & Option::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( "OpenFileGDB" ) ||
496 sFormat == QLatin1String( "SQLite" ) ||
497 sFormat == QLatin1String( "SpatiaLite" ) );
498
499 if ( sFormat == QLatin1String( "XLSX" ) )
500 leLayername->setMaxLength( 31 );
501 else if ( leLayername->isEnabled() )
502 leLayername->setMaxLength( 32767 ); // default length
503
504 if ( !leLayername->isEnabled() )
505 leLayername->setText( QString() );
506 else if ( leLayername->text().isEmpty() )
507 {
508 QString layerName = mDefaultOutputLayerNameFromInputLayerName;
509 if ( layerName.isEmpty() && !mFilename->filePath().isEmpty() )
510 {
511 layerName = QFileInfo( mFilename->filePath() ).baseName();
512 leLayername->setDefaultValue( layerName );
513 }
514 if ( layerName.isEmpty() )
515 layerName = tr( "new_layer" );
516 leLayername->setText( layerName );
517 }
518
519 if ( mLayer )
520 {
521 mAttributeTable->setRowCount( mLayer->fields().count() );
522
523 QStringList horizontalHeaders = QStringList() << tr( "Name" ) << tr( "Export name" ) << tr( "Type" ) << tr( "Replace with displayed values" );
524 mAttributeTable->setColumnCount( horizontalHeaders.size() );
525 mAttributeTable->setHorizontalHeaderLabels( horizontalHeaders );
526
527 bool foundFieldThatCanBeExportedAsDisplayedValue = false;
528 for ( int i = 0; i < mLayer->fields().size(); ++i )
529 {
530 const QgsEditorWidgetSetup setup = QgsGui::editorWidgetRegistry()->findBest( mLayer, mLayer->fields()[i].name() );
531 if ( setup.type() != QLatin1String( "TextEdit" ) &&
532 QgsGui::editorWidgetRegistry()->factory( setup.type() ) )
533 {
534 foundFieldThatCanBeExportedAsDisplayedValue = true;
535 break;
536 }
537 }
538 mAttributeTable->setColumnHidden( static_cast<int>( ColumnIndex::ExportAsDisplayedValue ),
539 ! foundFieldThatCanBeExportedAsDisplayedValue );
540
541 bool checkReplaceRawFieldValues = selectAllFields && isFormatForFieldsAsDisplayedValues;
542 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
543 {
544 for ( int i = 0; i < mLayer->fields().size(); ++i )
545 {
546 QgsField fld = mLayer->fields().at( i );
547 Qt::ItemFlags flags = mLayer->providerType() != QLatin1String( "oracle" ) || !fld.typeName().contains( QLatin1String( "SDO_GEOMETRY" ) ) ? Qt::ItemIsEnabled : Qt::NoItemFlags;
548 QTableWidgetItem *item = nullptr;
549 item = new QTableWidgetItem( fld.name() );
550 item->setFlags( flags | Qt::ItemIsUserCheckable );
551 item->setCheckState( ( selectAllFields ) ? Qt::Checked : Qt::Unchecked );
552 mAttributeTable->setItem( i, static_cast<int>( ColumnIndex::Name ), item );
553
554 item = new QTableWidgetItem( fld.name() );
555 item->setFlags( flags | Qt::ItemIsEditable );
556 item->setData( Qt::UserRole, fld.displayName() );
557 mAttributeTable->setItem( i, static_cast<int>( ColumnIndex::ExportName ), item );
558
559 item = new QTableWidgetItem( fld.typeName() );
560 item->setFlags( flags );
561 mAttributeTable->setItem( i, static_cast<int>( ColumnIndex::Type ), item );
562
563 if ( foundFieldThatCanBeExportedAsDisplayedValue )
564 {
565 const QgsEditorWidgetSetup setup = QgsGui::editorWidgetRegistry()->findBest( mLayer, mLayer->fields()[i].name() );
566 QgsEditorWidgetFactory *factory = nullptr;
567 const QString widgetId( setup.type() );
568 if ( flags == Qt::ItemIsEnabled &&
569 widgetId != QLatin1String( "TextEdit" ) &&
570 ( factory = QgsGui::editorWidgetRegistry()->factory( widgetId ) ) )
571 {
572 item = new QTableWidgetItem( tr( "Use %1" ).arg( factory->name() ) );
573 item->setFlags( ( selectAllFields ) ? ( Qt::ItemIsEnabled | Qt::ItemIsUserCheckable ) : Qt::ItemIsUserCheckable );
574 const bool checkItem = ( selectAllFields && isFormatForFieldsAsDisplayedValues &&
575 ( widgetId == QLatin1String( "ValueMap" ) ||
576 widgetId == QLatin1String( "ValueRelation" ) ||
577 widgetId == QLatin1String( "CheckBox" ) ||
578 widgetId == QLatin1String( "RelationReference" ) ) );
579 checkReplaceRawFieldValues &= checkItem;
580 item->setCheckState( checkItem ?
581 Qt::Checked : Qt::Unchecked );
582 mAttributeTable->setItem( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ), item );
583 }
584 else
585 {
586 item = new QTableWidgetItem();
587 item->setFlags( Qt::NoItemFlags );
588 mAttributeTable->setItem( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ), item );
589 }
590 }
591 }
592 }
593
594 whileBlocking( mReplaceRawFieldValues )->setChecked( checkReplaceRawFieldValues );
595 mReplaceRawFieldValues->setEnabled( selectAllFields );
596 mReplaceRawFieldValues->setVisible( foundFieldThatCanBeExportedAsDisplayedValue );
597
598 mAttributeTable->resizeColumnsToContents();
599 }
600
601 QgsVectorFileWriter::MetaData driverMetaData;
602
603 while ( mDatasourceOptionsGroupBox->layout()->count() )
604 {
605 QLayoutItem *item = mDatasourceOptionsGroupBox->layout()->takeAt( 0 );
606 delete item->widget();
607 delete item;
608 }
609
610 while ( mLayerOptionsGroupBox->layout()->count() )
611 {
612 QLayoutItem *item = mLayerOptionsGroupBox->layout()->takeAt( 0 );
613 delete item->widget();
614 delete item;
615 }
616
617 typedef QPair<QLabel *, QWidget *> LabelControlPair;
618
619 if ( QgsVectorFileWriter::driverMetadata( format(), driverMetaData ) )
620 {
621 if ( !driverMetaData.driverOptions.empty() )
622 {
623 mDatasourceOptionsGroupBox->setVisible( true );
624 QList<QPair<QLabel *, QWidget *> > controls = createControls( driverMetaData.driverOptions );
625
626 QFormLayout *datasourceLayout = dynamic_cast<QFormLayout *>( mDatasourceOptionsGroupBox->layout() );
627
628 const auto constControls = controls;
629 for ( LabelControlPair control : constControls )
630 {
631 datasourceLayout->addRow( control.first, control.second );
632 }
633 }
634 else
635 {
636 mDatasourceOptionsGroupBox->setVisible( false );
637 }
638
639 if ( !driverMetaData.layerOptions.empty() )
640 {
641 mLayerOptionsGroupBox->setVisible( true );
642 QList<QPair<QLabel *, QWidget *> > controls = createControls( driverMetaData.layerOptions );
643
644 QFormLayout *layerOptionsLayout = dynamic_cast<QFormLayout *>( mLayerOptionsGroupBox->layout() );
645
646 const auto constControls = controls;
647 for ( LabelControlPair control : constControls )
648 {
649 layerOptionsLayout->addRow( control.first, control.second );
650 }
651 }
652 else
653 {
654 mLayerOptionsGroupBox->setVisible( false );
655 }
656
657 if ( driverMetaData.compulsoryEncoding.isEmpty() )
658 {
659 mEncodingComboBox->setEnabled( true );
660 }
661 else
662 {
663 int idx = mEncodingComboBox->findText( driverMetaData.compulsoryEncoding );
664 if ( idx >= 0 )
665 {
666 mEncodingComboBox->setCurrentIndex( idx );
667 mEncodingComboBox->setDisabled( true );
668 }
669 else
670 {
671 mEncodingComboBox->setEnabled( true );
672 }
673 }
674
675 }
676 else
677 {
678 mEncodingComboBox->setEnabled( true );
679 }
680
681 GDALDriverH hDriver = GDALGetDriverByName( format().toUtf8().constData() );
682 if ( hDriver )
683 {
684 mAddToCanvas->setEnabled( GDALGetMetadataItem( hDriver, GDAL_DCAP_OPEN, nullptr ) != nullptr );
685 }
686}
687
688void QgsVectorLayerSaveAsDialog::mUseAliasesForExportedName_stateChanged( int state )
689{
690 const QSignalBlocker signalBlocker( mAttributeTable );
691
692 switch ( state )
693 {
694 case Qt::Unchecked:
695 {
696 // Check for modified entries
697 bool modifiedEntries = false;
698 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
699 {
700 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportName ) )->text()
701 != mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportName ) )->data( Qt::UserRole ).toString() )
702 {
703 modifiedEntries = true;
704 break;
705 }
706 }
707
708 if ( modifiedEntries )
709 {
710 if ( QMessageBox::question( this,
711 tr( "Modified names" ),
712 tr( "Some names were modified and will be overridden. Do you want to continue?" ) )
713 == QMessageBox::No )
714 {
715 whileBlocking( mUseAliasesForExportedName )->setCheckState( Qt::PartiallyChecked );
716 return;
717 }
718 }
719
720 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
721 {
722 mUseAliasesForExportedName->setTristate( false );
723 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportName ) )->setText( mAttributeTable->item( i, static_cast<int>( ColumnIndex::Name ) )->text() );
724 }
725 }
726 break;
727 case Qt::Checked:
728 {
729 // Check for modified entries
730 bool modifiedEntries = false;
731 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
732 {
733 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportName ) )->text()
734 != mAttributeTable->item( i, static_cast<int>( ColumnIndex::Name ) )->text() )
735 modifiedEntries = true;
736 }
737
738 if ( modifiedEntries )
739 {
740 if ( QMessageBox::question( this,
741 tr( "Modified names" ),
742 tr( "Some names were modified and will be overridden. Do you want to continue?" ) )
743 == QMessageBox::No )
744 {
745 whileBlocking( mUseAliasesForExportedName )->setCheckState( Qt::PartiallyChecked );
746 return;
747 }
748 }
749
750 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
751 {
752 mUseAliasesForExportedName->setTristate( false );
753 const QString alias = mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportName ) )->data( Qt::UserRole ).toString();
754 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportName ) )->setText( alias );
755 }
756 }
757 break;
758 case Qt::PartiallyChecked:
759 // Do nothing
760 break;
761 }
762}
763
764void QgsVectorLayerSaveAsDialog::mReplaceRawFieldValues_stateChanged( int )
765{
766 if ( mAttributeTable->isColumnHidden( static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
767 return;
768
769 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
770 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
771
772 if ( mReplaceRawFieldValues->checkState() != Qt::PartiallyChecked )
773 {
774 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
775 {
776 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::Name ) )->checkState() == Qt::Checked &&
777 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
778 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsEnabled )
779 {
780 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( mReplaceRawFieldValues->checkState() );
781 }
782 }
783 }
784 mReplaceRawFieldValues->setTristate( false );
785}
786
787void QgsVectorLayerSaveAsDialog::mAttributeTable_itemChanged( QTableWidgetItem *item )
788{
789 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
790 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
791
792 int row = item->row();
793 int column = item->column();
794
795 switch ( static_cast<ColumnIndex>( column ) )
796 {
797 case ColumnIndex::Name:
798 {
799 if ( mAttributeTable->isColumnHidden( static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) ||
800 ! mAttributeTable->item( row, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) ||
801 !( mAttributeTable->item( row, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsUserCheckable ) )
802 return;
803
804 if ( mAttributeTable->item( row, column )->checkState() == Qt::Unchecked )
805 {
806 mAttributeTable->item( row, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( Qt::Unchecked );
807 mAttributeTable->item( row, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable );
808 bool checkBoxEnabled = false;
809 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
810 {
811 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
812 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsEnabled )
813 {
814 checkBoxEnabled = true;
815 break;
816 }
817 }
818 mReplaceRawFieldValues->setEnabled( checkBoxEnabled );
819 if ( !checkBoxEnabled )
820 mReplaceRawFieldValues->setCheckState( Qt::Unchecked );
821 }
822 else if ( mAttributeTable->item( row, column )->checkState() == Qt::Checked )
823 {
824 mAttributeTable->item( row, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsEnabled );
825 mReplaceRawFieldValues->setEnabled( true );
826 }
827 }
828 break;
829 case ColumnIndex::ExportName:
830 {
831 // Check empty export name
832 if ( item->text().isEmpty() )
833 {
834 QMessageBox::warning( this,
835 tr( "Empty export name" ),
836 tr( "Empty export name are not allowed." ) );
837 return;
838 }
839
840 // Rename eventually duplicated names
841 QStringList names = attributesExportNames();
842 while ( names.count( item->text() ) > 1 )
843 item->setText( QString( "%1_2" ).arg( item->text() ) );
844
845 mUseAliasesForExportedName->setCheckState( Qt::PartiallyChecked );
846 }
847 break;
848 case ColumnIndex::Type:
849 // Nothing to do
850 break;
851 case ColumnIndex::ExportAsDisplayedValue:
852 {
853 if ( mAttributeTable->item( row, column )->flags() & Qt::ItemIsUserCheckable )
854 {
855 bool allChecked = true;
856 bool allUnchecked = true;
857 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
858 {
859 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
860 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsEnabled )
861 {
862 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->checkState() == Qt::Unchecked )
863 allChecked = false;
864 else
865 allUnchecked = false;
866 }
867 }
868 mReplaceRawFieldValues->setCheckState( ( !allChecked && !allUnchecked ) ? Qt::PartiallyChecked : ( allChecked ) ? Qt::Checked : Qt::Unchecked );
869 }
870 }
871 break;
872 }
873}
874
875void QgsVectorLayerSaveAsDialog::mCrsSelector_crsChanged( const QgsCoordinateReferenceSystem &crs )
876{
877 mSelectedCrs = crs;
878 mExtentGroupBox->setOutputCrs( mSelectedCrs );
879}
880
882{
883 return mFilename->filePath();
884}
885
887{
888 return leLayername->text();
889}
890
892{
893 return mEncodingComboBox->currentText();
894}
895
897{
898 return mFormatComboBox->currentData().toString();
899}
900
902{
903 return mSelectedCrs;
904}
905
907{
908 QStringList options;
909
910 QgsVectorFileWriter::MetaData driverMetaData;
911
912 if ( QgsVectorFileWriter::driverMetadata( format(), driverMetaData ) )
913 {
914 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
915
916 for ( it = driverMetaData.driverOptions.constBegin(); it != driverMetaData.driverOptions.constEnd(); ++it )
917 {
918 switch ( it.value()->type )
919 {
921 {
923 QSpinBox *sb = mDatasourceOptionsGroupBox->findChild<QSpinBox *>( it.key() );
924 if ( opt && sb && sb->value() != opt->defaultValue )
925 options << QStringLiteral( "%1=%2" ).arg( it.key() ).arg( sb->value() );
926 break;
927 }
928
930 {
932 QComboBox *cb = mDatasourceOptionsGroupBox->findChild<QComboBox *>( it.key() );
933 if ( opt && cb && cb->itemData( cb->currentIndex() ) != opt->defaultValue )
934 options << QStringLiteral( "%1=%2" ).arg( it.key(), cb->currentText() );
935 break;
936 }
937
939 {
941 QLineEdit *le = mDatasourceOptionsGroupBox->findChild<QLineEdit *>( it.key() );
942 if ( opt && le && le->text() != opt->defaultValue )
943 options << QStringLiteral( "%1=%2" ).arg( it.key(), le->text() );
944 break;
945 }
946
948 {
950 dynamic_cast<QgsVectorFileWriter::HiddenOption *>( it.value() );
951 options << QStringLiteral( "%1=%2" ).arg( it.key(), opt->mValue );
952 break;
953 }
954 }
955 }
956 }
957
958 QString plainText = mOgrDatasourceOptions->toPlainText().trimmed();
959 if ( !plainText.isEmpty() )
960 options += plainText.split( '\n' );
961
962 return options;
963}
964
966{
967 QStringList options;
968
969 QgsVectorFileWriter::MetaData driverMetaData;
970
971 if ( QgsVectorFileWriter::driverMetadata( format(), driverMetaData ) )
972 {
973 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
974
975 for ( it = driverMetaData.layerOptions.constBegin(); it != driverMetaData.layerOptions.constEnd(); ++it )
976 {
977 switch ( it.value()->type )
978 {
980 {
982 QSpinBox *sb = mLayerOptionsGroupBox->findChild<QSpinBox *>( it.key() );
983 if ( opt && sb && sb->value() != opt->defaultValue )
984 options << QStringLiteral( "%1=%2" ).arg( it.key() ).arg( sb->value() );
985 break;
986 }
987
989 {
991 QComboBox *cb = mLayerOptionsGroupBox->findChild<QComboBox *>( it.key() );
992 if ( opt && cb && cb->itemData( cb->currentIndex() ) != opt->defaultValue )
993 options << QStringLiteral( "%1=%2" ).arg( it.key(), cb->currentText() );
994 break;
995 }
996
998 {
1000 QLineEdit *le = mLayerOptionsGroupBox->findChild<QLineEdit *>( it.key() );
1001 if ( opt && le && le->text() != opt->defaultValue )
1002 options << QStringLiteral( "%1=%2" ).arg( it.key(), le->text() );
1003 break;
1004 }
1005
1007 {
1009 dynamic_cast<QgsVectorFileWriter::HiddenOption *>( it.value() );
1010 options << QStringLiteral( "%1=%2" ).arg( it.key(), opt->mValue );
1011 break;
1012 }
1013 }
1014 }
1015 }
1016
1017 QString plainText = mOgrLayerOptions->toPlainText().trimmed();
1018 if ( !plainText.isEmpty() )
1019 options += plainText.split( '\n' );
1020
1021 return options;
1022}
1023
1025{
1026 QgsAttributeList attributes;
1027
1028 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
1029 {
1030 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::Name ) )->checkState() == Qt::Checked )
1031 {
1032 attributes.append( i );
1033 }
1034 }
1035
1036 return attributes;
1037}
1038
1040{
1041 QgsAttributeList attributes;
1042
1043 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
1044 {
1045 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::Name ) )->checkState() == Qt::Checked &&
1046 ! mAttributeTable->isColumnHidden( static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
1047 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->checkState() == Qt::Checked )
1048 {
1049 attributes.append( i );
1050 }
1051 }
1052
1053 return attributes;
1054}
1055
1057{
1058 QStringList exportNames;
1059 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
1060 exportNames.append( mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportName ) )->text() );
1061
1062 return exportNames;
1063}
1064
1066{
1067 return mAddToCanvas->isChecked() && mAddToCanvas->isEnabled();
1068}
1069
1071{
1072 mAddToCanvas->setChecked( enabled );
1073}
1074
1076{
1077 return mSymbologyExportComboBox->currentData().value< Qgis::FeatureSymbologyExport >();
1078}
1079
1081{
1082 return mScaleWidget->scale();
1083}
1084
1086{
1087 mMapCanvas = canvas;
1088 mScaleWidget->setMapCanvas( canvas );
1089 mScaleWidget->setShowCurrentScaleButton( true );
1090 mExtentGroupBox->setCurrentExtent( canvas->mapSettings().visibleExtent(), canvas->mapSettings().destinationCrs() );
1091}
1092
1094{
1095 return mExtentGroupBox->isChecked();
1096}
1097
1099{
1100 return mExtentGroupBox->outputExtent();
1101}
1102
1104{
1105 mSelectedOnly->setChecked( onlySelected );
1106}
1107
1109{
1110 return mSelectedOnly->isChecked();
1111}
1112
1114{
1115 return mCheckPersistMetadata->isChecked();
1116}
1117
1119{
1120 int currentIndexData = mGeometryTypeComboBox->currentData().toInt();
1121 if ( currentIndexData == -1 )
1122 {
1123 //automatic
1125 }
1126
1127 return static_cast< Qgis::WkbType >( currentIndexData );
1128}
1129
1131{
1132 int currentIndexData = mGeometryTypeComboBox->currentData().toInt();
1133 return currentIndexData == -1;
1134}
1135
1137{
1138 return mForceMultiCheckBox->isChecked();
1139}
1140
1142{
1143 mForceMultiCheckBox->setChecked( checked );
1144}
1145
1147{
1148 return mIncludeZCheckBox->isChecked();
1149}
1150
1152{
1153 return mActionOnExistingFile;
1154}
1155
1157{
1158 mIncludeZCheckBox->setChecked( checked );
1159}
1160
1161void QgsVectorLayerSaveAsDialog::mSymbologyExportComboBox_currentIndexChanged( const QString &text )
1162{
1163 bool scaleEnabled = true;
1164 if ( text == tr( "No symbology" ) )
1165 {
1166 scaleEnabled = false;
1167 }
1168 mScaleWidget->setEnabled( scaleEnabled );
1169 mScaleLabel->setEnabled( scaleEnabled );
1170}
1171
1172void QgsVectorLayerSaveAsDialog::mGeometryTypeComboBox_currentIndexChanged( int )
1173{
1174 Qgis::WkbType currentIndexData = static_cast< Qgis::WkbType >( mGeometryTypeComboBox->currentData().toInt() );
1175
1176 if ( mGeometryTypeComboBox->currentIndex() != -1 && currentIndexData != Qgis::WkbType::NoGeometry )
1177 {
1178 mForceMultiCheckBox->setEnabled( true );
1179 mIncludeZCheckBox->setEnabled( true );
1180 }
1181 else
1182 {
1183 mForceMultiCheckBox->setEnabled( false );
1184 mForceMultiCheckBox->setChecked( false );
1185 mIncludeZCheckBox->setEnabled( false );
1186 mIncludeZCheckBox->setChecked( false );
1187 }
1188}
1189
1190void QgsVectorLayerSaveAsDialog::mSelectAllAttributes_clicked()
1191{
1192 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
1193 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
1194
1195 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
1196 {
1197 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::Name ) )->flags() & Qt::ItemIsEnabled )
1198 {
1199 if ( ! mAttributeTable->isColumnHidden( static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
1200 ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsUserCheckable ) )
1201 {
1202 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsEnabled );
1203 }
1204 mAttributeTable->item( i, static_cast<int>( ColumnIndex::Name ) )->setCheckState( Qt::Checked );
1205 }
1206 }
1207 if ( ! mAttributeTable->isColumnHidden( static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
1208 {
1209 mReplaceRawFieldValues->setEnabled( true );
1210 }
1211}
1212
1213void QgsVectorLayerSaveAsDialog::mDeselectAllAttributes_clicked()
1214{
1215 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
1216 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
1217
1218 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
1219 {
1220 mAttributeTable->item( i, static_cast<int>( ColumnIndex::Name ) )->setCheckState( Qt::Unchecked );
1221 if ( ! mAttributeTable->isColumnHidden( static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
1222 ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsUserCheckable ) )
1223 {
1224 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable );
1225 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( Qt::Unchecked );
1226 }
1227 }
1228 if ( ! mAttributeTable->isColumnHidden( static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
1229 {
1230 mReplaceRawFieldValues->setCheckState( Qt::Unchecked );
1231 mReplaceRawFieldValues->setEnabled( false );
1232 }
1233}
1234
1235void QgsVectorLayerSaveAsDialog::showHelp()
1236{
1237 QgsHelp::openHelp( QStringLiteral( "managing_data_source/create_layers.html#creating-new-layers-from-an-existing-layer" ) );
1238}
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition: qgis.h:154
@ LineString
LineString.
@ Polygon
Polygon.
@ NoGeometry
No geometry.
@ Unknown
Unknown.
@ GeometryCollection
GeometryCollection.
FeatureSymbologyExport
Options for exporting features considering their symbology.
Definition: qgis.h:3635
@ NoSymbology
Export only data.
This class represents a coordinate reference system (CRS).
QgsDatumEnsemble datumEnsemble() const SIP_THROW(QgsNotSupportedException)
Attempts to retrieve datum ensemble details from the CRS.
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:53
QString typeName() const
Gets the field type.
Definition: qgsfield.cpp:150
QString name
Definition: qgsfield.h:62
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:88
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:193
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:119
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.
QgsAttributeList selectedAttributes() const
Returns a list of attributes which are selected for saving.
QgsRectangle filterExtent() const
Determines the extent to be exported.
QString format() const
Returns the selected 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
Returns the selected encoding for 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.
QString fileName() const
Returns the target filename.
void setOnlySelected(bool onlySelected)
Sets whether only selected features will be saved.
QString layerName() const
Returns the target layer name.
bool automaticGeometryType() const
Returns true if geometry type is set to automatic.
Q_DECL_DEPRECATED QgsVectorLayerSaveAsDialog(long srsid, QWidget *parent=nullptr, Qt::WindowFlags fl=Qt::WindowFlags())
Available dialog options.
bool includeZ() const
Returns true if include z dimension is checked.
@ Symbology
Show symbology options.
@ DestinationCrs
Show destination CRS (reprojection) option.
@ AddToCanvas
Show add to map option.
@ Fields
Show field customization group.
@ SelectedOnly
Show selected features only option.
@ GeometryType
Show geometry group.
@ Metadata
Show metadata options.
QgsCoordinateReferenceSystem crs() 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 the creation action.
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.
Qgis::FeatureSymbologyExport symbologyExport() const
Returns type of symbology export.
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:3914
QList< int > QgsAttributeList
Definition: qgsfield.h:27
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,...