40#include <QRegularExpression>
45#include "moc_qgsvectorlayersaveasdialog.cpp"
47using namespace Qt::StringLiterals;
50 : QDialog( parent, fl )
58 : QDialog( parent, fl )
65 mSelectedCrs = layer->
crs();
66 mLayerExtent = layer->
extent();
73 leLayername->setDefaultValue( mDefaultOutputLayerNameFromInputLayerName );
75 if ( leLayername->isEnabled() )
76 leLayername->setText( mDefaultOutputLayerNameFromInputLayerName );
81 mSymbologyExportLabel->hide();
82 mSymbologyExportComboBox->hide();
93 mAttributesSelection->hide();
96 mSelectedOnly->hide();
102 mGeometryGroupBox->hide();
105 mExtentGroupBox->hide();
109 mCheckPersistMetadata->setChecked(
false );
110 mCheckPersistMetadata->hide();
114 mButtonBox->button( QDialogButtonBox::Ok )->setDisabled(
true );
117void QgsVectorLayerSaveAsDialog::setup()
122 connect( mFormatComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsVectorLayerSaveAsDialog::mFormatComboBox_currentIndexChanged );
124 connect( mSymbologyExportComboBox, &QComboBox::currentTextChanged,
this, &QgsVectorLayerSaveAsDialog::mSymbologyExportComboBox_currentIndexChanged );
125 connect( mGeometryTypeComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsVectorLayerSaveAsDialog::mGeometryTypeComboBox_currentIndexChanged );
126 connect( mSelectAllAttributes, &QPushButton::clicked,
this, &QgsVectorLayerSaveAsDialog::mSelectAllAttributes_clicked );
127 connect( mDeselectAllAttributes, &QPushButton::clicked,
this, &QgsVectorLayerSaveAsDialog::mDeselectAllAttributes_clicked );
128 connect( mUseAliasesForExportedName, &QCheckBox::stateChanged,
this, &QgsVectorLayerSaveAsDialog::mUseAliasesForExportedName_stateChanged );
129 connect( mReplaceRawFieldValues, &QCheckBox::stateChanged,
this, &QgsVectorLayerSaveAsDialog::mReplaceRawFieldValues_stateChanged );
130 connect( mAttributeTable, &QTableWidget::itemChanged,
this, &QgsVectorLayerSaveAsDialog::mAttributeTable_itemChanged );
133 mHelpButtonBox->setVisible(
false );
134 mButtonBox->addButton( QDialogButtonBox::Help );
135 connect( mButtonBox, &QDialogButtonBox::helpRequested,
this, &QgsVectorLayerSaveAsDialog::showHelp );
137 connect( mHelpButtonBox, &QDialogButtonBox::helpRequested,
this, &QgsVectorLayerSaveAsDialog::showHelp );
140 connect( mButtonBox, &QDialogButtonBox::rejected,
this, &QgsVectorLayerSaveAsDialog::reject );
143 mFormatComboBox->blockSignals(
true );
146 mFormatComboBox->addItem( driver.longName, driver.driverName );
149 QgsSettings settings;
150 QString
format = settings.
value( u
"UI/lastVectorFormat"_s,
"GPKG" ).toString();
151 mFormatComboBox->setCurrentIndex( mFormatComboBox->findData(
format ) );
152 mFormatComboBox->blockSignals(
false );
159 mGeometryTypeComboBox->addItem( tr(
"Automatic" ), -1 );
165 mGeometryTypeComboBox->setCurrentIndex( mGeometryTypeComboBox->findData( -1 ) );
169 QString enc = settings.
value( u
"UI/encoding"_s,
"System" ).toString();
170 int idx = mEncodingComboBox->findText( enc );
173 mEncodingComboBox->insertItem( 0, enc );
177 mCrsSelector->setCrs( mSelectedCrs );
178 mCrsSelector->setLayerCrs( mSelectedCrs );
179 mCrsSelector->setMessage( tr(
"Select the coordinate reference system for the vector file. "
180 "The data points will be transformed from the layer coordinate reference system." ) );
182 mEncodingComboBox->setCurrentIndex( idx );
183 mFormatComboBox_currentIndexChanged( mFormatComboBox->currentIndex() );
189 mSymbologyExportComboBox_currentIndexChanged( mSymbologyExportComboBox->currentText() );
192 mExtentGroupBox->setOutputCrs( mSelectedCrs );
193 mExtentGroupBox->setOriginalExtent( mLayerExtent, mSelectedCrs );
194 mExtentGroupBox->setOutputExtentFromOriginal();
195 mExtentGroupBox->setCheckable(
true );
196 mExtentGroupBox->setChecked(
false );
197 mExtentGroupBox->setCollapsed(
true );
200 mFilename->setDialogTitle( tr(
"Save Layer As" ) );
201 mFilename->setDefaultRoot( settings.
value( u
"UI/lastVectorFileFilterDir"_s, QDir::homePath() ).toString() );
202 mFilename->setConfirmOverwrite(
false );
204 QgsSettings settings;
205 QFileInfo tmplFileInfo( filePath );
206 settings.
setValue( u
"UI/lastVectorFileFilterDir"_s, tmplFileInfo.absolutePath() );
208 const QFileInfo fileInfo( filePath );
210 if ( mDefaultOutputLayerNameFromInputLayerName.isEmpty() )
211 leLayername->setDefaultValue( suggestedLayerName );
214 if ( leLayername->text().isEmpty() && !filePath.isEmpty() && leLayername->isEnabled() )
216 leLayername->setText( suggestedLayerName );
218 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( !filePath.isEmpty() );
223 const QgsDatumEnsemble ensemble = mSelectedCrs.datumEnsemble();
226 mCrsSelector->setSourceEnsemble( ensemble.
name() );
229 catch ( QgsNotSupportedException & )
233 mCrsSelector->setShowAccuracyWarnings(
true );
236QList<QPair<QLabel *, QWidget *>> QgsVectorLayerSaveAsDialog::createControls(
const QMap<QString, QgsVectorFileWriter::Option *> &options )
238 QList<QPair<QLabel *, QWidget *>> controls;
239 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
241 for ( it = options.constBegin(); it != options.constEnd(); ++it )
243 QgsVectorFileWriter::Option *option = it.value();
244 QWidget *control =
nullptr;
245 switch ( option->
type )
249 QgsVectorFileWriter::IntOption *opt =
dynamic_cast<QgsVectorFileWriter::IntOption *
>( option );
252 QSpinBox *sb =
new QSpinBox();
253 sb->setObjectName( it.key() );
254 sb->setMaximum( std::numeric_limits<int>::max() );
263 QgsVectorFileWriter::SetOption *opt =
dynamic_cast<QgsVectorFileWriter::SetOption *
>( option );
266 QComboBox *cb =
new QComboBox();
267 cb->setObjectName( it.key() );
268 for (
const QString &val : std::as_const( opt->
values ) )
270 cb->addItem( val, val );
277 cb->setCurrentIndex( idx );
285 QgsVectorFileWriter::StringOption *opt =
dynamic_cast<QgsVectorFileWriter::StringOption *
>( option );
289 le->setObjectName( it.key() );
302 QLabel *label =
new QLabel( it.key() );
305 label->setToolTip( u
"<p>%1</p>"_s.arg( option->
docString.toHtmlEscaped() ) );
306 control->setToolTip( u
"<p>%1</p>"_s.arg( option->
docString.toHtmlEscaped() ) );
308 controls << QPair<QLabel *, QWidget *>( label, control );
317#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION( 3, 9, 0 )
318 if (
format() ==
"OpenFileGDB"_L1 )
322 bool targetAll =
true;
325 if ( layerOption ==
"TARGET_ARCGIS_VERSION=ARCGIS_PRO_3_2_OR_LATER"_L1 )
332 for (
int i = 0; i < mLayer->fields().size(); ++i )
334 QgsField fld = mLayer->fields().at( i );
335 if ( fld.
type() == QMetaType::Type::LongLong )
337 if ( QMessageBox::question(
this, tr(
"Save Vector Layer As" ), tr(
"The layer contains at least one 64-bit integer field, which, with the current settings, can only be exported as a Real field. It could be exported as a 64-bit integer field if the TARGET_ARCGIS_VERSION layer option is set to ARCGIS_PRO_3_2_OR_LATER. Do you want to continue and export it as a Real field?" ) ) != QMessageBox::Yes )
346 else if (
format() ==
"FileGDB"_L1 )
349 for (
int i = 0; i < mLayer->fields().size(); ++i )
351 QgsField fld = mLayer->fields().at( i );
352 if ( fld.
type() == QMetaType::Type::LongLong )
354 if ( QMessageBox::question(
this, tr(
"Save Vector Layer As" ), tr(
"The layer contains at least one 64-bit integer field, which cannot be exported as such when using this output driver. 64-bit integer fields could be supported by selecting the %1 format and setting its TARGET_ARCGIS_VERSION layer option to ARCGIS_PRO_3_2_OR_LATER. Do you want to continue and export it as a Real field?" ).arg( tr(
"ESRI File Geodatabase" ) ) ) != QMessageBox::Yes )
369 msgBox.setIcon( QMessageBox::Question );
370 msgBox.setWindowTitle( tr(
"Save Vector Layer As" ) );
371 QPushButton *overwriteFileButton = msgBox.addButton( tr(
"Overwrite File" ), QMessageBox::ActionRole );
372 QPushButton *overwriteLayerButton = msgBox.addButton( tr(
"Overwrite Layer" ), QMessageBox::ActionRole );
373 QPushButton *appendToLayerButton = msgBox.addButton( tr(
"Append to Layer" ), QMessageBox::ActionRole );
374 msgBox.setStandardButtons( QMessageBox::Cancel );
375 msgBox.setDefaultButton( QMessageBox::Cancel );
376 overwriteFileButton->hide();
377 overwriteLayerButton->hide();
378 appendToLayerButton->hide();
383 msgBox.setText( tr(
"The layer already exists. Do you want to overwrite the whole file or overwrite the layer?" ) );
384 overwriteFileButton->setVisible(
true );
385 overwriteLayerButton->setVisible(
true );
389 msgBox.setText( tr(
"The file already exists. Do you want to overwrite it?" ) );
390 overwriteFileButton->setVisible(
true );
394 msgBox.setText( tr(
"The layer already exists. Do you want to overwrite the whole file, overwrite the layer or append features to the layer?" ) );
395 appendToLayerButton->setVisible(
true );
396 overwriteFileButton->setVisible(
true );
397 overwriteLayerButton->setVisible(
true );
401 msgBox.setText( tr(
"The layer already exists. Do you want to overwrite the whole file or append features to the layer?" ) );
402 appendToLayerButton->setVisible(
true );
403 overwriteFileButton->setVisible(
true );
406 int ret = msgBox.exec();
407 if ( ret == QMessageBox::Cancel )
409 if ( msgBox.clickedButton() == overwriteFileButton )
411 else if ( msgBox.clickedButton() == overwriteLayerButton )
413 else if ( msgBox.clickedButton() == appendToLayerButton )
425 if ( QMessageBox::question(
this, tr(
"Save Vector Layer As" ), tr(
"The file already exists. Do you want to overwrite it?" ) ) != QMessageBox::Yes )
438 if ( QMessageBox::question(
this, tr(
"Save Vector Layer As" ), tr(
"The existing layer has additional fields. Do you want to add the missing fields to the layer?" ) ) == QMessageBox::Yes )
447 QStringList layerList;
448 layerList.reserve( sublayers.size() );
451 layerList.append( sublayer.name() );
453 if ( layerList.length() > 1 )
455 layerList.sort( Qt::CaseInsensitive );
457 msgBox.setIcon( QMessageBox::Warning );
458 msgBox.setWindowTitle( tr(
"Overwrite File" ) );
459 msgBox.setText( tr(
"This file contains %1 layers that will be lost!\n" ).arg( QLocale().toString( layerList.length() ) ) );
460 msgBox.setDetailedText( tr(
"The following layers will be permanently lost:\n\n%1" ).arg( layerList.join(
"\n" ) ) );
461 msgBox.setStandardButtons( QMessageBox::Ok | QMessageBox::Cancel );
462 if ( msgBox.exec() == QMessageBox::Cancel )
468 settings.
setValue( u
"UI/lastVectorFileFilterDir"_s, QFileInfo(
fileName() ).absolutePath() );
474void QgsVectorLayerSaveAsDialog::mFormatComboBox_currentIndexChanged(
int idx )
478 mFilename->setEnabled(
true );
486 if (
format() ==
"OpenFileGDB"_L1 ||
format() ==
"FileGDB"_L1 )
487 filter = u
"%1 (*.gdb *.GDB gdb)"_s.arg( tr(
"ESRI File Geodatabase" ) );
488 mFilename->setFilter( filter );
492 if ( !mFilename->filePath().isEmpty() )
494 const thread_local QRegularExpression rx(
"\\.(.*?)[\\s]" );
495 const QString ext = rx.match( filter ).captured( 1 );
496 if ( !ext.isEmpty() )
498 QFileInfo fi( mFilename->filePath() );
499 mFilename->setFilePath( u
"%1/%2.%3"_s.arg( fi.path(), fi.baseName(), ext ) );
503 bool selectAllFields =
true;
508 bool isFormatForFieldsAsDisplayedValues =
false;
510 const QString sFormat(
format() );
511 if ( sFormat ==
"DXF"_L1 || sFormat ==
"DGN"_L1 )
513 mAttributesSelection->setVisible(
false );
514 selectAllFields =
false;
520 mAttributesSelection->setVisible(
true );
521 isFormatForFieldsAsDisplayedValues = ( sFormat ==
"CSV"_L1 || sFormat ==
"XLS"_L1 || sFormat ==
"XLSX"_L1 || sFormat ==
"ODS"_L1 );
528 mSymbologyExportLabel->setVisible(
true );
529 mSymbologyExportComboBox->setVisible(
true );
530 mScaleLabel->setVisible(
true );
531 mScaleWidget->setVisible(
true );
535 mSymbologyExportLabel->hide();
536 mSymbologyExportComboBox->hide();
538 mScaleWidget->hide();
541 leLayername->setEnabled( sFormat ==
"KML"_L1 || sFormat ==
"GPKG"_L1 || sFormat ==
"XLSX"_L1 || sFormat ==
"ODS"_L1 || sFormat ==
"FileGDB"_L1 || sFormat ==
"OpenFileGDB"_L1 || sFormat ==
"SQLite"_L1 || sFormat ==
"SpatiaLite"_L1 );
543 if ( sFormat ==
"XLSX"_L1 )
544 leLayername->setMaxLength( 31 );
545 else if ( leLayername->isEnabled() )
546 leLayername->setMaxLength( 32767 );
548 if ( !leLayername->isEnabled() )
549 leLayername->setText( QString() );
550 else if ( leLayername->text().isEmpty() )
552 QString
layerName = mDefaultOutputLayerNameFromInputLayerName;
553 if (
layerName.isEmpty() && !mFilename->filePath().isEmpty() )
555 layerName = QFileInfo( mFilename->filePath() ).baseName();
556 leLayername->setDefaultValue(
layerName );
565 mAttributeTable->setRowCount( mLayer->fields().count() );
567 QStringList horizontalHeaders = QStringList() << tr(
"Name" ) << tr(
"Export name" ) << tr(
"Type" ) << tr(
"Replace with displayed values" );
568 mAttributeTable->setColumnCount( horizontalHeaders.size() );
569 mAttributeTable->setHorizontalHeaderLabels( horizontalHeaders );
571 bool foundFieldThatCanBeExportedAsDisplayedValue =
false;
572 for (
int i = 0; i < mLayer->fields().size(); ++i )
577 foundFieldThatCanBeExportedAsDisplayedValue =
true;
581 mAttributeTable->setColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ), !foundFieldThatCanBeExportedAsDisplayedValue );
583 bool checkReplaceRawFieldValues = selectAllFields && isFormatForFieldsAsDisplayedValues;
584 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
586 for (
int i = 0; i < mLayer->fields().size(); ++i )
588 QgsField fld = mLayer->fields().at( i );
589 Qt::ItemFlags flags = mLayer->providerType() !=
"oracle"_L1 || !fld.
typeName().contains(
"SDO_GEOMETRY"_L1 ) ? Qt::ItemIsEnabled : Qt::NoItemFlags;
590 QTableWidgetItem *item =
nullptr;
591 item =
new QTableWidgetItem( fld.
name() );
592 item->setFlags( flags | Qt::ItemIsUserCheckable );
593 item->setCheckState( ( selectAllFields ) ? Qt::Checked : Qt::Unchecked );
594 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::Name ), item );
596 item =
new QTableWidgetItem( fld.
name() );
597 item->setFlags( flags | Qt::ItemIsEditable );
599 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::ExportName ), item );
601 item =
new QTableWidgetItem( fld.
typeName() );
602 item->setFlags( flags );
603 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::Type ), item );
605 if ( foundFieldThatCanBeExportedAsDisplayedValue )
608 QgsEditorWidgetFactory *factory =
nullptr;
609 const QString widgetId( setup.type() );
612 item =
new QTableWidgetItem( tr(
"Use %1" ).arg( factory->
name() ) );
613 item->setFlags( ( selectAllFields ) ? ( Qt::ItemIsEnabled | Qt::ItemIsUserCheckable ) : Qt::ItemIsUserCheckable );
614 const bool checkItem = ( selectAllFields && isFormatForFieldsAsDisplayedValues && ( widgetId ==
"ValueMap"_L1 || widgetId ==
"ValueRelation"_L1 || widgetId ==
"CheckBox"_L1 || widgetId ==
"RelationReference"_L1 ) );
615 checkReplaceRawFieldValues &= checkItem;
616 item->setCheckState( checkItem ? Qt::Checked : Qt::Unchecked );
617 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ), item );
621 item =
new QTableWidgetItem();
622 item->setFlags( Qt::NoItemFlags );
623 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ), item );
629 whileBlocking( mReplaceRawFieldValues )->setChecked( checkReplaceRawFieldValues );
630 mReplaceRawFieldValues->setEnabled( selectAllFields );
631 mReplaceRawFieldValues->setVisible( foundFieldThatCanBeExportedAsDisplayedValue );
633 mAttributeTable->resizeColumnsToContents();
636 QgsVectorFileWriter::MetaData driverMetaData;
638 while ( mDatasourceOptionsGroupBox->layout()->count() )
640 QLayoutItem *item = mDatasourceOptionsGroupBox->layout()->takeAt( 0 );
641 delete item->widget();
645 while ( mLayerOptionsGroupBox->layout()->count() )
647 QLayoutItem *item = mLayerOptionsGroupBox->layout()->takeAt( 0 );
648 delete item->widget();
652 typedef QPair<QLabel *, QWidget *> LabelControlPair;
658 mDatasourceOptionsGroupBox->setVisible(
true );
659 QList<QPair<QLabel *, QWidget *>> controls = createControls( driverMetaData.
driverOptions );
661 QFormLayout *datasourceLayout =
dynamic_cast<QFormLayout *
>( mDatasourceOptionsGroupBox->layout() );
663 const auto constControls = controls;
664 for ( LabelControlPair control : constControls )
666 datasourceLayout->addRow( control.first, control.second );
671 mDatasourceOptionsGroupBox->setVisible(
false );
676 mLayerOptionsGroupBox->setVisible(
true );
677 QList<QPair<QLabel *, QWidget *>> controls = createControls( driverMetaData.
layerOptions );
679 QFormLayout *layerOptionsLayout =
dynamic_cast<QFormLayout *
>( mLayerOptionsGroupBox->layout() );
681 const auto constControls = controls;
682 for ( LabelControlPair control : constControls )
684 layerOptionsLayout->addRow( control.first, control.second );
689 mLayerOptionsGroupBox->setVisible(
false );
694 mEncodingComboBox->setEnabled(
true );
701 mEncodingComboBox->setCurrentIndex( idx );
702 mEncodingComboBox->setDisabled(
true );
706 mEncodingComboBox->setEnabled(
true );
712 mEncodingComboBox->setEnabled(
true );
715 GDALDriverH hDriver = GDALGetDriverByName(
format().toUtf8().constData() );
718 const bool canReopen = GDALGetMetadataItem( hDriver, GDAL_DCAP_OPEN,
nullptr );
719 if ( mAddToCanvas->isEnabled() && !canReopen )
721 mAddToCanvasStateOnOpenCompatibleDriver = mAddToCanvas->isChecked();
722 mAddToCanvas->setChecked(
false );
723 mAddToCanvas->setEnabled(
false );
725 else if ( !mAddToCanvas->isEnabled() && canReopen )
727 mAddToCanvas->setChecked( mAddToCanvasStateOnOpenCompatibleDriver );
728 mAddToCanvas->setEnabled(
true );
733void QgsVectorLayerSaveAsDialog::mUseAliasesForExportedName_stateChanged(
int state )
735 const QSignalBlocker signalBlocker( mAttributeTable );
742 bool modifiedEntries =
false;
743 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
745 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->text()
746 != mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->data( Qt::UserRole ).toString() )
748 modifiedEntries =
true;
753 if ( modifiedEntries )
755 if ( QMessageBox::question(
this, tr(
"Modified names" ), tr(
"Some names were modified and will be overridden. Do you want to continue?" ) )
758 whileBlocking( mUseAliasesForExportedName )->setCheckState( Qt::PartiallyChecked );
763 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
765 mUseAliasesForExportedName->setTristate(
false );
766 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->setText( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->text() );
773 bool modifiedEntries =
false;
774 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
776 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->text()
777 != mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->text() )
778 modifiedEntries =
true;
781 if ( modifiedEntries )
783 if ( QMessageBox::question(
this, tr(
"Modified names" ), tr(
"Some names were modified and will be overridden. Do you want to continue?" ) )
786 whileBlocking( mUseAliasesForExportedName )->setCheckState( Qt::PartiallyChecked );
791 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
793 mUseAliasesForExportedName->setTristate(
false );
794 const QString alias = mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->data( Qt::UserRole ).toString();
795 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->setText( alias );
799 case Qt::PartiallyChecked:
805void QgsVectorLayerSaveAsDialog::mReplaceRawFieldValues_stateChanged(
int )
807 if ( mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
810 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
811 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
813 if ( mReplaceRawFieldValues->checkState() != Qt::PartiallyChecked )
815 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
817 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->checkState() == Qt::Checked && mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) && mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsEnabled )
819 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( mReplaceRawFieldValues->checkState() );
823 mReplaceRawFieldValues->setTristate(
false );
826void QgsVectorLayerSaveAsDialog::mAttributeTable_itemChanged( QTableWidgetItem *item )
828 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
829 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
831 int row = item->row();
832 int column = item->column();
834 switch (
static_cast<ColumnIndex
>( column ) )
836 case ColumnIndex::Name:
838 if ( mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) || !mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) || !( mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsUserCheckable ) )
841 if ( mAttributeTable->item( row, column )->checkState() == Qt::Unchecked )
843 mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( Qt::Unchecked );
844 mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable );
845 bool checkBoxEnabled =
false;
846 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
848 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) && mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsEnabled )
850 checkBoxEnabled =
true;
854 mReplaceRawFieldValues->setEnabled( checkBoxEnabled );
855 if ( !checkBoxEnabled )
856 mReplaceRawFieldValues->setCheckState( Qt::Unchecked );
858 else if ( mAttributeTable->item( row, column )->checkState() == Qt::Checked )
860 mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsEnabled );
861 mReplaceRawFieldValues->setEnabled(
true );
865 case ColumnIndex::ExportName:
868 if ( item->text().isEmpty() )
870 QMessageBox::warning(
this, tr(
"Empty export name" ), tr(
"Empty export name are not allowed." ) );
876 while ( names.count( item->text() ) > 1 )
877 item->setText( QString(
"%1_2" ).arg( item->text() ) );
879 mUseAliasesForExportedName->setCheckState( Qt::PartiallyChecked );
882 case ColumnIndex::Type:
885 case ColumnIndex::ExportAsDisplayedValue:
887 if ( mAttributeTable->item( row, column )->flags() & Qt::ItemIsUserCheckable )
889 bool allChecked =
true;
890 bool allUnchecked =
true;
891 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
893 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) && mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsEnabled )
895 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->checkState() == Qt::Unchecked )
898 allUnchecked =
false;
901 mReplaceRawFieldValues->setCheckState( ( !allChecked && !allUnchecked ) ? Qt::PartiallyChecked : ( allChecked ) ? Qt::Checked
912 mExtentGroupBox->setOutputCrs( mSelectedCrs );
917 return mFilename->filePath();
922 return leLayername->text();
927 return mEncodingComboBox->currentText();
932 return mFormatComboBox->currentData().toString();
948 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
952 switch ( it.value()->type )
957 QSpinBox *sb = mDatasourceOptionsGroupBox->findChild<QSpinBox *>( it.key() );
959 options << u
"%1=%2"_s.arg( it.key() ).arg( sb->value() );
966 QComboBox *cb = mDatasourceOptionsGroupBox->findChild<QComboBox *>( it.key() );
967 if ( opt && cb && cb->itemData( cb->currentIndex() ) != opt->
defaultValue )
968 options << u
"%1=%2"_s.arg( it.key(), cb->currentText() );
975 QLineEdit *le = mDatasourceOptionsGroupBox->findChild<QLineEdit *>( it.key() );
977 options << u
"%1=%2"_s.arg( it.key(), le->text() );
984 if ( opt && !opt->
mValue.isEmpty() )
985 options << u
"%1=%2"_s.arg( it.key(), opt->
mValue );
992 QString plainText = mOgrDatasourceOptions->toPlainText().trimmed();
993 if ( !plainText.isEmpty() )
994 options += plainText.split(
'\n' );
1001 QStringList options;
1007 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
1011 switch ( it.value()->type )
1016 QSpinBox *sb = mLayerOptionsGroupBox->findChild<QSpinBox *>( it.key() );
1018 options << u
"%1=%2"_s.arg( it.key() ).arg( sb->value() );
1025 QComboBox *cb = mLayerOptionsGroupBox->findChild<QComboBox *>( it.key() );
1026 if ( opt && cb && cb->itemData( cb->currentIndex() ) != opt->
defaultValue )
1027 options << u
"%1=%2"_s.arg( it.key(), cb->currentText() );
1034 QLineEdit *le = mLayerOptionsGroupBox->findChild<QLineEdit *>( it.key() );
1036 options << u
"%1=%2"_s.arg( it.key(), le->text() );
1043 if ( !opt->
mValue.isEmpty() )
1044 options << u
"%1=%2"_s.arg( it.key(), opt->
mValue );
1051 QString plainText = mOgrLayerOptions->toPlainText().trimmed();
1052 if ( !plainText.isEmpty() )
1053 options += plainText.split(
'\n' );
1062 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1064 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->checkState() == Qt::Checked )
1066 attributes.append( i );
1077 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1079 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->checkState() == Qt::Checked && !mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) && mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->checkState() == Qt::Checked )
1081 attributes.append( i );
1090 QStringList exportNames;
1091 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1092 exportNames.append( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->text() );
1099 return mAddToCanvas->isChecked();
1104 mAddToCanvasStateOnOpenCompatibleDriver = enabled;
1105 if ( mAddToCanvas->isEnabled() )
1106 mAddToCanvas->setChecked( enabled );
1116 return mScaleWidget->scale();
1121 mMapCanvas = canvas;
1122 mScaleWidget->setMapCanvas( canvas );
1123 mScaleWidget->setShowCurrentScaleButton(
true );
1129 return mExtentGroupBox->isChecked();
1134 return mExtentGroupBox->outputExtent();
1144 return mSelectedOnly->isChecked();
1149 return mCheckPersistMetadata->isChecked();
1154 int currentIndexData = mGeometryTypeComboBox->currentData().toInt();
1155 if ( currentIndexData == -1 )
1166 int currentIndexData = mGeometryTypeComboBox->currentData().toInt();
1167 return currentIndexData == -1;
1172 return mForceMultiCheckBox->isChecked();
1177 mForceMultiCheckBox->setChecked( checked );
1182 return mIncludeZCheckBox->isChecked();
1187 return mActionOnExistingFile;
1192 mIncludeZCheckBox->setChecked( checked );
1195void QgsVectorLayerSaveAsDialog::mSymbologyExportComboBox_currentIndexChanged(
const QString &text )
1197 bool scaleEnabled =
true;
1198 if ( text == tr(
"No symbology" ) )
1200 scaleEnabled =
false;
1202 mScaleWidget->setEnabled( scaleEnabled );
1203 mScaleLabel->setEnabled( scaleEnabled );
1206void QgsVectorLayerSaveAsDialog::mGeometryTypeComboBox_currentIndexChanged(
int )
1208 const int currentIndexData = mGeometryTypeComboBox->currentData().toInt();
1211 mForceMultiCheckBox->setEnabled(
true );
1212 mIncludeZCheckBox->setEnabled(
true );
1218 mForceMultiCheckBox->setEnabled(
false );
1219 mForceMultiCheckBox->setChecked(
false );
1223 mForceMultiCheckBox->setEnabled(
true );
1225 mIncludeZCheckBox->setEnabled(
false );
1226 mIncludeZCheckBox->setChecked(
false );
1230void QgsVectorLayerSaveAsDialog::mSelectAllAttributes_clicked()
1232 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
1233 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
1235 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1237 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->flags() & Qt::ItemIsEnabled )
1239 if ( !mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) && ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsUserCheckable ) )
1241 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsEnabled );
1243 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->setCheckState( Qt::Checked );
1246 if ( !mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
1248 mReplaceRawFieldValues->setEnabled(
true );
1252void QgsVectorLayerSaveAsDialog::mDeselectAllAttributes_clicked()
1254 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
1255 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
1257 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1259 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->setCheckState( Qt::Unchecked );
1260 if ( !mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) && ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsUserCheckable ) )
1262 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable );
1263 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( Qt::Unchecked );
1266 if ( !mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
1268 mReplaceRawFieldValues->setCheckState( Qt::Unchecked );
1269 mReplaceRawFieldValues->setEnabled(
false );
1273void QgsVectorLayerSaveAsDialog::showHelp()
1275 QgsHelp::openHelp( u
"managing_data_source/create_layers.html#creating-new-layers-from-an-existing-layer"_s );
WkbType
The WKB type describes the number of dimensions a geometry has.
@ GeometryCollection
GeometryCollection.
FeatureSymbologyExport
Options for exporting features considering their symbology.
@ 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.
Represents a coordinate reference system (CRS).
bool isValid() const
Returns true if the datum ensemble is a valid object, or false if it is a null/invalid object.
QString name() const
Display name of datum ensemble.
Encapsulate a field in an attribute table or data source.
QString typeName() const
Gets the field type.
QString displayName() const
Returns the name to use when displaying this field.
@ 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.
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...
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
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...
QgsCoordinateReferenceSystem crs
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.
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.
Stores settings for use within QGIS.
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 QVariant createNullVariant(QMetaType::Type metaType)
Helper method to properly create a null QVariant from a metaType Returns the created QVariant.
static QStringList availableEncodings()
Returns a list of available encodings.
A hidden option for file writing for a particular output format.
An available option for configuring file writing for a particular output format, presenting an intege...
QgsVectorFileWriter::OptionType type
An available option for configuring file writing for a particular output format, presenting a choice ...
An available option for configuring file writing for a particular output format, presenting a freefor...
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.
QFlags< EditionCapability > EditionCapabilities
Combination of CanAddNewLayer, CanAppendToExistingLayer, CanAddNewFieldsToExistingLayer or CanDeleteL...
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
Enumeration to describe how to handle existing files.
@ 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())
Construct a new QgsVectorLayerSaveAsDialog.
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.
@ Extent
Show extent 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.
QFlags< Option > Options
Available dialog options.
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 dataset.
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 Q_INVOKABLE 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.
QList< int > QgsAttributeList
Details of available driver formats.