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