33#include <QRegularExpression>
42 : QDialog( parent, fl )
50 : QDialog( parent, fl )
57 mSelectedCrs = layer->
crs();
58 mLayerExtent = layer->
extent();
65 leLayername->setDefaultValue( mDefaultOutputLayerNameFromInputLayerName );
67 if ( leLayername->isEnabled() )
68 leLayername->setText( mDefaultOutputLayerNameFromInputLayerName );
73 mSymbologyExportLabel->hide();
74 mSymbologyExportComboBox->hide();
85 mAttributesSelection->hide();
88 mSelectedOnly->hide();
94 mGeometryGroupBox->hide();
97 mExtentGroupBox->hide();
101 mCheckPersistMetadata->setChecked(
false );
102 mCheckPersistMetadata->hide();
106 mButtonBox->button( QDialogButtonBox::Ok )->setDisabled(
true );
109void QgsVectorLayerSaveAsDialog::setup()
114 connect( mFormatComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsVectorLayerSaveAsDialog::mFormatComboBox_currentIndexChanged );
116 connect( mSymbologyExportComboBox, &QComboBox::currentTextChanged,
this, &QgsVectorLayerSaveAsDialog::mSymbologyExportComboBox_currentIndexChanged );
117 connect( mGeometryTypeComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsVectorLayerSaveAsDialog::mGeometryTypeComboBox_currentIndexChanged );
118 connect( mSelectAllAttributes, &QPushButton::clicked,
this, &QgsVectorLayerSaveAsDialog::mSelectAllAttributes_clicked );
119 connect( mDeselectAllAttributes, &QPushButton::clicked,
this, &QgsVectorLayerSaveAsDialog::mDeselectAllAttributes_clicked );
120 connect( mUseAliasesForExportedName, &QCheckBox::stateChanged,
this, &QgsVectorLayerSaveAsDialog::mUseAliasesForExportedName_stateChanged );
121 connect( mReplaceRawFieldValues, &QCheckBox::stateChanged,
this, &QgsVectorLayerSaveAsDialog::mReplaceRawFieldValues_stateChanged );
122 connect( mAttributeTable, &QTableWidget::itemChanged,
this, &QgsVectorLayerSaveAsDialog::mAttributeTable_itemChanged );
125 mHelpButtonBox->setVisible(
false );
126 mButtonBox->addButton( QDialogButtonBox::Help );
127 connect( mButtonBox, &QDialogButtonBox::helpRequested,
this, &QgsVectorLayerSaveAsDialog::showHelp );
129 connect( mHelpButtonBox, &QDialogButtonBox::helpRequested,
this, &QgsVectorLayerSaveAsDialog::showHelp );
132 connect( mButtonBox, &QDialogButtonBox::rejected,
this, &QgsVectorLayerSaveAsDialog::reject );
135 mFormatComboBox->blockSignals(
true );
138 mFormatComboBox->addItem( driver.longName, driver.driverName );
142 QString
format = settings.
value( QStringLiteral(
"UI/lastVectorFormat" ),
"GPKG" ).toString();
143 mFormatComboBox->setCurrentIndex( mFormatComboBox->findData(
format ) );
144 mFormatComboBox->blockSignals(
false );
152 mGeometryTypeComboBox->addItem( tr(
"Automatic" ), -1 );
158 mGeometryTypeComboBox->setCurrentIndex( mGeometryTypeComboBox->findData( -1 ) );
162 QString enc = settings.
value( QStringLiteral(
"UI/encoding" ),
"System" ).toString();
163 int idx = mEncodingComboBox->findText( enc );
166 mEncodingComboBox->insertItem( 0, enc );
170 mCrsSelector->setCrs( mSelectedCrs );
171 mCrsSelector->setLayerCrs( mSelectedCrs );
172 mCrsSelector->setMessage( tr(
"Select the coordinate reference system for the vector file. "
173 "The data points will be transformed from the layer coordinate reference system." ) );
175 mEncodingComboBox->setCurrentIndex( idx );
176 mFormatComboBox_currentIndexChanged( mFormatComboBox->currentIndex() );
182 mSymbologyExportComboBox_currentIndexChanged( mSymbologyExportComboBox->currentText() );
185 mExtentGroupBox->setOutputCrs( mSelectedCrs );
186 mExtentGroupBox->setOriginalExtent( mLayerExtent, mSelectedCrs );
187 mExtentGroupBox->setOutputExtentFromOriginal();
188 mExtentGroupBox->setCheckable(
true );
189 mExtentGroupBox->setChecked(
false );
190 mExtentGroupBox->setCollapsed(
true );
193 mFilename->setDialogTitle( tr(
"Save Layer As" ) );
194 mFilename->setDefaultRoot( settings.
value( QStringLiteral(
"UI/lastVectorFileFilterDir" ), QDir::homePath() ).toString() );
195 mFilename->setConfirmOverwrite(
false );
199 QFileInfo tmplFileInfo( filePath );
200 settings.
setValue( QStringLiteral(
"UI/lastVectorFileFilterDir" ), tmplFileInfo.absolutePath() );
202 const QFileInfo fileInfo( filePath );
204 if ( mDefaultOutputLayerNameFromInputLayerName.isEmpty() )
205 leLayername->setDefaultValue( suggestedLayerName );
208 if ( leLayername->text().isEmpty() && !filePath.isEmpty() && leLayername->isEnabled() )
210 leLayername->setText( suggestedLayerName );
212 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( !filePath.isEmpty() );
220 mCrsSelector->setSourceEnsemble( ensemble.
name() );
227 mCrsSelector->setShowAccuracyWarnings(
true );
230QList<QPair<QLabel *, QWidget *> > QgsVectorLayerSaveAsDialog::createControls(
const QMap<QString, QgsVectorFileWriter::Option *> &options )
232 QList<QPair<QLabel *, QWidget *> > controls;
233 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
235 for ( it = options.constBegin(); it != options.constEnd(); ++it )
238 QWidget *control =
nullptr;
239 switch ( option->
type )
246 QSpinBox *sb =
new QSpinBox();
247 sb->setObjectName( it.key() );
248 sb->setMaximum( std::numeric_limits<int>::max() );
260 QComboBox *cb =
new QComboBox();
261 cb->setObjectName( it.key() );
262 for (
const QString &val : std::as_const( opt->values ) )
264 cb->addItem( val, val );
271 cb->setCurrentIndex( idx );
283 le->setObjectName( it.key() );
296 QLabel *label =
new QLabel( it.key() );
299 label->setToolTip( QStringLiteral(
"<p>%1</p>" ).arg( option->
docString.toHtmlEscaped() ) );
300 control->setToolTip( QStringLiteral(
"<p>%1</p>" ).arg( option->
docString.toHtmlEscaped() ) );
302 controls << QPair<QLabel *, QWidget *>( label, control );
311#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3,9,0)
312 if (
format() == QLatin1String(
"OpenFileGDB" ) )
316 bool targetAll =
true;
319 if ( layerOption == QLatin1String(
"TARGET_ARCGIS_VERSION=ARCGIS_PRO_3_2_OR_LATER" ) )
326 for (
int i = 0; i < mLayer->
fields().
size(); ++i )
329 if ( fld.
type() == QMetaType::Type::LongLong )
331 if ( QMessageBox::question(
this,
332 tr(
"Save Vector Layer As" ),
333 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 )
342 else if (
format() == QLatin1String(
"FileGDB" ) )
345 for (
int i = 0; i < mLayer->
fields().
size(); ++i )
348 if ( fld.
type() == QMetaType::Type::LongLong )
350 if ( QMessageBox::question(
this,
351 tr(
"Save Vector Layer As" ),
352 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();
385 msgBox.setText( tr(
"The layer already exists. Do you want to overwrite the whole file or overwrite the layer?" ) );
386 overwriteFileButton->setVisible(
true );
387 overwriteLayerButton->setVisible(
true );
391 msgBox.setText( tr(
"The file already exists. Do you want to overwrite it?" ) );
392 overwriteFileButton->setVisible(
true );
397 msgBox.setText( tr(
"The layer already exists. Do you want to overwrite the whole file, overwrite the layer or append features to the layer?" ) );
398 appendToLayerButton->setVisible(
true );
399 overwriteFileButton->setVisible(
true );
400 overwriteLayerButton->setVisible(
true );
404 msgBox.setText( tr(
"The layer already exists. Do you want to overwrite the whole file or append features to the layer?" ) );
405 appendToLayerButton->setVisible(
true );
406 overwriteFileButton->setVisible(
true );
409 int ret = msgBox.exec();
410 if ( ret == QMessageBox::Cancel )
412 if ( msgBox.clickedButton() == overwriteFileButton )
414 else if ( msgBox.clickedButton() == overwriteLayerButton )
416 else if ( msgBox.clickedButton() == appendToLayerButton )
428 if ( QMessageBox::question(
this,
429 tr(
"Save Vector Layer As" ),
430 tr(
"The file already exists. Do you want to overwrite it?" ) ) != QMessageBox::Yes )
443 if ( QMessageBox::question(
this,
444 tr(
"Save Vector Layer As" ),
445 tr(
"The existing layer has additional fields. Do you want to add the missing fields to the layer?" ) ) == QMessageBox::Yes )
454 QStringList layerList;
455 layerList.reserve( sublayers.size() );
458 layerList.append( sublayer.name() );
460 if ( layerList.length() > 1 )
462 layerList.sort( Qt::CaseInsensitive );
464 msgBox.setIcon( QMessageBox::Warning );
465 msgBox.setWindowTitle( tr(
"Overwrite File" ) );
466 msgBox.setText( tr(
"This file contains %1 layers that will be lost!\n" ).arg( QLocale().toString( layerList.length() ) ) );
467 msgBox.setDetailedText( tr(
"The following layers will be permanently lost:\n\n%1" ).arg( layerList.join(
"\n" ) ) );
468 msgBox.setStandardButtons( QMessageBox::Ok | QMessageBox::Cancel );
469 if ( msgBox.exec() == QMessageBox::Cancel )
475 settings.
setValue( QStringLiteral(
"UI/lastVectorFileFilterDir" ), QFileInfo(
fileName() ).absolutePath() );
476 settings.
setValue( QStringLiteral(
"UI/lastVectorFormat" ),
format() );
481void QgsVectorLayerSaveAsDialog::mFormatComboBox_currentIndexChanged(
int idx )
485 mFilename->setEnabled(
true );
493 if (
format() == QLatin1String(
"OpenFileGDB" ) ||
format() == QLatin1String(
"FileGDB" ) )
494 filter = QStringLiteral(
"%1 (*.gdb *.GDB gdb)" ).arg( tr(
"ESRI File Geodatabase" ) );
495 mFilename->setFilter( filter );
499 if ( !mFilename->filePath().isEmpty() )
501 const thread_local QRegularExpression rx(
"\\.(.*?)[\\s]" );
502 const QString ext = rx.match( filter ).captured( 1 );
503 if ( !ext.isEmpty() )
505 QFileInfo fi( mFilename->filePath() );
506 mFilename->setFilePath( QStringLiteral(
"%1/%2.%3" ).arg( fi.path(), fi.baseName(), ext ) );
510 bool selectAllFields =
true;
515 bool isFormatForFieldsAsDisplayedValues =
false;
517 const QString sFormat(
format() );
518 if ( sFormat == QLatin1String(
"DXF" ) || sFormat == QLatin1String(
"DGN" ) )
520 mAttributesSelection->setVisible(
false );
521 selectAllFields =
false;
527 mAttributesSelection->setVisible(
true );
528 isFormatForFieldsAsDisplayedValues = ( sFormat == QLatin1String(
"CSV" ) ||
529 sFormat == QLatin1String(
"XLS" ) ||
530 sFormat == QLatin1String(
"XLSX" ) ||
531 sFormat == QLatin1String(
"ODS" ) );
538 mSymbologyExportLabel->setVisible(
true );
539 mSymbologyExportComboBox->setVisible(
true );
540 mScaleLabel->setVisible(
true );
541 mScaleWidget->setVisible(
true );
545 mSymbologyExportLabel->hide();
546 mSymbologyExportComboBox->hide();
548 mScaleWidget->hide();
551 leLayername->setEnabled( sFormat == QLatin1String(
"KML" ) ||
552 sFormat == QLatin1String(
"GPKG" ) ||
553 sFormat == QLatin1String(
"XLSX" ) ||
554 sFormat == QLatin1String(
"ODS" ) ||
555 sFormat == QLatin1String(
"FileGDB" ) ||
556 sFormat == QLatin1String(
"OpenFileGDB" ) ||
557 sFormat == QLatin1String(
"SQLite" ) ||
558 sFormat == QLatin1String(
"SpatiaLite" ) );
560 if ( sFormat == QLatin1String(
"XLSX" ) )
561 leLayername->setMaxLength( 31 );
562 else if ( leLayername->isEnabled() )
563 leLayername->setMaxLength( 32767 );
565 if ( !leLayername->isEnabled() )
566 leLayername->setText( QString() );
567 else if ( leLayername->text().isEmpty() )
569 QString
layerName = mDefaultOutputLayerNameFromInputLayerName;
570 if (
layerName.isEmpty() && !mFilename->filePath().isEmpty() )
572 layerName = QFileInfo( mFilename->filePath() ).baseName();
573 leLayername->setDefaultValue(
layerName );
582 mAttributeTable->setRowCount( mLayer->
fields().
count() );
584 QStringList horizontalHeaders = QStringList() << tr(
"Name" ) << tr(
"Export name" ) << tr(
"Type" ) << tr(
"Replace with displayed values" );
585 mAttributeTable->setColumnCount( horizontalHeaders.size() );
586 mAttributeTable->setHorizontalHeaderLabels( horizontalHeaders );
588 bool foundFieldThatCanBeExportedAsDisplayedValue =
false;
589 for (
int i = 0; i < mLayer->
fields().size(); ++i )
592 if ( setup.
type() != QLatin1String(
"TextEdit" ) &&
595 foundFieldThatCanBeExportedAsDisplayedValue =
true;
599 mAttributeTable->setColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ),
600 ! foundFieldThatCanBeExportedAsDisplayedValue );
602 bool checkReplaceRawFieldValues = selectAllFields && isFormatForFieldsAsDisplayedValues;
603 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
605 for (
int i = 0; i < mLayer->
fields().size(); ++i )
608 Qt::ItemFlags flags = mLayer->
providerType() != QLatin1String(
"oracle" ) || !fld.
typeName().contains( QLatin1String(
"SDO_GEOMETRY" ) ) ? Qt::ItemIsEnabled : Qt::NoItemFlags;
609 QTableWidgetItem *item =
nullptr;
610 item =
new QTableWidgetItem( fld.
name() );
611 item->setFlags( flags | Qt::ItemIsUserCheckable );
612 item->setCheckState( ( selectAllFields ) ? Qt::Checked : Qt::Unchecked );
613 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::Name ), item );
615 item =
new QTableWidgetItem( fld.
name() );
616 item->setFlags( flags | Qt::ItemIsEditable );
618 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::ExportName ), item );
620 item =
new QTableWidgetItem( fld.
typeName() );
621 item->setFlags( flags );
622 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::Type ), item );
624 if ( foundFieldThatCanBeExportedAsDisplayedValue )
628 const QString widgetId( setup.
type() );
629 if ( flags == Qt::ItemIsEnabled &&
630 widgetId != QLatin1String(
"TextEdit" ) &&
633 item =
new QTableWidgetItem( tr(
"Use %1" ).arg( factory->
name() ) );
634 item->setFlags( ( selectAllFields ) ? ( Qt::ItemIsEnabled | Qt::ItemIsUserCheckable ) : Qt::ItemIsUserCheckable );
635 const bool checkItem = ( selectAllFields && isFormatForFieldsAsDisplayedValues &&
636 ( widgetId == QLatin1String(
"ValueMap" ) ||
637 widgetId == QLatin1String(
"ValueRelation" ) ||
638 widgetId == QLatin1String(
"CheckBox" ) ||
639 widgetId == QLatin1String(
"RelationReference" ) ) );
640 checkReplaceRawFieldValues &= checkItem;
641 item->setCheckState( checkItem ?
642 Qt::Checked : Qt::Unchecked );
643 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ), item );
647 item =
new QTableWidgetItem();
648 item->setFlags( Qt::NoItemFlags );
649 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ), item );
655 whileBlocking( mReplaceRawFieldValues )->setChecked( checkReplaceRawFieldValues );
656 mReplaceRawFieldValues->setEnabled( selectAllFields );
657 mReplaceRawFieldValues->setVisible( foundFieldThatCanBeExportedAsDisplayedValue );
659 mAttributeTable->resizeColumnsToContents();
664 while ( mDatasourceOptionsGroupBox->layout()->count() )
666 QLayoutItem *item = mDatasourceOptionsGroupBox->layout()->takeAt( 0 );
667 delete item->widget();
671 while ( mLayerOptionsGroupBox->layout()->count() )
673 QLayoutItem *item = mLayerOptionsGroupBox->layout()->takeAt( 0 );
674 delete item->widget();
678 typedef QPair<QLabel *, QWidget *> LabelControlPair;
684 mDatasourceOptionsGroupBox->setVisible(
true );
685 QList<QPair<QLabel *, QWidget *> > controls = createControls( driverMetaData.
driverOptions );
687 QFormLayout *datasourceLayout =
dynamic_cast<QFormLayout *
>( mDatasourceOptionsGroupBox->layout() );
689 const auto constControls = controls;
690 for ( LabelControlPair control : constControls )
692 datasourceLayout->addRow( control.first, control.second );
697 mDatasourceOptionsGroupBox->setVisible(
false );
702 mLayerOptionsGroupBox->setVisible(
true );
703 QList<QPair<QLabel *, QWidget *> > controls = createControls( driverMetaData.
layerOptions );
705 QFormLayout *layerOptionsLayout =
dynamic_cast<QFormLayout *
>( mLayerOptionsGroupBox->layout() );
707 const auto constControls = controls;
708 for ( LabelControlPair control : constControls )
710 layerOptionsLayout->addRow( control.first, control.second );
715 mLayerOptionsGroupBox->setVisible(
false );
720 mEncodingComboBox->setEnabled(
true );
727 mEncodingComboBox->setCurrentIndex( idx );
728 mEncodingComboBox->setDisabled(
true );
732 mEncodingComboBox->setEnabled(
true );
739 mEncodingComboBox->setEnabled(
true );
742 GDALDriverH hDriver = GDALGetDriverByName(
format().toUtf8().constData() );
745 const bool canReopen = GDALGetMetadataItem( hDriver, GDAL_DCAP_OPEN,
nullptr );
746 if ( mAddToCanvas->isEnabled() && !canReopen )
748 mAddToCanvasStateOnOpenCompatibleDriver = mAddToCanvas->isChecked();
749 mAddToCanvas->setChecked(
false );
750 mAddToCanvas->setEnabled(
false );
752 else if ( !mAddToCanvas->isEnabled() && canReopen )
754 mAddToCanvas->setChecked( mAddToCanvasStateOnOpenCompatibleDriver );
755 mAddToCanvas->setEnabled(
true );
760void QgsVectorLayerSaveAsDialog::mUseAliasesForExportedName_stateChanged(
int state )
762 const QSignalBlocker signalBlocker( mAttributeTable );
769 bool modifiedEntries =
false;
770 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
772 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->text()
773 != mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->data( Qt::UserRole ).toString() )
775 modifiedEntries =
true;
780 if ( modifiedEntries )
782 if ( QMessageBox::question(
this,
783 tr(
"Modified names" ),
784 tr(
"Some names were modified and will be overridden. Do you want to continue?" ) )
787 whileBlocking( mUseAliasesForExportedName )->setCheckState( Qt::PartiallyChecked );
792 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
794 mUseAliasesForExportedName->setTristate(
false );
795 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->setText( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->text() );
802 bool modifiedEntries =
false;
803 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
805 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->text()
806 != mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->text() )
807 modifiedEntries =
true;
810 if ( modifiedEntries )
812 if ( QMessageBox::question(
this,
813 tr(
"Modified names" ),
814 tr(
"Some names were modified and will be overridden. Do you want to continue?" ) )
817 whileBlocking( mUseAliasesForExportedName )->setCheckState( Qt::PartiallyChecked );
822 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
824 mUseAliasesForExportedName->setTristate(
false );
825 const QString alias = mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->data( Qt::UserRole ).toString();
826 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->setText( alias );
830 case Qt::PartiallyChecked:
836void QgsVectorLayerSaveAsDialog::mReplaceRawFieldValues_stateChanged(
int )
838 if ( mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
841 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
842 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
844 if ( mReplaceRawFieldValues->checkState() != Qt::PartiallyChecked )
846 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
848 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->checkState() == Qt::Checked &&
849 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
850 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsEnabled )
852 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( mReplaceRawFieldValues->checkState() );
856 mReplaceRawFieldValues->setTristate(
false );
859void QgsVectorLayerSaveAsDialog::mAttributeTable_itemChanged( QTableWidgetItem *item )
861 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
862 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
864 int row = item->row();
865 int column = item->column();
867 switch (
static_cast<ColumnIndex
>( column ) )
869 case ColumnIndex::Name:
871 if ( mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) ||
872 ! mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) ||
873 !( mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsUserCheckable ) )
876 if ( mAttributeTable->item( row, column )->checkState() == Qt::Unchecked )
878 mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( Qt::Unchecked );
879 mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable );
880 bool checkBoxEnabled =
false;
881 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
883 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
884 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsEnabled )
886 checkBoxEnabled =
true;
890 mReplaceRawFieldValues->setEnabled( checkBoxEnabled );
891 if ( !checkBoxEnabled )
892 mReplaceRawFieldValues->setCheckState( Qt::Unchecked );
894 else if ( mAttributeTable->item( row, column )->checkState() == Qt::Checked )
896 mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsEnabled );
897 mReplaceRawFieldValues->setEnabled(
true );
901 case ColumnIndex::ExportName:
904 if ( item->text().isEmpty() )
906 QMessageBox::warning(
this,
907 tr(
"Empty export name" ),
908 tr(
"Empty export name are not allowed." ) );
914 while ( names.count( item->text() ) > 1 )
915 item->setText( QString(
"%1_2" ).arg( item->text() ) );
917 mUseAliasesForExportedName->setCheckState( Qt::PartiallyChecked );
920 case ColumnIndex::Type:
923 case ColumnIndex::ExportAsDisplayedValue:
925 if ( mAttributeTable->item( row, column )->flags() & Qt::ItemIsUserCheckable )
927 bool allChecked =
true;
928 bool allUnchecked =
true;
929 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
931 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
932 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsEnabled )
934 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->checkState() == Qt::Unchecked )
937 allUnchecked =
false;
940 mReplaceRawFieldValues->setCheckState( ( !allChecked && !allUnchecked ) ? Qt::PartiallyChecked : ( allChecked ) ? Qt::Checked : Qt::Unchecked );
950 mExtentGroupBox->setOutputCrs( mSelectedCrs );
955 return mFilename->filePath();
960 return leLayername->text();
965 return mEncodingComboBox->currentText();
970 return mFormatComboBox->currentData().toString();
986 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
990 switch ( it.value()->type )
995 QSpinBox *sb = mDatasourceOptionsGroupBox->findChild<QSpinBox *>( it.key() );
997 options << QStringLiteral(
"%1=%2" ).arg( it.key() ).arg( sb->value() );
1004 QComboBox *cb = mDatasourceOptionsGroupBox->findChild<QComboBox *>( it.key() );
1005 if ( opt && cb && cb->itemData( cb->currentIndex() ) != opt->
defaultValue )
1006 options << QStringLiteral(
"%1=%2" ).arg( it.key(), cb->currentText() );
1013 QLineEdit *le = mDatasourceOptionsGroupBox->findChild<QLineEdit *>( it.key() );
1015 options << QStringLiteral(
"%1=%2" ).arg( it.key(), le->text() );
1023 if ( !opt->
mValue.isEmpty() )
1024 options << QStringLiteral(
"%1=%2" ).arg( it.key(), opt->
mValue );
1031 QString plainText = mOgrDatasourceOptions->toPlainText().trimmed();
1032 if ( !plainText.isEmpty() )
1033 options += plainText.split(
'\n' );
1040 QStringList options;
1046 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
1050 switch ( it.value()->type )
1055 QSpinBox *sb = mLayerOptionsGroupBox->findChild<QSpinBox *>( it.key() );
1057 options << QStringLiteral(
"%1=%2" ).arg( it.key() ).arg( sb->value() );
1064 QComboBox *cb = mLayerOptionsGroupBox->findChild<QComboBox *>( it.key() );
1065 if ( opt && cb && cb->itemData( cb->currentIndex() ) != opt->
defaultValue )
1066 options << QStringLiteral(
"%1=%2" ).arg( it.key(), cb->currentText() );
1073 QLineEdit *le = mLayerOptionsGroupBox->findChild<QLineEdit *>( it.key() );
1075 options << QStringLiteral(
"%1=%2" ).arg( it.key(), le->text() );
1083 if ( !opt->
mValue.isEmpty() )
1084 options << QStringLiteral(
"%1=%2" ).arg( it.key(), opt->
mValue );
1091 QString plainText = mOgrLayerOptions->toPlainText().trimmed();
1092 if ( !plainText.isEmpty() )
1093 options += plainText.split(
'\n' );
1102 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1104 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->checkState() == Qt::Checked )
1106 attributes.append( i );
1117 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1119 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->checkState() == Qt::Checked &&
1120 ! mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
1121 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->checkState() == Qt::Checked )
1123 attributes.append( i );
1132 QStringList exportNames;
1133 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1134 exportNames.append( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->text() );
1141 return mAddToCanvas->isChecked();
1146 mAddToCanvasStateOnOpenCompatibleDriver = enabled;
1147 if ( mAddToCanvas->isEnabled() )
1148 mAddToCanvas->setChecked( enabled );
1158 return mScaleWidget->scale();
1163 mMapCanvas = canvas;
1164 mScaleWidget->setMapCanvas( canvas );
1165 mScaleWidget->setShowCurrentScaleButton(
true );
1171 return mExtentGroupBox->isChecked();
1176 return mExtentGroupBox->outputExtent();
1186 return mSelectedOnly->isChecked();
1191 return mCheckPersistMetadata->isChecked();
1196 int currentIndexData = mGeometryTypeComboBox->currentData().toInt();
1197 if ( currentIndexData == -1 )
1208 int currentIndexData = mGeometryTypeComboBox->currentData().toInt();
1209 return currentIndexData == -1;
1214 return mForceMultiCheckBox->isChecked();
1219 mForceMultiCheckBox->setChecked( checked );
1224 return mIncludeZCheckBox->isChecked();
1229 return mActionOnExistingFile;
1234 mIncludeZCheckBox->setChecked( checked );
1237void QgsVectorLayerSaveAsDialog::mSymbologyExportComboBox_currentIndexChanged(
const QString &text )
1239 bool scaleEnabled =
true;
1240 if ( text == tr(
"No symbology" ) )
1242 scaleEnabled =
false;
1244 mScaleWidget->setEnabled( scaleEnabled );
1245 mScaleLabel->setEnabled( scaleEnabled );
1248void QgsVectorLayerSaveAsDialog::mGeometryTypeComboBox_currentIndexChanged(
int )
1254 mForceMultiCheckBox->setEnabled(
true );
1255 mIncludeZCheckBox->setEnabled(
true );
1259 mForceMultiCheckBox->setEnabled(
false );
1260 mForceMultiCheckBox->setChecked(
false );
1261 mIncludeZCheckBox->setEnabled(
false );
1262 mIncludeZCheckBox->setChecked(
false );
1266void QgsVectorLayerSaveAsDialog::mSelectAllAttributes_clicked()
1268 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
1269 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
1271 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1273 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->flags() & Qt::ItemIsEnabled )
1275 if ( ! mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
1276 ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsUserCheckable ) )
1278 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsEnabled );
1280 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->setCheckState( Qt::Checked );
1283 if ( ! mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
1285 mReplaceRawFieldValues->setEnabled(
true );
1289void QgsVectorLayerSaveAsDialog::mDeselectAllAttributes_clicked()
1291 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
1292 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
1294 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1296 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->setCheckState( Qt::Unchecked );
1297 if ( ! mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
1298 ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsUserCheckable ) )
1300 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable );
1301 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( Qt::Unchecked );
1304 if ( ! mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
1306 mReplaceRawFieldValues->setCheckState( Qt::Unchecked );
1307 mReplaceRawFieldValues->setEnabled(
false );
1311void QgsVectorLayerSaveAsDialog::showHelp()
1313 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.
This class represents a coordinate reference system (CRS).
QgsDatumEnsemble datumEnsemble() const
Attempts to retrieve datum ensemble details from the CRS.
Contains information about a datum ensemble.
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.
int size() const
Returns number of items.
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
@ 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...
QString providerType() const
Returns the provider type (provider key) for this layer.
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.
Custom exception class which is raised when an operation is not supported.
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:
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.
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.
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 data sets.
int selectedFeatureCount() const
Returns the number of features that are selected in this layer.
QgsRectangle extent() const FINAL
Returns the extent of the layer.
static QString translatedDisplayString(Qgis::WkbType type)
Returns a translated display string type for a WKB type, e.g., the geometry name used in WKT geometry...
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
QList< int > QgsAttributeList
const QgsCoordinateReferenceSystem & crs
Details of available driver formats.