QGIS API Documentation 3.28.11-Firenze (exported)
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"
25#include "qgssettings.h"
26#include "qgsmapcanvas.h"
27#include "qgsgui.h"
28#include "qgsapplication.h"
29#include "qgsmaplayerutils.h"
30#include <QMessageBox>
31#include <QFileDialog>
32#include <QTextCodec>
33#include <QSpinBox>
34#include <QRegularExpression>
35#include <limits>
36#include "gdal.h"
37#include "qgsdatums.h"
38#include "qgsiconutils.h"
39#include "qgsproviderregistry.h"
41
42QgsVectorLayerSaveAsDialog::QgsVectorLayerSaveAsDialog( long srsid, QWidget *parent, Qt::WindowFlags fl )
43 : QDialog( parent, fl )
44 , mSelectedCrs( QgsCoordinateReferenceSystem::fromSrsId( srsid ) )
45 , mActionOnExistingFile( QgsVectorFileWriter::CreateOrOverwriteFile )
46{
47 setup();
48}
49
50QgsVectorLayerSaveAsDialog::QgsVectorLayerSaveAsDialog( QgsVectorLayer *layer, Options options, QWidget *parent, Qt::WindowFlags fl )
51 : QDialog( parent, fl )
52 , mLayer( layer )
53 , mActionOnExistingFile( QgsVectorFileWriter::CreateOrOverwriteFile )
54 , mOptions( options )
55{
56 if ( layer )
57 {
58 mSelectedCrs = layer->crs();
59 mLayerExtent = layer->extent();
60 }
61 setup();
62
63 if ( layer )
64 {
65 mDefaultOutputLayerNameFromInputLayerName = QgsMapLayerUtils::launderLayerName( layer->name() );
66 leLayername->setDefaultValue( mDefaultOutputLayerNameFromInputLayerName );
67 leLayername->setClearMode( QgsFilterLineEdit::ClearToDefault );
68 if ( leLayername->isEnabled() )
69 leLayername->setText( mDefaultOutputLayerNameFromInputLayerName );
70 }
71
72 if ( !( mOptions & Symbology ) )
73 {
74 mSymbologyExportLabel->hide();
75 mSymbologyExportComboBox->hide();
76 mScaleLabel->hide();
77 mScaleWidget->hide();
78 }
79
80 if ( !( mOptions & DestinationCrs ) )
81 {
82 mCrsLabel->hide();
83 mCrsSelector->hide();
84 }
85 if ( !( mOptions & Fields ) )
86 mAttributesSelection->hide();
87
88 if ( !( mOptions & SelectedOnly ) )
89 mSelectedOnly->hide();
90
91 if ( !( mOptions & AddToCanvas ) )
92 mAddToCanvas->hide();
93
94 if ( !( mOptions & GeometryType ) )
95 mGeometryGroupBox->hide();
96
97 if ( !( mOptions & Extent ) )
98 mExtentGroupBox->hide();
99
100 if ( !( mOptions & Metadata ) )
101 {
102 mCheckPersistMetadata->setChecked( false );
103 mCheckPersistMetadata->hide();
104 }
105
106 mSelectedOnly->setEnabled( layer && layer->selectedFeatureCount() != 0 );
107 mButtonBox->button( QDialogButtonBox::Ok )->setDisabled( true );
108}
109
110void QgsVectorLayerSaveAsDialog::setup()
111{
112 setupUi( this );
114
115 connect( mFormatComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsVectorLayerSaveAsDialog::mFormatComboBox_currentIndexChanged );
116 connect( mCrsSelector, &QgsProjectionSelectionWidget::crsChanged, this, &QgsVectorLayerSaveAsDialog::mCrsSelector_crsChanged );
117 connect( mSymbologyExportComboBox, &QComboBox::currentTextChanged, this, &QgsVectorLayerSaveAsDialog::mSymbologyExportComboBox_currentIndexChanged );
118 connect( mGeometryTypeComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsVectorLayerSaveAsDialog::mGeometryTypeComboBox_currentIndexChanged );
119 connect( mSelectAllAttributes, &QPushButton::clicked, this, &QgsVectorLayerSaveAsDialog::mSelectAllAttributes_clicked );
120 connect( mDeselectAllAttributes, &QPushButton::clicked, this, &QgsVectorLayerSaveAsDialog::mDeselectAllAttributes_clicked );
121 connect( mUseAliasesForExportedName, &QCheckBox::stateChanged, this, &QgsVectorLayerSaveAsDialog::mUseAliasesForExportedName_stateChanged );
122 connect( mReplaceRawFieldValues, &QCheckBox::stateChanged, this, &QgsVectorLayerSaveAsDialog::mReplaceRawFieldValues_stateChanged );
123 connect( mAttributeTable, &QTableWidget::itemChanged, this, &QgsVectorLayerSaveAsDialog::mAttributeTable_itemChanged );
124
125#ifdef Q_OS_WIN
126 mHelpButtonBox->setVisible( false );
127 mButtonBox->addButton( QDialogButtonBox::Help );
128 connect( mButtonBox, &QDialogButtonBox::helpRequested, this, &QgsVectorLayerSaveAsDialog::showHelp );
129#else
130 connect( mHelpButtonBox, &QDialogButtonBox::helpRequested, this, &QgsVectorLayerSaveAsDialog::showHelp );
131#endif
132 connect( mButtonBox, &QDialogButtonBox::accepted, this, &QgsVectorLayerSaveAsDialog::accept );
133 connect( mButtonBox, &QDialogButtonBox::rejected, this, &QgsVectorLayerSaveAsDialog::reject );
134
135 const QList< QgsVectorFileWriter::DriverDetails > drivers = QgsVectorFileWriter::ogrDriverList();
136 mFormatComboBox->blockSignals( true );
137 for ( const QgsVectorFileWriter::DriverDetails &driver : drivers )
138 {
139 mFormatComboBox->addItem( driver.longName, driver.driverName );
140 }
141
142 QgsSettings settings;
143 QString format = settings.value( QStringLiteral( "UI/lastVectorFormat" ), "GPKG" ).toString();
144 mFormatComboBox->setCurrentIndex( mFormatComboBox->findData( format ) );
145 mFormatComboBox->blockSignals( false );
146
147 const auto addGeomItem = [this]( QgsWkbTypes::Type type )
148 {
149 mGeometryTypeComboBox->addItem( QgsIconUtils::iconForWkbType( type ), QgsWkbTypes::translatedDisplayString( type ), type );
150 };
151
152 //add geometry types to combobox
153 mGeometryTypeComboBox->addItem( tr( "Automatic" ), -1 );
154 addGeomItem( QgsWkbTypes::Point );
155 addGeomItem( QgsWkbTypes::LineString );
156 addGeomItem( QgsWkbTypes::Polygon );
158 addGeomItem( QgsWkbTypes::NoGeometry );
159 mGeometryTypeComboBox->setCurrentIndex( mGeometryTypeComboBox->findData( -1 ) );
160
161 mEncodingComboBox->addItems( QgsVectorDataProvider::availableEncodings() );
162
163 QString enc = settings.value( QStringLiteral( "UI/encoding" ), "System" ).toString();
164 int idx = mEncodingComboBox->findText( enc );
165 if ( idx < 0 )
166 {
167 mEncodingComboBox->insertItem( 0, enc );
168 idx = 0;
169 }
170
171 mCrsSelector->setCrs( mSelectedCrs );
172 mCrsSelector->setLayerCrs( mSelectedCrs );
173 mCrsSelector->setMessage( tr( "Select the coordinate reference system for the vector file. "
174 "The data points will be transformed from the layer coordinate reference system." ) );
175
176 mEncodingComboBox->setCurrentIndex( idx );
177 mFormatComboBox_currentIndexChanged( mFormatComboBox->currentIndex() );
178
179 //symbology export combo box
180 mSymbologyExportComboBox->addItem( tr( "No Symbology" ), QgsVectorFileWriter::NoSymbology );
181 mSymbologyExportComboBox->addItem( tr( "Feature Symbology" ), QgsVectorFileWriter::FeatureSymbology );
182 mSymbologyExportComboBox->addItem( tr( "Symbol Layer Symbology" ), QgsVectorFileWriter::SymbolLayerSymbology );
183 mSymbologyExportComboBox_currentIndexChanged( mSymbologyExportComboBox->currentText() );
184
185 // extent group box
186 mExtentGroupBox->setOutputCrs( mSelectedCrs );
187 mExtentGroupBox->setOriginalExtent( mLayerExtent, mSelectedCrs );
188 mExtentGroupBox->setOutputExtentFromOriginal();
189 mExtentGroupBox->setCheckable( true );
190 mExtentGroupBox->setChecked( false );
191 mExtentGroupBox->setCollapsed( true );
192
193 mFilename->setStorageMode( QgsFileWidget::SaveFile );
194 mFilename->setDialogTitle( tr( "Save Layer As" ) );
195 mFilename->setDefaultRoot( settings.value( QStringLiteral( "UI/lastVectorFileFilterDir" ), QDir::homePath() ).toString() );
196 mFilename->setConfirmOverwrite( false );
197 connect( mFilename, &QgsFileWidget::fileChanged, this, [ = ]( const QString & filePath )
198 {
199 QgsSettings settings;
200 QFileInfo tmplFileInfo( filePath );
201 settings.setValue( QStringLiteral( "UI/lastVectorFileFilterDir" ), tmplFileInfo.absolutePath() );
202
203 const QFileInfo fileInfo( filePath );
204 const QString suggestedLayerName = QgsMapLayerUtils::launderLayerName( fileInfo.completeBaseName() );
205 if ( mDefaultOutputLayerNameFromInputLayerName.isEmpty() )
206 leLayername->setDefaultValue( suggestedLayerName );
207
208 // if no layer name set, then automatically match the output layer name to the file name
209 if ( leLayername->text().isEmpty() && !filePath.isEmpty() && leLayername->isEnabled() )
210 {
211 leLayername->setText( suggestedLayerName );
212 }
213 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( !filePath.isEmpty() );
214 } );
215
216 try
217 {
218 const QgsDatumEnsemble ensemble = mSelectedCrs.datumEnsemble();
219 if ( ensemble.isValid() )
220 {
221 mCrsSelector->setSourceEnsemble( ensemble.name() );
222 }
223 }
224 catch ( QgsNotSupportedException & )
225 {
226 }
227
228 mCrsSelector->setShowAccuracyWarnings( true );
229}
230
231QList<QPair<QLabel *, QWidget *> > QgsVectorLayerSaveAsDialog::createControls( const QMap<QString, QgsVectorFileWriter::Option *> &options )
232{
233 QList<QPair<QLabel *, QWidget *> > controls;
234 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
235
236 for ( it = options.constBegin(); it != options.constEnd(); ++it )
237 {
238 QgsVectorFileWriter::Option *option = it.value();
239 QLabel *label = new QLabel( it.key() );
240 QWidget *control = nullptr;
241 switch ( option->type )
242 {
244 {
245 QgsVectorFileWriter::IntOption *opt = dynamic_cast<QgsVectorFileWriter::IntOption *>( option );
246 if ( opt )
247 {
248 QSpinBox *sb = new QSpinBox();
249 sb->setObjectName( it.key() );
250 sb->setMaximum( std::numeric_limits<int>::max() ); // the default is 99
251 sb->setValue( opt->defaultValue );
252 control = sb;
253 }
254 break;
255 }
256
258 {
259 QgsVectorFileWriter::SetOption *opt = dynamic_cast<QgsVectorFileWriter::SetOption *>( option );
260 if ( opt )
261 {
262 QComboBox *cb = new QComboBox();
263 cb->setObjectName( it.key() );
264 for ( const QString &val : std::as_const( opt->values ) )
265 {
266 cb->addItem( val, val );
267 }
268 if ( opt->allowNone )
269 cb->addItem( tr( "<Default>" ), QVariant( QVariant::String ) );
270 int idx = cb->findText( opt->defaultValue );
271 if ( idx == -1 )
272 idx = cb->findData( QVariant( QVariant::String ) );
273 cb->setCurrentIndex( idx );
274 control = cb;
275 }
276 break;
277 }
278
280 {
282 if ( opt )
283 {
284 QLineEdit *le = new QLineEdit( opt->defaultValue );
285 le->setObjectName( it.key() );
286 control = le;
287 }
288 break;
289 }
290
292 control = nullptr;
293 break;
294 }
295
296 if ( control )
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
309void QgsVectorLayerSaveAsDialog::accept()
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 QRegularExpression rx( "\\.(.*?)[\\s]" );
442 QString ext;
443 ext = rx.match( QgsVectorFileWriter::filterForDriver( format() ) ).captured( 1 );
444 if ( !ext.isEmpty() )
445 {
446 QFileInfo fi( mFilename->filePath() );
447 mFilename->setFilePath( QStringLiteral( "%1/%2.%3" ).arg( fi.path() ).arg( fi.baseName() ).arg( ext ) );
448 }
449 }
450
451 bool selectAllFields = true;
452
453 // Is it a format for which fields that have attached widgets of types
454 // ValueMap, ValueRelation, etc. should be by default exported with their displayed
455 // values
456 bool isFormatForFieldsAsDisplayedValues = false;
457
458 const QString sFormat( format() );
459 if ( sFormat == QLatin1String( "DXF" ) || sFormat == QLatin1String( "DGN" ) )
460 {
461 mAttributesSelection->setVisible( false );
462 selectAllFields = false;
463 }
464 else
465 {
466 if ( mOptions & Fields )
467 {
468 mAttributesSelection->setVisible( true );
469 isFormatForFieldsAsDisplayedValues = ( sFormat == QLatin1String( "CSV" ) ||
470 sFormat == QLatin1String( "XLS" ) ||
471 sFormat == QLatin1String( "XLSX" ) ||
472 sFormat == QLatin1String( "ODS" ) );
473 }
474 }
475
476 // Show symbology options only for some formats
477 if ( QgsVectorFileWriter::supportsFeatureStyles( sFormat ) && ( mOptions & Symbology ) )
478 {
479 mSymbologyExportLabel->setVisible( true );
480 mSymbologyExportComboBox->setVisible( true );
481 mScaleLabel->setVisible( true );
482 mScaleWidget->setVisible( true );
483 }
484 else
485 {
486 mSymbologyExportLabel->hide();
487 mSymbologyExportComboBox->hide();
488 mScaleLabel->hide();
489 mScaleWidget->hide();
490 }
491
492 leLayername->setEnabled( sFormat == QLatin1String( "KML" ) ||
493 sFormat == QLatin1String( "GPKG" ) ||
494 sFormat == QLatin1String( "XLSX" ) ||
495 sFormat == QLatin1String( "ODS" ) ||
496 sFormat == QLatin1String( "FileGDB" ) ||
497 sFormat == QLatin1String( "OpenFileGDB" ) ||
498 sFormat == QLatin1String( "SQLite" ) ||
499 sFormat == QLatin1String( "SpatiaLite" ) );
500
501 if ( sFormat == QLatin1String( "XLSX" ) )
502 leLayername->setMaxLength( 31 );
503 else if ( leLayername->isEnabled() )
504 leLayername->setMaxLength( 32767 ); // default length
505
506 if ( !leLayername->isEnabled() )
507 leLayername->setText( QString() );
508 else if ( leLayername->text().isEmpty() )
509 {
510 QString layerName = mDefaultOutputLayerNameFromInputLayerName;
511 if ( layerName.isEmpty() && !mFilename->filePath().isEmpty() )
512 {
513 layerName = QFileInfo( mFilename->filePath() ).baseName();
514 leLayername->setDefaultValue( layerName );
515 }
516 if ( layerName.isEmpty() )
517 layerName = tr( "new_layer" );
518 leLayername->setText( layerName );
519 }
520
521 if ( mLayer )
522 {
523 mAttributeTable->setRowCount( mLayer->fields().count() );
524
525 QStringList horizontalHeaders = QStringList() << tr( "Name" ) << tr( "Export name" ) << tr( "Type" ) << tr( "Replace with displayed values" );
526 mAttributeTable->setColumnCount( horizontalHeaders.size() );
527 mAttributeTable->setHorizontalHeaderLabels( horizontalHeaders );
528
529 bool foundFieldThatCanBeExportedAsDisplayedValue = false;
530 for ( int i = 0; i < mLayer->fields().size(); ++i )
531 {
532 const QgsEditorWidgetSetup setup = QgsGui::editorWidgetRegistry()->findBest( mLayer, mLayer->fields()[i].name() );
533 if ( setup.type() != QLatin1String( "TextEdit" ) &&
534 QgsGui::editorWidgetRegistry()->factory( setup.type() ) )
535 {
536 foundFieldThatCanBeExportedAsDisplayedValue = true;
537 break;
538 }
539 }
540 mAttributeTable->setColumnHidden( static_cast<int>( ColumnIndex::ExportAsDisplayedValue ),
541 ! foundFieldThatCanBeExportedAsDisplayedValue );
542
543 bool checkReplaceRawFieldValues = selectAllFields && isFormatForFieldsAsDisplayedValues;
544 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
545 {
546 for ( int i = 0; i < mLayer->fields().size(); ++i )
547 {
548 QgsField fld = mLayer->fields().at( i );
549 Qt::ItemFlags flags = mLayer->providerType() != QLatin1String( "oracle" ) || !fld.typeName().contains( QLatin1String( "SDO_GEOMETRY" ) ) ? Qt::ItemIsEnabled : Qt::NoItemFlags;
550 QTableWidgetItem *item = nullptr;
551 item = new QTableWidgetItem( fld.name() );
552 item->setFlags( flags | Qt::ItemIsUserCheckable );
553 item->setCheckState( ( selectAllFields ) ? Qt::Checked : Qt::Unchecked );
554 mAttributeTable->setItem( i, static_cast<int>( ColumnIndex::Name ), item );
555
556 item = new QTableWidgetItem( fld.name() );
557 item->setFlags( flags | Qt::ItemIsEditable );
558 item->setData( Qt::UserRole, fld.displayName() );
559 mAttributeTable->setItem( i, static_cast<int>( ColumnIndex::ExportName ), item );
560
561 item = new QTableWidgetItem( fld.typeName() );
562 item->setFlags( flags );
563 mAttributeTable->setItem( i, static_cast<int>( ColumnIndex::Type ), item );
564
565 if ( foundFieldThatCanBeExportedAsDisplayedValue )
566 {
567 const QgsEditorWidgetSetup setup = QgsGui::editorWidgetRegistry()->findBest( mLayer, mLayer->fields()[i].name() );
568 QgsEditorWidgetFactory *factory = nullptr;
569 const QString widgetId( setup.type() );
570 if ( flags == Qt::ItemIsEnabled &&
571 widgetId != QLatin1String( "TextEdit" ) &&
572 ( factory = QgsGui::editorWidgetRegistry()->factory( widgetId ) ) )
573 {
574 item = new QTableWidgetItem( tr( "Use %1" ).arg( factory->name() ) );
575 item->setFlags( ( selectAllFields ) ? ( Qt::ItemIsEnabled | Qt::ItemIsUserCheckable ) : Qt::ItemIsUserCheckable );
576 const bool checkItem = ( selectAllFields && isFormatForFieldsAsDisplayedValues &&
577 ( widgetId == QLatin1String( "ValueMap" ) ||
578 widgetId == QLatin1String( "ValueRelation" ) ||
579 widgetId == QLatin1String( "CheckBox" ) ||
580 widgetId == QLatin1String( "RelationReference" ) ) );
581 checkReplaceRawFieldValues &= checkItem;
582 item->setCheckState( checkItem ?
583 Qt::Checked : Qt::Unchecked );
584 mAttributeTable->setItem( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ), item );
585 }
586 else
587 {
588 item = new QTableWidgetItem();
589 item->setFlags( Qt::NoItemFlags );
590 mAttributeTable->setItem( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ), item );
591 }
592 }
593 }
594 }
595
596 whileBlocking( mReplaceRawFieldValues )->setChecked( checkReplaceRawFieldValues );
597 mReplaceRawFieldValues->setEnabled( selectAllFields );
598 mReplaceRawFieldValues->setVisible( foundFieldThatCanBeExportedAsDisplayedValue );
599
600 mAttributeTable->resizeColumnsToContents();
601 }
602
603 QgsVectorFileWriter::MetaData driverMetaData;
604
605 while ( mDatasourceOptionsGroupBox->layout()->count() )
606 {
607 QLayoutItem *item = mDatasourceOptionsGroupBox->layout()->takeAt( 0 );
608 delete item->widget();
609 delete item;
610 }
611
612 while ( mLayerOptionsGroupBox->layout()->count() )
613 {
614 QLayoutItem *item = mLayerOptionsGroupBox->layout()->takeAt( 0 );
615 delete item->widget();
616 delete item;
617 }
618
619 typedef QPair<QLabel *, QWidget *> LabelControlPair;
620
621 if ( QgsVectorFileWriter::driverMetadata( format(), driverMetaData ) )
622 {
623 if ( !driverMetaData.driverOptions.empty() )
624 {
625 mDatasourceOptionsGroupBox->setVisible( true );
626 QList<QPair<QLabel *, QWidget *> > controls = createControls( driverMetaData.driverOptions );
627
628 QFormLayout *datasourceLayout = dynamic_cast<QFormLayout *>( mDatasourceOptionsGroupBox->layout() );
629
630 const auto constControls = controls;
631 for ( LabelControlPair control : constControls )
632 {
633 datasourceLayout->addRow( control.first, control.second );
634 }
635 }
636 else
637 {
638 mDatasourceOptionsGroupBox->setVisible( false );
639 }
640
641 if ( !driverMetaData.layerOptions.empty() )
642 {
643 mLayerOptionsGroupBox->setVisible( true );
644 QList<QPair<QLabel *, QWidget *> > controls = createControls( driverMetaData.layerOptions );
645
646 QFormLayout *layerOptionsLayout = dynamic_cast<QFormLayout *>( mLayerOptionsGroupBox->layout() );
647
648 const auto constControls = controls;
649 for ( LabelControlPair control : constControls )
650 {
651 layerOptionsLayout->addRow( control.first, control.second );
652 }
653 }
654 else
655 {
656 mLayerOptionsGroupBox->setVisible( false );
657 }
658
659 if ( driverMetaData.compulsoryEncoding.isEmpty() )
660 {
661 mEncodingComboBox->setEnabled( true );
662 }
663 else
664 {
665 int idx = mEncodingComboBox->findText( driverMetaData.compulsoryEncoding );
666 if ( idx >= 0 )
667 {
668 mEncodingComboBox->setCurrentIndex( idx );
669 mEncodingComboBox->setDisabled( true );
670 }
671 else
672 {
673 mEncodingComboBox->setEnabled( true );
674 }
675 }
676
677 }
678 else
679 {
680 mEncodingComboBox->setEnabled( true );
681 }
682
683 GDALDriverH hDriver = GDALGetDriverByName( format().toUtf8().constData() );
684 if ( hDriver )
685 {
686 mAddToCanvas->setEnabled( GDALGetMetadataItem( hDriver, GDAL_DCAP_OPEN, nullptr ) != nullptr );
687 }
688}
689
690void QgsVectorLayerSaveAsDialog::mUseAliasesForExportedName_stateChanged( int state )
691{
692 const QSignalBlocker signalBlocker( mAttributeTable );
693
694 switch ( state )
695 {
696 case Qt::Unchecked:
697 {
698 // Check for modified entries
699 bool modifiedEntries = false;
700 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
701 {
702 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportName ) )->text()
703 != mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportName ) )->data( Qt::UserRole ).toString() )
704 {
705 modifiedEntries = true;
706 break;
707 }
708 }
709
710 if ( modifiedEntries )
711 {
712 if ( QMessageBox::question( this,
713 tr( "Modified names" ),
714 tr( "Some names were modified and will be overridden. Do you want to continue?" ) )
715 == QMessageBox::No )
716 {
717 whileBlocking( mUseAliasesForExportedName )->setCheckState( Qt::PartiallyChecked );
718 return;
719 }
720 }
721
722 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
723 {
724 mUseAliasesForExportedName->setTristate( false );
725 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportName ) )->setText( mAttributeTable->item( i, static_cast<int>( ColumnIndex::Name ) )->text() );
726 }
727 }
728 break;
729 case Qt::Checked:
730 {
731 // Check for modified entries
732 bool modifiedEntries = false;
733 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
734 {
735 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportName ) )->text()
736 != mAttributeTable->item( i, static_cast<int>( ColumnIndex::Name ) )->text() )
737 modifiedEntries = true;
738 }
739
740 if ( modifiedEntries )
741 {
742 if ( QMessageBox::question( this,
743 tr( "Modified names" ),
744 tr( "Some names were modified and will be overridden. Do you want to continue?" ) )
745 == QMessageBox::No )
746 {
747 whileBlocking( mUseAliasesForExportedName )->setCheckState( Qt::PartiallyChecked );
748 return;
749 }
750 }
751
752 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
753 {
754 mUseAliasesForExportedName->setTristate( false );
755 const QString alias = mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportName ) )->data( Qt::UserRole ).toString();
756 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportName ) )->setText( alias );
757 }
758 }
759 break;
760 case Qt::PartiallyChecked:
761 // Do nothing
762 break;
763 }
764}
765
766void QgsVectorLayerSaveAsDialog::mReplaceRawFieldValues_stateChanged( int )
767{
768 if ( mAttributeTable->isColumnHidden( static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
769 return;
770
771 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
772 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
773
774 if ( mReplaceRawFieldValues->checkState() != Qt::PartiallyChecked )
775 {
776 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
777 {
778 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::Name ) )->checkState() == Qt::Checked &&
779 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
780 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsEnabled )
781 {
782 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( mReplaceRawFieldValues->checkState() );
783 }
784 }
785 }
786 mReplaceRawFieldValues->setTristate( false );
787}
788
789void QgsVectorLayerSaveAsDialog::mAttributeTable_itemChanged( QTableWidgetItem *item )
790{
791 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
792 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
793
794 int row = item->row();
795 int column = item->column();
796
797 switch ( static_cast<ColumnIndex>( column ) )
798 {
799 case ColumnIndex::Name:
800 {
801 if ( mAttributeTable->isColumnHidden( static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) ||
802 ! mAttributeTable->item( row, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) ||
803 !( mAttributeTable->item( row, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsUserCheckable ) )
804 return;
805
806 if ( mAttributeTable->item( row, column )->checkState() == Qt::Unchecked )
807 {
808 mAttributeTable->item( row, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( Qt::Unchecked );
809 mAttributeTable->item( row, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable );
810 bool checkBoxEnabled = false;
811 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
812 {
813 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
814 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsEnabled )
815 {
816 checkBoxEnabled = true;
817 break;
818 }
819 }
820 mReplaceRawFieldValues->setEnabled( checkBoxEnabled );
821 if ( !checkBoxEnabled )
822 mReplaceRawFieldValues->setCheckState( Qt::Unchecked );
823 }
824 else if ( mAttributeTable->item( row, column )->checkState() == Qt::Checked )
825 {
826 mAttributeTable->item( row, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsEnabled );
827 mReplaceRawFieldValues->setEnabled( true );
828 }
829 }
830 break;
831 case ColumnIndex::ExportName:
832 {
833 // Check empty export name
834 if ( item->text().isEmpty() )
835 {
836 QMessageBox::warning( this,
837 tr( "Empty export name" ),
838 tr( "Empty export name are not allowed." ) );
839 return;
840 }
841
842 // Rename eventually duplicated names
843 QStringList names = attributesExportNames();
844 while ( names.count( item->text() ) > 1 )
845 item->setText( QString( "%1_2" ).arg( item->text() ) );
846
847 mUseAliasesForExportedName->setCheckState( Qt::PartiallyChecked );
848 }
849 break;
850 case ColumnIndex::Type:
851 // Nothing to do
852 break;
853 case ColumnIndex::ExportAsDisplayedValue:
854 {
855 if ( mAttributeTable->item( row, column )->flags() & Qt::ItemIsUserCheckable )
856 {
857 bool allChecked = true;
858 bool allUnchecked = true;
859 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
860 {
861 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
862 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsEnabled )
863 {
864 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->checkState() == Qt::Unchecked )
865 allChecked = false;
866 else
867 allUnchecked = false;
868 }
869 }
870 mReplaceRawFieldValues->setCheckState( ( !allChecked && !allUnchecked ) ? Qt::PartiallyChecked : ( allChecked ) ? Qt::Checked : Qt::Unchecked );
871 }
872 }
873 break;
874 }
875}
876
877void QgsVectorLayerSaveAsDialog::mCrsSelector_crsChanged( const QgsCoordinateReferenceSystem &crs )
878{
879 mSelectedCrs = crs;
880 mExtentGroupBox->setOutputCrs( mSelectedCrs );
881}
882
884{
885 return mFilename->filePath();
886}
887
889{
890 return leLayername->text();
891}
892
894{
895 return mEncodingComboBox->currentText();
896}
897
899{
900 return mFormatComboBox->currentData().toString();
901}
902
904{
905 return mSelectedCrs.srsid();
906}
907
912
914{
915 QStringList options;
916
917 QgsVectorFileWriter::MetaData driverMetaData;
918
919 if ( QgsVectorFileWriter::driverMetadata( format(), driverMetaData ) )
920 {
921 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
922
923 for ( it = driverMetaData.driverOptions.constBegin(); it != driverMetaData.driverOptions.constEnd(); ++it )
924 {
925 switch ( it.value()->type )
926 {
928 {
930 QSpinBox *sb = mDatasourceOptionsGroupBox->findChild<QSpinBox *>( it.key() );
931 if ( opt && sb && sb->value() != opt->defaultValue )
932 options << QStringLiteral( "%1=%2" ).arg( it.key() ).arg( sb->value() );
933 break;
934 }
935
937 {
939 QComboBox *cb = mDatasourceOptionsGroupBox->findChild<QComboBox *>( it.key() );
940 if ( opt && cb && cb->itemData( cb->currentIndex() ) != opt->defaultValue )
941 options << QStringLiteral( "%1=%2" ).arg( it.key(), cb->currentText() );
942 break;
943 }
944
946 {
948 QLineEdit *le = mDatasourceOptionsGroupBox->findChild<QLineEdit *>( it.key() );
949 if ( opt && le && le->text() != opt->defaultValue )
950 options << QStringLiteral( "%1=%2" ).arg( it.key(), le->text() );
951 break;
952 }
953
955 {
957 dynamic_cast<QgsVectorFileWriter::HiddenOption *>( it.value() );
958 options << QStringLiteral( "%1=%2" ).arg( it.key(), opt->mValue );
959 break;
960 }
961 }
962 }
963 }
964
965 QString plainText = mOgrDatasourceOptions->toPlainText().trimmed();
966 if ( !plainText.isEmpty() )
967 options += plainText.split( '\n' );
968
969 return options;
970}
971
973{
974 QStringList options;
975
976 QgsVectorFileWriter::MetaData driverMetaData;
977
978 if ( QgsVectorFileWriter::driverMetadata( format(), driverMetaData ) )
979 {
980 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
981
982 for ( it = driverMetaData.layerOptions.constBegin(); it != driverMetaData.layerOptions.constEnd(); ++it )
983 {
984 switch ( it.value()->type )
985 {
987 {
989 QSpinBox *sb = mLayerOptionsGroupBox->findChild<QSpinBox *>( it.key() );
990 if ( opt && sb && sb->value() != opt->defaultValue )
991 options << QStringLiteral( "%1=%2" ).arg( it.key() ).arg( sb->value() );
992 break;
993 }
994
996 {
998 QComboBox *cb = mLayerOptionsGroupBox->findChild<QComboBox *>( it.key() );
999 if ( opt && cb && cb->itemData( cb->currentIndex() ) != opt->defaultValue )
1000 options << QStringLiteral( "%1=%2" ).arg( it.key(), cb->currentText() );
1001 break;
1002 }
1003
1005 {
1007 QLineEdit *le = mLayerOptionsGroupBox->findChild<QLineEdit *>( it.key() );
1008 if ( opt && le && le->text() != opt->defaultValue )
1009 options << QStringLiteral( "%1=%2" ).arg( it.key(), le->text() );
1010 break;
1011 }
1012
1014 {
1016 dynamic_cast<QgsVectorFileWriter::HiddenOption *>( it.value() );
1017 options << QStringLiteral( "%1=%2" ).arg( it.key(), opt->mValue );
1018 break;
1019 }
1020 }
1021 }
1022 }
1023
1024 QString plainText = mOgrLayerOptions->toPlainText().trimmed();
1025 if ( !plainText.isEmpty() )
1026 options += plainText.split( '\n' );
1027
1028 return options;
1029}
1030
1032{
1033 QgsAttributeList attributes;
1034
1035 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
1036 {
1037 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::Name ) )->checkState() == Qt::Checked )
1038 {
1039 attributes.append( i );
1040 }
1041 }
1042
1043 return attributes;
1044}
1045
1047{
1048 QgsAttributeList attributes;
1049
1050 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
1051 {
1052 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::Name ) )->checkState() == Qt::Checked &&
1053 ! mAttributeTable->isColumnHidden( static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
1054 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->checkState() == Qt::Checked )
1055 {
1056 attributes.append( i );
1057 }
1058 }
1059
1060 return attributes;
1061}
1062
1064{
1065 QStringList exportNames;
1066 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
1067 exportNames.append( mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportName ) )->text() );
1068
1069 return exportNames;
1070}
1071
1073{
1074 return mAddToCanvas->isChecked() && mAddToCanvas->isEnabled();
1075}
1076
1078{
1079 mAddToCanvas->setChecked( enabled );
1080}
1081
1083{
1084 return mSymbologyExportComboBox->currentData().toInt();
1085}
1086
1088{
1089 return mScaleWidget->scale();
1090}
1091
1093{
1094 mMapCanvas = canvas;
1095 mScaleWidget->setMapCanvas( canvas );
1096 mScaleWidget->setShowCurrentScaleButton( true );
1097 mExtentGroupBox->setCurrentExtent( canvas->mapSettings().visibleExtent(), canvas->mapSettings().destinationCrs() );
1098}
1099
1101{
1102 return mExtentGroupBox->isChecked();
1103}
1104
1106{
1107 return mExtentGroupBox->outputExtent();
1108}
1109
1111{
1112 mSelectedOnly->setChecked( onlySelected );
1113}
1114
1116{
1117 return mSelectedOnly->isChecked();
1118}
1119
1121{
1122 return mCheckPersistMetadata->isChecked();
1123}
1124
1126{
1127 int currentIndexData = mGeometryTypeComboBox->currentData().toInt();
1128 if ( currentIndexData == -1 )
1129 {
1130 //automatic
1131 return QgsWkbTypes::Unknown;
1132 }
1133
1134 return static_cast< QgsWkbTypes::Type >( currentIndexData );
1135}
1136
1138{
1139 int currentIndexData = mGeometryTypeComboBox->currentData().toInt();
1140 return currentIndexData == -1;
1141}
1142
1144{
1145 return mForceMultiCheckBox->isChecked();
1146}
1147
1149{
1150 mForceMultiCheckBox->setChecked( checked );
1151}
1152
1154{
1155 return mIncludeZCheckBox->isChecked();
1156}
1157
1162
1164{
1165 mIncludeZCheckBox->setChecked( checked );
1166}
1167
1168void QgsVectorLayerSaveAsDialog::mSymbologyExportComboBox_currentIndexChanged( const QString &text )
1169{
1170 bool scaleEnabled = true;
1171 if ( text == tr( "No symbology" ) )
1172 {
1173 scaleEnabled = false;
1174 }
1175 mScaleWidget->setEnabled( scaleEnabled );
1176 mScaleLabel->setEnabled( scaleEnabled );
1177}
1178
1179void QgsVectorLayerSaveAsDialog::mGeometryTypeComboBox_currentIndexChanged( int index )
1180{
1181 int currentIndexData = mGeometryTypeComboBox->itemData( index ).toInt();
1182
1183 if ( currentIndexData != -1 && currentIndexData != QgsWkbTypes::NoGeometry )
1184 {
1185 mForceMultiCheckBox->setEnabled( true );
1186 mIncludeZCheckBox->setEnabled( true );
1187 }
1188 else
1189 {
1190 mForceMultiCheckBox->setEnabled( false );
1191 mForceMultiCheckBox->setChecked( false );
1192 mIncludeZCheckBox->setEnabled( false );
1193 mIncludeZCheckBox->setChecked( false );
1194 }
1195}
1196
1197void QgsVectorLayerSaveAsDialog::mSelectAllAttributes_clicked()
1198{
1199 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
1200 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
1201
1202 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
1203 {
1204 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::Name ) )->flags() & Qt::ItemIsEnabled )
1205 {
1206 if ( ! mAttributeTable->isColumnHidden( static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
1207 ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsUserCheckable ) )
1208 {
1209 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsEnabled );
1210 }
1211 mAttributeTable->item( i, static_cast<int>( ColumnIndex::Name ) )->setCheckState( Qt::Checked );
1212 }
1213 }
1214 if ( ! mAttributeTable->isColumnHidden( static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
1215 {
1216 mReplaceRawFieldValues->setEnabled( true );
1217 }
1218}
1219
1220void QgsVectorLayerSaveAsDialog::mDeselectAllAttributes_clicked()
1221{
1222 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
1223 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
1224
1225 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
1226 {
1227 mAttributeTable->item( i, static_cast<int>( ColumnIndex::Name ) )->setCheckState( Qt::Unchecked );
1228 if ( ! mAttributeTable->isColumnHidden( static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
1229 ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsUserCheckable ) )
1230 {
1231 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable );
1232 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( Qt::Unchecked );
1233 }
1234 }
1235 if ( ! mAttributeTable->isColumnHidden( static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
1236 {
1237 mReplaceRawFieldValues->setCheckState( Qt::Unchecked );
1238 mReplaceRawFieldValues->setEnabled( false );
1239 }
1240}
1241
1242void QgsVectorLayerSaveAsDialog::showHelp()
1243{
1244 QgsHelp::openHelp( QStringLiteral( "managing_data_source/create_layers.html#creating-new-layers-from-an-existing-layer" ) );
1245}
This class represents a coordinate reference system (CRS).
QgsDatumEnsemble datumEnsemble() const
Attempts to retrieve datum ensemble details from the CRS.
long srsid() const
Returns the internal CRS ID, if available.
Contains information about a datum ensemble.
Definition qgsdatums.h:95
bool isValid() const
Returns true if the datum ensemble is a valid object, or false if it is a null/invalid object.
Definition qgsdatums.h:102
QString name() const
Display name of datum ensemble.
Definition qgsdatums.h:107
Every attribute editor widget needs a factory, which inherits this class.
QString name() const
Returns The human readable identifier name of this widget type.
QgsEditorWidgetSetup findBest(const QgsVectorLayer *vl, const QString &fieldName) const
Find the best editor widget and its configuration for a given field.
Holder for the widget type and its configuration for a field.
Encapsulate a field in an attribute table or data source.
Definition qgsfield.h:51
QString typeName() const
Gets the field type.
Definition qgsfield.cpp:152
QString name
Definition qgsfield.h:60
QString displayName() const
Returns the name to use when displaying this field.
Definition qgsfield.cpp:90
int count() const
Returns number of items.
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:83
static void enableAutoGeometryRestore(QWidget *widget, const QString &key=QString())
Register the widget to allow its position to be automatically saved and restored when open and closed...
Definition qgsgui.cpp:178
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition qgshelp.cpp:38
static QIcon iconForWkbType(QgsWkbTypes::Type type)
Returns the icon for a vector layer whose geometry type is provided.
Map canvas is a class for displaying all GIS data types on a canvas.
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.
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:62
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
static QStringList availableEncodings()
Returns a list of available encodings.
QgsVectorFileWriter::OptionType type
A convenience class for writing vector layers to disk based formats (e.g.
@ CanAppendToExistingLayer
Flag to indicate that new features can be added to an existing layer.
@ CanAddNewLayer
Flag to indicate that a new layer can be added to the dataset.
@ CanDeleteLayer
Flag to indicate that an existing layer can be deleted.
static QgsVectorFileWriter::EditionCapabilities editionCapabilities(const QString &datasetName)
Returns edition capabilities for an existing dataset name.
static bool supportsFeatureStyles(const QString &driverName)
Returns true if the specified driverName supports feature styles.
static bool targetLayerExists(const QString &datasetName, const QString &layerName)
Returns whether the target layer already exists.
static bool driverMetadata(const QString &driverName, MetaData &driverMetadata)
static QString filterForDriver(const QString &driverName)
Creates a filter for an OGR driver key.
static bool areThereNewFieldsToCreate(const QString &datasetName, const QString &layerName, QgsVectorLayer *layer, const QgsAttributeList &attributes)
Returns whether there are among the attributes specified some that do not exist yet in the layer.
static QList< QgsVectorFileWriter::DriverDetails > ogrDriverList(VectorFormatOptions options=SortRecommended)
Returns the driver list that can be used for dialogs.
ActionOnExistingFile
Combination of CanAddNewLayer, CanAppendToExistingLayer, CanAddNewFieldsToExistingLayer or CanDeleteL...
@ CreateOrOverwriteLayer
Create or overwrite layer.
@ CreateOrOverwriteFile
Create or overwrite file.
@ AppendToLayerNoNewFields
Append features to existing layer, but do not create new fields.
@ AppendToLayerAddFields
Append features to existing layer, and create new fields if needed.
bool onlySelected() const
Returns whether only selected features will be saved.
bool forceMulti() const
Returns true if force multi geometry type is checked.
QString filename() const
Returns the target filename.
QgsAttributeList selectedAttributes() const
Returns a list of attributes which are selected for saving.
QgsRectangle filterExtent() const
Determines the extent to be exported.
Q_DECL_DEPRECATED long crs() const
Returns the internal CRS ID.
QString format() const
The format in which the export should be written.
QStringList datasourceOptions() const
Returns a list of additional data source options which are passed to OGR.
bool persistMetadata() const
Returns true if the persist metadata (copy source metadata to destination layer) option is checked.
QString encoding() const
The encoding of the target file.
void setIncludeZ(bool checked)
Sets whether the include z dimension checkbox should be checked.
QStringList attributesExportNames() const
Returns a list of export names for attributes.
void setOnlySelected(bool onlySelected)
Sets whether only selected features will be saved.
@ DestinationCrs
Show destination CRS (reprojection) option.
@ AddToCanvas
Show add to map option.
@ SelectedOnly
Show selected features only option.
@ Fields
Show field customization group.
bool automaticGeometryType() const
Returns true if geometry type is set to automatic.
QString layername() const
Returns the target layer name.
QgsWkbTypes::Type geometryType() const
Returns the selected flat geometry type for the export.
Q_DECL_DEPRECATED QgsVectorLayerSaveAsDialog(long srsid, QWidget *parent=nullptr, Qt::WindowFlags fl=Qt::WindowFlags())
Construct a new QgsVectorLayerSaveAsDialog.
bool includeZ() const
Returns true if include z dimension is checked.
QgsCoordinateReferenceSystem crsObject() const
Returns the CRS chosen for export.
QStringList layerOptions() const
Returns a list of additional layer options which are passed to OGR.
void setForceMulti(bool checked)
Sets whether the force multi geometry checkbox should be checked.
bool addToCanvas() const
Returns true if the "add to canvas" checkbox is checked.
void setMapCanvas(QgsMapCanvas *canvas)
Sets a map canvas to associate with the dialog.
QgsVectorFileWriter::ActionOnExistingFile creationActionOnExistingFile() const
Returns creation action.
int symbologyExport() const
Returns type of symbology export.
QgsAttributeList attributesAsDisplayedValues() const
Returns selected attributes that must be exported with their displayed values instead of their raw va...
double scale() const
Returns the specified map scale.
bool hasFilterExtent() const
Determines if filtering the export by an extent is activated.
void setAddToCanvas(bool checked)
Sets whether the "add to canvas" checkbox should be checked.
Represents a vector layer which manages a vector based data sets.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
int selectedFeatureCount() const
Returns the number of features that are selected in this layer.
QgsRectangle extent() const FINAL
Returns the extent of the layer.
Type
The WKB type describes the number of dimensions a geometry has.
Definition qgswkbtypes.h:70
static QString translatedDisplayString(Type 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:2453
QList< int > QgsAttributeList
Definition qgsfield.h:26
const QgsCoordinateReferenceSystem & crs
Details of available driver formats.
QMap< QString, QgsVectorFileWriter::Option * > driverOptions
QMap< QString, QgsVectorFileWriter::Option * > layerOptions
QString compulsoryEncoding
Some formats require a compulsory encoding, typically UTF-8. If no compulsory encoding,...