40#include <QRegularExpression>
44#include "moc_qgsvectorlayersaveasdialog.cpp"
47 : QDialog( parent, fl )
55 : QDialog( parent, fl )
62 mSelectedCrs = layer->
crs();
63 mLayerExtent = layer->
extent();
70 leLayername->setDefaultValue( mDefaultOutputLayerNameFromInputLayerName );
72 if ( leLayername->isEnabled() )
73 leLayername->setText( mDefaultOutputLayerNameFromInputLayerName );
78 mSymbologyExportLabel->hide();
79 mSymbologyExportComboBox->hide();
90 mAttributesSelection->hide();
93 mSelectedOnly->hide();
99 mGeometryGroupBox->hide();
102 mExtentGroupBox->hide();
106 mCheckPersistMetadata->setChecked(
false );
107 mCheckPersistMetadata->hide();
111 mButtonBox->button( QDialogButtonBox::Ok )->setDisabled(
true );
114void QgsVectorLayerSaveAsDialog::setup()
119 connect( mFormatComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsVectorLayerSaveAsDialog::mFormatComboBox_currentIndexChanged );
121 connect( mSymbologyExportComboBox, &QComboBox::currentTextChanged,
this, &QgsVectorLayerSaveAsDialog::mSymbologyExportComboBox_currentIndexChanged );
122 connect( mGeometryTypeComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsVectorLayerSaveAsDialog::mGeometryTypeComboBox_currentIndexChanged );
123 connect( mSelectAllAttributes, &QPushButton::clicked,
this, &QgsVectorLayerSaveAsDialog::mSelectAllAttributes_clicked );
124 connect( mDeselectAllAttributes, &QPushButton::clicked,
this, &QgsVectorLayerSaveAsDialog::mDeselectAllAttributes_clicked );
125 connect( mUseAliasesForExportedName, &QCheckBox::stateChanged,
this, &QgsVectorLayerSaveAsDialog::mUseAliasesForExportedName_stateChanged );
126 connect( mReplaceRawFieldValues, &QCheckBox::stateChanged,
this, &QgsVectorLayerSaveAsDialog::mReplaceRawFieldValues_stateChanged );
127 connect( mAttributeTable, &QTableWidget::itemChanged,
this, &QgsVectorLayerSaveAsDialog::mAttributeTable_itemChanged );
130 mHelpButtonBox->setVisible(
false );
131 mButtonBox->addButton( QDialogButtonBox::Help );
132 connect( mButtonBox, &QDialogButtonBox::helpRequested,
this, &QgsVectorLayerSaveAsDialog::showHelp );
134 connect( mHelpButtonBox, &QDialogButtonBox::helpRequested,
this, &QgsVectorLayerSaveAsDialog::showHelp );
137 connect( mButtonBox, &QDialogButtonBox::rejected,
this, &QgsVectorLayerSaveAsDialog::reject );
140 mFormatComboBox->blockSignals(
true );
143 mFormatComboBox->addItem( driver.longName, driver.driverName );
146 QgsSettings settings;
147 QString
format = settings.
value( QStringLiteral(
"UI/lastVectorFormat" ),
"GPKG" ).toString();
148 mFormatComboBox->setCurrentIndex( mFormatComboBox->findData(
format ) );
149 mFormatComboBox->blockSignals(
false );
156 mGeometryTypeComboBox->addItem( tr(
"Automatic" ), -1 );
162 mGeometryTypeComboBox->setCurrentIndex( mGeometryTypeComboBox->findData( -1 ) );
166 QString enc = settings.
value( QStringLiteral(
"UI/encoding" ),
"System" ).toString();
167 int idx = mEncodingComboBox->findText( enc );
170 mEncodingComboBox->insertItem( 0, enc );
174 mCrsSelector->setCrs( mSelectedCrs );
175 mCrsSelector->setLayerCrs( mSelectedCrs );
176 mCrsSelector->setMessage( tr(
"Select the coordinate reference system for the vector file. "
177 "The data points will be transformed from the layer coordinate reference system." ) );
179 mEncodingComboBox->setCurrentIndex( idx );
180 mFormatComboBox_currentIndexChanged( mFormatComboBox->currentIndex() );
186 mSymbologyExportComboBox_currentIndexChanged( mSymbologyExportComboBox->currentText() );
189 mExtentGroupBox->setOutputCrs( mSelectedCrs );
190 mExtentGroupBox->setOriginalExtent( mLayerExtent, mSelectedCrs );
191 mExtentGroupBox->setOutputExtentFromOriginal();
192 mExtentGroupBox->setCheckable(
true );
193 mExtentGroupBox->setChecked(
false );
194 mExtentGroupBox->setCollapsed(
true );
197 mFilename->setDialogTitle( tr(
"Save Layer As" ) );
198 mFilename->setDefaultRoot( settings.
value( QStringLiteral(
"UI/lastVectorFileFilterDir" ), QDir::homePath() ).toString() );
199 mFilename->setConfirmOverwrite(
false );
201 QgsSettings settings;
202 QFileInfo tmplFileInfo( filePath );
203 settings.
setValue( QStringLiteral(
"UI/lastVectorFileFilterDir" ), tmplFileInfo.absolutePath() );
205 const QFileInfo fileInfo( filePath );
207 if ( mDefaultOutputLayerNameFromInputLayerName.isEmpty() )
208 leLayername->setDefaultValue( suggestedLayerName );
211 if ( leLayername->text().isEmpty() && !filePath.isEmpty() && leLayername->isEnabled() )
213 leLayername->setText( suggestedLayerName );
215 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( !filePath.isEmpty() );
220 const QgsDatumEnsemble ensemble = mSelectedCrs.datumEnsemble();
223 mCrsSelector->setSourceEnsemble( ensemble.
name() );
226 catch ( QgsNotSupportedException & )
230 mCrsSelector->setShowAccuracyWarnings(
true );
233QList<QPair<QLabel *, QWidget *>> QgsVectorLayerSaveAsDialog::createControls(
const QMap<QString, QgsVectorFileWriter::Option *> &options )
235 QList<QPair<QLabel *, QWidget *>> controls;
236 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
238 for ( it = options.constBegin(); it != options.constEnd(); ++it )
240 QgsVectorFileWriter::Option *option = it.value();
241 QWidget *control =
nullptr;
242 switch ( option->
type )
246 QgsVectorFileWriter::IntOption *opt =
dynamic_cast<QgsVectorFileWriter::IntOption *
>( option );
249 QSpinBox *sb =
new QSpinBox();
250 sb->setObjectName( it.key() );
251 sb->setMaximum( std::numeric_limits<int>::max() );
260 QgsVectorFileWriter::SetOption *opt =
dynamic_cast<QgsVectorFileWriter::SetOption *
>( option );
263 QComboBox *cb =
new QComboBox();
264 cb->setObjectName( it.key() );
265 for (
const QString &val : std::as_const( opt->
values ) )
267 cb->addItem( val, val );
274 cb->setCurrentIndex( idx );
282 QgsVectorFileWriter::StringOption *opt =
dynamic_cast<QgsVectorFileWriter::StringOption *
>( option );
286 le->setObjectName( it.key() );
299 QLabel *label =
new QLabel( it.key() );
302 label->setToolTip( QStringLiteral(
"<p>%1</p>" ).arg( option->
docString.toHtmlEscaped() ) );
303 control->setToolTip( QStringLiteral(
"<p>%1</p>" ).arg( option->
docString.toHtmlEscaped() ) );
305 controls << QPair<QLabel *, QWidget *>( label, control );
314#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION( 3, 9, 0 )
315 if (
format() == QLatin1String(
"OpenFileGDB" ) )
319 bool targetAll =
true;
322 if ( layerOption == QLatin1String(
"TARGET_ARCGIS_VERSION=ARCGIS_PRO_3_2_OR_LATER" ) )
329 for (
int i = 0; i < mLayer->fields().size(); ++i )
331 QgsField fld = mLayer->fields().at( i );
332 if ( fld.
type() == QMetaType::Type::LongLong )
334 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 )
343 else if (
format() == QLatin1String(
"FileGDB" ) )
346 for (
int i = 0; i < mLayer->fields().size(); ++i )
348 QgsField fld = mLayer->fields().at( i );
349 if ( fld.
type() == QMetaType::Type::LongLong )
351 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 )
366 msgBox.setIcon( QMessageBox::Question );
367 msgBox.setWindowTitle( tr(
"Save Vector Layer As" ) );
368 QPushButton *overwriteFileButton = msgBox.addButton( tr(
"Overwrite File" ), QMessageBox::ActionRole );
369 QPushButton *overwriteLayerButton = msgBox.addButton( tr(
"Overwrite Layer" ), QMessageBox::ActionRole );
370 QPushButton *appendToLayerButton = msgBox.addButton( tr(
"Append to Layer" ), QMessageBox::ActionRole );
371 msgBox.setStandardButtons( QMessageBox::Cancel );
372 msgBox.setDefaultButton( QMessageBox::Cancel );
373 overwriteFileButton->hide();
374 overwriteLayerButton->hide();
375 appendToLayerButton->hide();
380 msgBox.setText( tr(
"The layer already exists. Do you want to overwrite the whole file or overwrite the layer?" ) );
381 overwriteFileButton->setVisible(
true );
382 overwriteLayerButton->setVisible(
true );
386 msgBox.setText( tr(
"The file already exists. Do you want to overwrite it?" ) );
387 overwriteFileButton->setVisible(
true );
391 msgBox.setText( tr(
"The layer already exists. Do you want to overwrite the whole file, overwrite the layer or append features to the layer?" ) );
392 appendToLayerButton->setVisible(
true );
393 overwriteFileButton->setVisible(
true );
394 overwriteLayerButton->setVisible(
true );
398 msgBox.setText( tr(
"The layer already exists. Do you want to overwrite the whole file or append features to the layer?" ) );
399 appendToLayerButton->setVisible(
true );
400 overwriteFileButton->setVisible(
true );
403 int ret = msgBox.exec();
404 if ( ret == QMessageBox::Cancel )
406 if ( msgBox.clickedButton() == overwriteFileButton )
408 else if ( msgBox.clickedButton() == overwriteLayerButton )
410 else if ( msgBox.clickedButton() == appendToLayerButton )
422 if ( QMessageBox::question(
this, tr(
"Save Vector Layer As" ), tr(
"The file already exists. Do you want to overwrite it?" ) ) != QMessageBox::Yes )
435 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 )
444 QStringList layerList;
445 layerList.reserve( sublayers.size() );
448 layerList.append( sublayer.name() );
450 if ( layerList.length() > 1 )
452 layerList.sort( Qt::CaseInsensitive );
454 msgBox.setIcon( QMessageBox::Warning );
455 msgBox.setWindowTitle( tr(
"Overwrite File" ) );
456 msgBox.setText( tr(
"This file contains %1 layers that will be lost!\n" ).arg( QLocale().toString( layerList.length() ) ) );
457 msgBox.setDetailedText( tr(
"The following layers will be permanently lost:\n\n%1" ).arg( layerList.join(
"\n" ) ) );
458 msgBox.setStandardButtons( QMessageBox::Ok | QMessageBox::Cancel );
459 if ( msgBox.exec() == QMessageBox::Cancel )
465 settings.
setValue( QStringLiteral(
"UI/lastVectorFileFilterDir" ), QFileInfo(
fileName() ).absolutePath() );
466 settings.
setValue( QStringLiteral(
"UI/lastVectorFormat" ),
format() );
471void QgsVectorLayerSaveAsDialog::mFormatComboBox_currentIndexChanged(
int idx )
475 mFilename->setEnabled(
true );
483 if (
format() == QLatin1String(
"OpenFileGDB" ) ||
format() == QLatin1String(
"FileGDB" ) )
484 filter = QStringLiteral(
"%1 (*.gdb *.GDB gdb)" ).arg( tr(
"ESRI File Geodatabase" ) );
485 mFilename->setFilter( filter );
489 if ( !mFilename->filePath().isEmpty() )
491 const thread_local QRegularExpression rx(
"\\.(.*?)[\\s]" );
492 const QString ext = rx.match( filter ).captured( 1 );
493 if ( !ext.isEmpty() )
495 QFileInfo fi( mFilename->filePath() );
496 mFilename->setFilePath( QStringLiteral(
"%1/%2.%3" ).arg( fi.path(), fi.baseName(), ext ) );
500 bool selectAllFields =
true;
505 bool isFormatForFieldsAsDisplayedValues =
false;
507 const QString sFormat(
format() );
508 if ( sFormat == QLatin1String(
"DXF" ) || sFormat == QLatin1String(
"DGN" ) )
510 mAttributesSelection->setVisible(
false );
511 selectAllFields =
false;
517 mAttributesSelection->setVisible(
true );
518 isFormatForFieldsAsDisplayedValues = ( sFormat == QLatin1String(
"CSV" ) || sFormat == QLatin1String(
"XLS" ) || sFormat == QLatin1String(
"XLSX" ) || sFormat == QLatin1String(
"ODS" ) );
525 mSymbologyExportLabel->setVisible(
true );
526 mSymbologyExportComboBox->setVisible(
true );
527 mScaleLabel->setVisible(
true );
528 mScaleWidget->setVisible(
true );
532 mSymbologyExportLabel->hide();
533 mSymbologyExportComboBox->hide();
535 mScaleWidget->hide();
538 leLayername->setEnabled( sFormat == QLatin1String(
"KML" ) || sFormat == QLatin1String(
"GPKG" ) || sFormat == QLatin1String(
"XLSX" ) || sFormat == QLatin1String(
"ODS" ) || sFormat == QLatin1String(
"FileGDB" ) || sFormat == QLatin1String(
"OpenFileGDB" ) || sFormat == QLatin1String(
"SQLite" ) || sFormat == QLatin1String(
"SpatiaLite" ) );
540 if ( sFormat == QLatin1String(
"XLSX" ) )
541 leLayername->setMaxLength( 31 );
542 else if ( leLayername->isEnabled() )
543 leLayername->setMaxLength( 32767 );
545 if ( !leLayername->isEnabled() )
546 leLayername->setText( QString() );
547 else if ( leLayername->text().isEmpty() )
549 QString
layerName = mDefaultOutputLayerNameFromInputLayerName;
550 if (
layerName.isEmpty() && !mFilename->filePath().isEmpty() )
552 layerName = QFileInfo( mFilename->filePath() ).baseName();
553 leLayername->setDefaultValue(
layerName );
562 mAttributeTable->setRowCount( mLayer->fields().count() );
564 QStringList horizontalHeaders = QStringList() << tr(
"Name" ) << tr(
"Export name" ) << tr(
"Type" ) << tr(
"Replace with displayed values" );
565 mAttributeTable->setColumnCount( horizontalHeaders.size() );
566 mAttributeTable->setHorizontalHeaderLabels( horizontalHeaders );
568 bool foundFieldThatCanBeExportedAsDisplayedValue =
false;
569 for (
int i = 0; i < mLayer->fields().size(); ++i )
574 foundFieldThatCanBeExportedAsDisplayedValue =
true;
578 mAttributeTable->setColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ), !foundFieldThatCanBeExportedAsDisplayedValue );
580 bool checkReplaceRawFieldValues = selectAllFields && isFormatForFieldsAsDisplayedValues;
581 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
583 for (
int i = 0; i < mLayer->fields().size(); ++i )
585 QgsField fld = mLayer->fields().at( i );
586 Qt::ItemFlags flags = mLayer->providerType() != QLatin1String(
"oracle" ) || !fld.
typeName().contains( QLatin1String(
"SDO_GEOMETRY" ) ) ? Qt::ItemIsEnabled : Qt::NoItemFlags;
587 QTableWidgetItem *item =
nullptr;
588 item =
new QTableWidgetItem( fld.
name() );
589 item->setFlags( flags | Qt::ItemIsUserCheckable );
590 item->setCheckState( ( selectAllFields ) ? Qt::Checked : Qt::Unchecked );
591 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::Name ), item );
593 item =
new QTableWidgetItem( fld.
name() );
594 item->setFlags( flags | Qt::ItemIsEditable );
596 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::ExportName ), item );
598 item =
new QTableWidgetItem( fld.
typeName() );
599 item->setFlags( flags );
600 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::Type ), item );
602 if ( foundFieldThatCanBeExportedAsDisplayedValue )
605 QgsEditorWidgetFactory *factory =
nullptr;
606 const QString widgetId( setup.type() );
607 if ( flags == Qt::ItemIsEnabled && widgetId != QLatin1String(
"TextEdit" ) && ( factory =
QgsGui::editorWidgetRegistry()->factory( widgetId ) ) )
609 item =
new QTableWidgetItem( tr(
"Use %1" ).arg( factory->
name() ) );
610 item->setFlags( ( selectAllFields ) ? ( Qt::ItemIsEnabled | Qt::ItemIsUserCheckable ) : Qt::ItemIsUserCheckable );
611 const bool checkItem = ( selectAllFields && isFormatForFieldsAsDisplayedValues && ( widgetId == QLatin1String(
"ValueMap" ) || widgetId == QLatin1String(
"ValueRelation" ) || widgetId == QLatin1String(
"CheckBox" ) || widgetId == QLatin1String(
"RelationReference" ) ) );
612 checkReplaceRawFieldValues &= checkItem;
613 item->setCheckState( checkItem ? Qt::Checked : Qt::Unchecked );
614 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ), item );
618 item =
new QTableWidgetItem();
619 item->setFlags( Qt::NoItemFlags );
620 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ), item );
626 whileBlocking( mReplaceRawFieldValues )->setChecked( checkReplaceRawFieldValues );
627 mReplaceRawFieldValues->setEnabled( selectAllFields );
628 mReplaceRawFieldValues->setVisible( foundFieldThatCanBeExportedAsDisplayedValue );
630 mAttributeTable->resizeColumnsToContents();
633 QgsVectorFileWriter::MetaData driverMetaData;
635 while ( mDatasourceOptionsGroupBox->layout()->count() )
637 QLayoutItem *item = mDatasourceOptionsGroupBox->layout()->takeAt( 0 );
638 delete item->widget();
642 while ( mLayerOptionsGroupBox->layout()->count() )
644 QLayoutItem *item = mLayerOptionsGroupBox->layout()->takeAt( 0 );
645 delete item->widget();
649 typedef QPair<QLabel *, QWidget *> LabelControlPair;
655 mDatasourceOptionsGroupBox->setVisible(
true );
656 QList<QPair<QLabel *, QWidget *>> controls = createControls( driverMetaData.
driverOptions );
658 QFormLayout *datasourceLayout =
dynamic_cast<QFormLayout *
>( mDatasourceOptionsGroupBox->layout() );
660 const auto constControls = controls;
661 for ( LabelControlPair control : constControls )
663 datasourceLayout->addRow( control.first, control.second );
668 mDatasourceOptionsGroupBox->setVisible(
false );
673 mLayerOptionsGroupBox->setVisible(
true );
674 QList<QPair<QLabel *, QWidget *>> controls = createControls( driverMetaData.
layerOptions );
676 QFormLayout *layerOptionsLayout =
dynamic_cast<QFormLayout *
>( mLayerOptionsGroupBox->layout() );
678 const auto constControls = controls;
679 for ( LabelControlPair control : constControls )
681 layerOptionsLayout->addRow( control.first, control.second );
686 mLayerOptionsGroupBox->setVisible(
false );
691 mEncodingComboBox->setEnabled(
true );
698 mEncodingComboBox->setCurrentIndex( idx );
699 mEncodingComboBox->setDisabled(
true );
703 mEncodingComboBox->setEnabled(
true );
709 mEncodingComboBox->setEnabled(
true );
712 GDALDriverH hDriver = GDALGetDriverByName(
format().toUtf8().constData() );
715 const bool canReopen = GDALGetMetadataItem( hDriver, GDAL_DCAP_OPEN,
nullptr );
716 if ( mAddToCanvas->isEnabled() && !canReopen )
718 mAddToCanvasStateOnOpenCompatibleDriver = mAddToCanvas->isChecked();
719 mAddToCanvas->setChecked(
false );
720 mAddToCanvas->setEnabled(
false );
722 else if ( !mAddToCanvas->isEnabled() && canReopen )
724 mAddToCanvas->setChecked( mAddToCanvasStateOnOpenCompatibleDriver );
725 mAddToCanvas->setEnabled(
true );
730void QgsVectorLayerSaveAsDialog::mUseAliasesForExportedName_stateChanged(
int state )
732 const QSignalBlocker signalBlocker( mAttributeTable );
739 bool modifiedEntries =
false;
740 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
742 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->text()
743 != mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->data( Qt::UserRole ).toString() )
745 modifiedEntries =
true;
750 if ( modifiedEntries )
752 if ( QMessageBox::question(
this, tr(
"Modified names" ), tr(
"Some names were modified and will be overridden. Do you want to continue?" ) )
755 whileBlocking( mUseAliasesForExportedName )->setCheckState( Qt::PartiallyChecked );
760 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
762 mUseAliasesForExportedName->setTristate(
false );
763 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->setText( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->text() );
770 bool modifiedEntries =
false;
771 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
773 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->text()
774 != mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->text() )
775 modifiedEntries =
true;
778 if ( modifiedEntries )
780 if ( QMessageBox::question(
this, tr(
"Modified names" ), tr(
"Some names were modified and will be overridden. Do you want to continue?" ) )
783 whileBlocking( mUseAliasesForExportedName )->setCheckState( Qt::PartiallyChecked );
788 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
790 mUseAliasesForExportedName->setTristate(
false );
791 const QString alias = mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->data( Qt::UserRole ).toString();
792 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->setText( alias );
796 case Qt::PartiallyChecked:
802void QgsVectorLayerSaveAsDialog::mReplaceRawFieldValues_stateChanged(
int )
804 if ( mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
807 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
808 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
810 if ( mReplaceRawFieldValues->checkState() != Qt::PartiallyChecked )
812 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
814 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 )
816 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( mReplaceRawFieldValues->checkState() );
820 mReplaceRawFieldValues->setTristate(
false );
823void QgsVectorLayerSaveAsDialog::mAttributeTable_itemChanged( QTableWidgetItem *item )
825 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
826 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
828 int row = item->row();
829 int column = item->column();
831 switch (
static_cast<ColumnIndex
>( column ) )
833 case ColumnIndex::Name:
835 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 ) )
838 if ( mAttributeTable->item( row, column )->checkState() == Qt::Unchecked )
840 mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( Qt::Unchecked );
841 mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable );
842 bool checkBoxEnabled =
false;
843 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
845 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) && mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsEnabled )
847 checkBoxEnabled =
true;
851 mReplaceRawFieldValues->setEnabled( checkBoxEnabled );
852 if ( !checkBoxEnabled )
853 mReplaceRawFieldValues->setCheckState( Qt::Unchecked );
855 else if ( mAttributeTable->item( row, column )->checkState() == Qt::Checked )
857 mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsEnabled );
858 mReplaceRawFieldValues->setEnabled(
true );
862 case ColumnIndex::ExportName:
865 if ( item->text().isEmpty() )
867 QMessageBox::warning(
this, tr(
"Empty export name" ), tr(
"Empty export name are not allowed." ) );
873 while ( names.count( item->text() ) > 1 )
874 item->setText( QString(
"%1_2" ).arg( item->text() ) );
876 mUseAliasesForExportedName->setCheckState( Qt::PartiallyChecked );
879 case ColumnIndex::Type:
882 case ColumnIndex::ExportAsDisplayedValue:
884 if ( mAttributeTable->item( row, column )->flags() & Qt::ItemIsUserCheckable )
886 bool allChecked =
true;
887 bool allUnchecked =
true;
888 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
890 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) && mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsEnabled )
892 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->checkState() == Qt::Unchecked )
895 allUnchecked =
false;
898 mReplaceRawFieldValues->setCheckState( ( !allChecked && !allUnchecked ) ? Qt::PartiallyChecked : ( allChecked ) ? Qt::Checked
909 mExtentGroupBox->setOutputCrs( mSelectedCrs );
914 return mFilename->filePath();
919 return leLayername->text();
924 return mEncodingComboBox->currentText();
929 return mFormatComboBox->currentData().toString();
945 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
949 switch ( it.value()->type )
954 QSpinBox *sb = mDatasourceOptionsGroupBox->findChild<QSpinBox *>( it.key() );
956 options << QStringLiteral(
"%1=%2" ).arg( it.key() ).arg( sb->value() );
963 QComboBox *cb = mDatasourceOptionsGroupBox->findChild<QComboBox *>( it.key() );
964 if ( opt && cb && cb->itemData( cb->currentIndex() ) != opt->
defaultValue )
965 options << QStringLiteral(
"%1=%2" ).arg( it.key(), cb->currentText() );
972 QLineEdit *le = mDatasourceOptionsGroupBox->findChild<QLineEdit *>( it.key() );
974 options << QStringLiteral(
"%1=%2" ).arg( it.key(), le->text() );
981 if ( opt && !opt->
mValue.isEmpty() )
982 options << QStringLiteral(
"%1=%2" ).arg( it.key(), opt->
mValue );
989 QString plainText = mOgrDatasourceOptions->toPlainText().trimmed();
990 if ( !plainText.isEmpty() )
991 options += plainText.split(
'\n' );
1004 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
1008 switch ( it.value()->type )
1013 QSpinBox *sb = mLayerOptionsGroupBox->findChild<QSpinBox *>( it.key() );
1015 options << QStringLiteral(
"%1=%2" ).arg( it.key() ).arg( sb->value() );
1022 QComboBox *cb = mLayerOptionsGroupBox->findChild<QComboBox *>( it.key() );
1023 if ( opt && cb && cb->itemData( cb->currentIndex() ) != opt->
defaultValue )
1024 options << QStringLiteral(
"%1=%2" ).arg( it.key(), cb->currentText() );
1031 QLineEdit *le = mLayerOptionsGroupBox->findChild<QLineEdit *>( it.key() );
1033 options << QStringLiteral(
"%1=%2" ).arg( it.key(), le->text() );
1040 if ( !opt->
mValue.isEmpty() )
1041 options << QStringLiteral(
"%1=%2" ).arg( it.key(), opt->
mValue );
1048 QString plainText = mOgrLayerOptions->toPlainText().trimmed();
1049 if ( !plainText.isEmpty() )
1050 options += plainText.split(
'\n' );
1059 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1061 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->checkState() == Qt::Checked )
1063 attributes.append( i );
1074 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1076 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 )
1078 attributes.append( i );
1087 QStringList exportNames;
1088 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1089 exportNames.append( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->text() );
1096 return mAddToCanvas->isChecked();
1101 mAddToCanvasStateOnOpenCompatibleDriver = enabled;
1102 if ( mAddToCanvas->isEnabled() )
1103 mAddToCanvas->setChecked( enabled );
1113 return mScaleWidget->scale();
1118 mMapCanvas = canvas;
1119 mScaleWidget->setMapCanvas( canvas );
1120 mScaleWidget->setShowCurrentScaleButton(
true );
1126 return mExtentGroupBox->isChecked();
1131 return mExtentGroupBox->outputExtent();
1141 return mSelectedOnly->isChecked();
1146 return mCheckPersistMetadata->isChecked();
1151 int currentIndexData = mGeometryTypeComboBox->currentData().toInt();
1152 if ( currentIndexData == -1 )
1163 int currentIndexData = mGeometryTypeComboBox->currentData().toInt();
1164 return currentIndexData == -1;
1169 return mForceMultiCheckBox->isChecked();
1174 mForceMultiCheckBox->setChecked( checked );
1179 return mIncludeZCheckBox->isChecked();
1184 return mActionOnExistingFile;
1189 mIncludeZCheckBox->setChecked( checked );
1192void QgsVectorLayerSaveAsDialog::mSymbologyExportComboBox_currentIndexChanged(
const QString &text )
1194 bool scaleEnabled =
true;
1195 if ( text == tr(
"No symbology" ) )
1197 scaleEnabled =
false;
1199 mScaleWidget->setEnabled( scaleEnabled );
1200 mScaleLabel->setEnabled( scaleEnabled );
1203void QgsVectorLayerSaveAsDialog::mGeometryTypeComboBox_currentIndexChanged(
int )
1205 const int currentIndexData = mGeometryTypeComboBox->currentData().toInt();
1208 mForceMultiCheckBox->setEnabled(
true );
1209 mIncludeZCheckBox->setEnabled(
true );
1215 mForceMultiCheckBox->setEnabled(
false );
1216 mForceMultiCheckBox->setChecked(
false );
1220 mForceMultiCheckBox->setEnabled(
true );
1222 mIncludeZCheckBox->setEnabled(
false );
1223 mIncludeZCheckBox->setChecked(
false );
1227void QgsVectorLayerSaveAsDialog::mSelectAllAttributes_clicked()
1229 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
1230 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
1232 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1234 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->flags() & Qt::ItemIsEnabled )
1236 if ( !mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) && ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsUserCheckable ) )
1238 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsEnabled );
1240 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->setCheckState( Qt::Checked );
1243 if ( !mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
1245 mReplaceRawFieldValues->setEnabled(
true );
1249void QgsVectorLayerSaveAsDialog::mDeselectAllAttributes_clicked()
1251 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
1252 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
1254 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1256 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->setCheckState( Qt::Unchecked );
1257 if ( !mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) && ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsUserCheckable ) )
1259 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable );
1260 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( Qt::Unchecked );
1263 if ( !mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
1265 mReplaceRawFieldValues->setCheckState( Qt::Unchecked );
1266 mReplaceRawFieldValues->setEnabled(
false );
1270void QgsVectorLayerSaveAsDialog::showHelp()
1272 QgsHelp::openHelp( QStringLiteral(
"managing_data_source/create_layers.html#creating-new-layers-from-an-existing-layer" ) );
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.