20#include "moc_qgsvectorlayersaveasdialog.cpp"
34#include <QRegularExpression>
43 : QDialog( parent, fl )
51 : QDialog( parent, fl )
58 mSelectedCrs = layer->
crs();
59 mLayerExtent = layer->
extent();
66 leLayername->setDefaultValue( mDefaultOutputLayerNameFromInputLayerName );
68 if ( leLayername->isEnabled() )
69 leLayername->setText( mDefaultOutputLayerNameFromInputLayerName );
74 mSymbologyExportLabel->hide();
75 mSymbologyExportComboBox->hide();
86 mAttributesSelection->hide();
89 mSelectedOnly->hide();
95 mGeometryGroupBox->hide();
98 mExtentGroupBox->hide();
102 mCheckPersistMetadata->setChecked(
false );
103 mCheckPersistMetadata->hide();
107 mButtonBox->button( QDialogButtonBox::Ok )->setDisabled(
true );
110void QgsVectorLayerSaveAsDialog::setup()
115 connect( mFormatComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsVectorLayerSaveAsDialog::mFormatComboBox_currentIndexChanged );
117 connect( mSymbologyExportComboBox, &QComboBox::currentTextChanged,
this, &QgsVectorLayerSaveAsDialog::mSymbologyExportComboBox_currentIndexChanged );
118 connect( mGeometryTypeComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsVectorLayerSaveAsDialog::mGeometryTypeComboBox_currentIndexChanged );
119 connect( mSelectAllAttributes, &QPushButton::clicked,
this, &QgsVectorLayerSaveAsDialog::mSelectAllAttributes_clicked );
120 connect( mDeselectAllAttributes, &QPushButton::clicked,
this, &QgsVectorLayerSaveAsDialog::mDeselectAllAttributes_clicked );
121 connect( mUseAliasesForExportedName, &QCheckBox::stateChanged,
this, &QgsVectorLayerSaveAsDialog::mUseAliasesForExportedName_stateChanged );
122 connect( mReplaceRawFieldValues, &QCheckBox::stateChanged,
this, &QgsVectorLayerSaveAsDialog::mReplaceRawFieldValues_stateChanged );
123 connect( mAttributeTable, &QTableWidget::itemChanged,
this, &QgsVectorLayerSaveAsDialog::mAttributeTable_itemChanged );
126 mHelpButtonBox->setVisible(
false );
127 mButtonBox->addButton( QDialogButtonBox::Help );
128 connect( mButtonBox, &QDialogButtonBox::helpRequested,
this, &QgsVectorLayerSaveAsDialog::showHelp );
130 connect( mHelpButtonBox, &QDialogButtonBox::helpRequested,
this, &QgsVectorLayerSaveAsDialog::showHelp );
133 connect( mButtonBox, &QDialogButtonBox::rejected,
this, &QgsVectorLayerSaveAsDialog::reject );
136 mFormatComboBox->blockSignals(
true );
139 mFormatComboBox->addItem( driver.longName, driver.driverName );
143 QString
format = settings.
value( QStringLiteral(
"UI/lastVectorFormat" ),
"GPKG" ).toString();
144 mFormatComboBox->setCurrentIndex( mFormatComboBox->findData(
format ) );
145 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 );
198 QFileInfo tmplFileInfo( filePath );
199 settings.
setValue( QStringLiteral(
"UI/lastVectorFileFilterDir" ), tmplFileInfo.absolutePath() );
201 const QFileInfo fileInfo( filePath );
203 if ( mDefaultOutputLayerNameFromInputLayerName.isEmpty() )
204 leLayername->setDefaultValue( suggestedLayerName );
207 if ( leLayername->text().isEmpty() && !filePath.isEmpty() && leLayername->isEnabled() )
209 leLayername->setText( suggestedLayerName );
211 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( !filePath.isEmpty() );
219 mCrsSelector->setSourceEnsemble( ensemble.
name() );
226 mCrsSelector->setShowAccuracyWarnings(
true );
229QList<QPair<QLabel *, QWidget *>> QgsVectorLayerSaveAsDialog::createControls(
const QMap<QString, QgsVectorFileWriter::Option *> &options )
231 QList<QPair<QLabel *, QWidget *>> controls;
232 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
234 for ( it = options.constBegin(); it != options.constEnd(); ++it )
237 QWidget *control =
nullptr;
238 switch ( option->
type )
245 QSpinBox *sb =
new QSpinBox();
246 sb->setObjectName( it.key() );
247 sb->setMaximum( std::numeric_limits<int>::max() );
259 QComboBox *cb =
new QComboBox();
260 cb->setObjectName( it.key() );
261 for (
const QString &val : std::as_const( opt->values ) )
263 cb->addItem( val, val );
270 cb->setCurrentIndex( idx );
282 le->setObjectName( it.key() );
295 QLabel *label =
new QLabel( it.key() );
298 label->setToolTip( QStringLiteral(
"<p>%1</p>" ).arg( option->
docString.toHtmlEscaped() ) );
299 control->setToolTip( QStringLiteral(
"<p>%1</p>" ).arg( option->
docString.toHtmlEscaped() ) );
301 controls << QPair<QLabel *, QWidget *>( label, control );
310#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION( 3, 9, 0 )
311 if (
format() == QLatin1String(
"OpenFileGDB" ) )
315 bool targetAll =
true;
318 if ( layerOption == QLatin1String(
"TARGET_ARCGIS_VERSION=ARCGIS_PRO_3_2_OR_LATER" ) )
325 for (
int i = 0; i < mLayer->
fields().
size(); ++i )
328 if ( fld.
type() == QMetaType::Type::LongLong )
330 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 )
339 else if (
format() == QLatin1String(
"FileGDB" ) )
342 for (
int i = 0; i < mLayer->
fields().
size(); ++i )
345 if ( fld.
type() == QMetaType::Type::LongLong )
347 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 )
362 msgBox.setIcon( QMessageBox::Question );
363 msgBox.setWindowTitle( tr(
"Save Vector Layer As" ) );
364 QPushButton *overwriteFileButton = msgBox.addButton( tr(
"Overwrite File" ), QMessageBox::ActionRole );
365 QPushButton *overwriteLayerButton = msgBox.addButton( tr(
"Overwrite Layer" ), QMessageBox::ActionRole );
366 QPushButton *appendToLayerButton = msgBox.addButton( tr(
"Append to Layer" ), QMessageBox::ActionRole );
367 msgBox.setStandardButtons( QMessageBox::Cancel );
368 msgBox.setDefaultButton( QMessageBox::Cancel );
369 overwriteFileButton->hide();
370 overwriteLayerButton->hide();
371 appendToLayerButton->hide();
376 msgBox.setText( tr(
"The layer already exists. Do you want to overwrite the whole file or overwrite the layer?" ) );
377 overwriteFileButton->setVisible(
true );
378 overwriteLayerButton->setVisible(
true );
382 msgBox.setText( tr(
"The file already exists. Do you want to overwrite it?" ) );
383 overwriteFileButton->setVisible(
true );
387 msgBox.setText( tr(
"The layer already exists. Do you want to overwrite the whole file, overwrite the layer or append features to the layer?" ) );
388 appendToLayerButton->setVisible(
true );
389 overwriteFileButton->setVisible(
true );
390 overwriteLayerButton->setVisible(
true );
394 msgBox.setText( tr(
"The layer already exists. Do you want to overwrite the whole file or append features to the layer?" ) );
395 appendToLayerButton->setVisible(
true );
396 overwriteFileButton->setVisible(
true );
399 int ret = msgBox.exec();
400 if ( ret == QMessageBox::Cancel )
402 if ( msgBox.clickedButton() == overwriteFileButton )
404 else if ( msgBox.clickedButton() == overwriteLayerButton )
406 else if ( msgBox.clickedButton() == appendToLayerButton )
418 if ( QMessageBox::question(
this, tr(
"Save Vector Layer As" ), tr(
"The file already exists. Do you want to overwrite it?" ) ) != QMessageBox::Yes )
431 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 )
440 QStringList layerList;
441 layerList.reserve( sublayers.size() );
444 layerList.append( sublayer.name() );
446 if ( layerList.length() > 1 )
448 layerList.sort( Qt::CaseInsensitive );
450 msgBox.setIcon( QMessageBox::Warning );
451 msgBox.setWindowTitle( tr(
"Overwrite File" ) );
452 msgBox.setText( tr(
"This file contains %1 layers that will be lost!\n" ).arg( QLocale().toString( layerList.length() ) ) );
453 msgBox.setDetailedText( tr(
"The following layers will be permanently lost:\n\n%1" ).arg( layerList.join(
"\n" ) ) );
454 msgBox.setStandardButtons( QMessageBox::Ok | QMessageBox::Cancel );
455 if ( msgBox.exec() == QMessageBox::Cancel )
461 settings.
setValue( QStringLiteral(
"UI/lastVectorFileFilterDir" ), QFileInfo(
fileName() ).absolutePath() );
462 settings.
setValue( QStringLiteral(
"UI/lastVectorFormat" ),
format() );
467void QgsVectorLayerSaveAsDialog::mFormatComboBox_currentIndexChanged(
int idx )
471 mFilename->setEnabled(
true );
479 if (
format() == QLatin1String(
"OpenFileGDB" ) ||
format() == QLatin1String(
"FileGDB" ) )
480 filter = QStringLiteral(
"%1 (*.gdb *.GDB gdb)" ).arg( tr(
"ESRI File Geodatabase" ) );
481 mFilename->setFilter( filter );
485 if ( !mFilename->filePath().isEmpty() )
487 const thread_local QRegularExpression rx(
"\\.(.*?)[\\s]" );
488 const QString ext = rx.match( filter ).captured( 1 );
489 if ( !ext.isEmpty() )
491 QFileInfo fi( mFilename->filePath() );
492 mFilename->setFilePath( QStringLiteral(
"%1/%2.%3" ).arg( fi.path(), fi.baseName(), ext ) );
496 bool selectAllFields =
true;
501 bool isFormatForFieldsAsDisplayedValues =
false;
503 const QString sFormat(
format() );
504 if ( sFormat == QLatin1String(
"DXF" ) || sFormat == QLatin1String(
"DGN" ) )
506 mAttributesSelection->setVisible(
false );
507 selectAllFields =
false;
513 mAttributesSelection->setVisible(
true );
514 isFormatForFieldsAsDisplayedValues = ( sFormat == QLatin1String(
"CSV" ) || sFormat == QLatin1String(
"XLS" ) || sFormat == QLatin1String(
"XLSX" ) || sFormat == QLatin1String(
"ODS" ) );
521 mSymbologyExportLabel->setVisible(
true );
522 mSymbologyExportComboBox->setVisible(
true );
523 mScaleLabel->setVisible(
true );
524 mScaleWidget->setVisible(
true );
528 mSymbologyExportLabel->hide();
529 mSymbologyExportComboBox->hide();
531 mScaleWidget->hide();
534 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" ) );
536 if ( sFormat == QLatin1String(
"XLSX" ) )
537 leLayername->setMaxLength( 31 );
538 else if ( leLayername->isEnabled() )
539 leLayername->setMaxLength( 32767 );
541 if ( !leLayername->isEnabled() )
542 leLayername->setText( QString() );
543 else if ( leLayername->text().isEmpty() )
545 QString
layerName = mDefaultOutputLayerNameFromInputLayerName;
546 if (
layerName.isEmpty() && !mFilename->filePath().isEmpty() )
548 layerName = QFileInfo( mFilename->filePath() ).baseName();
549 leLayername->setDefaultValue(
layerName );
558 mAttributeTable->setRowCount( mLayer->
fields().
count() );
560 QStringList horizontalHeaders = QStringList() << tr(
"Name" ) << tr(
"Export name" ) << tr(
"Type" ) << tr(
"Replace with displayed values" );
561 mAttributeTable->setColumnCount( horizontalHeaders.size() );
562 mAttributeTable->setHorizontalHeaderLabels( horizontalHeaders );
564 bool foundFieldThatCanBeExportedAsDisplayedValue =
false;
565 for (
int i = 0; i < mLayer->
fields().size(); ++i )
570 foundFieldThatCanBeExportedAsDisplayedValue =
true;
574 mAttributeTable->setColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ), !foundFieldThatCanBeExportedAsDisplayedValue );
576 bool checkReplaceRawFieldValues = selectAllFields && isFormatForFieldsAsDisplayedValues;
577 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
579 for (
int i = 0; i < mLayer->
fields().size(); ++i )
582 Qt::ItemFlags flags = mLayer->
providerType() != QLatin1String(
"oracle" ) || !fld.
typeName().contains( QLatin1String(
"SDO_GEOMETRY" ) ) ? Qt::ItemIsEnabled : Qt::NoItemFlags;
583 QTableWidgetItem *item =
nullptr;
584 item =
new QTableWidgetItem( fld.
name() );
585 item->setFlags( flags | Qt::ItemIsUserCheckable );
586 item->setCheckState( ( selectAllFields ) ? Qt::Checked : Qt::Unchecked );
587 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::Name ), item );
589 item =
new QTableWidgetItem( fld.
name() );
590 item->setFlags( flags | Qt::ItemIsEditable );
592 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::ExportName ), item );
594 item =
new QTableWidgetItem( fld.
typeName() );
595 item->setFlags( flags );
596 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::Type ), item );
598 if ( foundFieldThatCanBeExportedAsDisplayedValue )
602 const QString widgetId( setup.
type() );
603 if ( flags == Qt::ItemIsEnabled && widgetId != QLatin1String(
"TextEdit" ) && ( factory =
QgsGui::editorWidgetRegistry()->factory( widgetId ) ) )
605 item =
new QTableWidgetItem( tr(
"Use %1" ).arg( factory->
name() ) );
606 item->setFlags( ( selectAllFields ) ? ( Qt::ItemIsEnabled | Qt::ItemIsUserCheckable ) : Qt::ItemIsUserCheckable );
607 const bool checkItem = ( selectAllFields && isFormatForFieldsAsDisplayedValues && ( widgetId == QLatin1String(
"ValueMap" ) || widgetId == QLatin1String(
"ValueRelation" ) || widgetId == QLatin1String(
"CheckBox" ) || widgetId == QLatin1String(
"RelationReference" ) ) );
608 checkReplaceRawFieldValues &= checkItem;
609 item->setCheckState( checkItem ? Qt::Checked : Qt::Unchecked );
610 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ), item );
614 item =
new QTableWidgetItem();
615 item->setFlags( Qt::NoItemFlags );
616 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ), item );
622 whileBlocking( mReplaceRawFieldValues )->setChecked( checkReplaceRawFieldValues );
623 mReplaceRawFieldValues->setEnabled( selectAllFields );
624 mReplaceRawFieldValues->setVisible( foundFieldThatCanBeExportedAsDisplayedValue );
626 mAttributeTable->resizeColumnsToContents();
631 while ( mDatasourceOptionsGroupBox->layout()->count() )
633 QLayoutItem *item = mDatasourceOptionsGroupBox->layout()->takeAt( 0 );
634 delete item->widget();
638 while ( mLayerOptionsGroupBox->layout()->count() )
640 QLayoutItem *item = mLayerOptionsGroupBox->layout()->takeAt( 0 );
641 delete item->widget();
645 typedef QPair<QLabel *, QWidget *> LabelControlPair;
651 mDatasourceOptionsGroupBox->setVisible(
true );
652 QList<QPair<QLabel *, QWidget *>> controls = createControls( driverMetaData.
driverOptions );
654 QFormLayout *datasourceLayout =
dynamic_cast<QFormLayout *
>( mDatasourceOptionsGroupBox->layout() );
656 const auto constControls = controls;
657 for ( LabelControlPair control : constControls )
659 datasourceLayout->addRow( control.first, control.second );
664 mDatasourceOptionsGroupBox->setVisible(
false );
669 mLayerOptionsGroupBox->setVisible(
true );
670 QList<QPair<QLabel *, QWidget *>> controls = createControls( driverMetaData.
layerOptions );
672 QFormLayout *layerOptionsLayout =
dynamic_cast<QFormLayout *
>( mLayerOptionsGroupBox->layout() );
674 const auto constControls = controls;
675 for ( LabelControlPair control : constControls )
677 layerOptionsLayout->addRow( control.first, control.second );
682 mLayerOptionsGroupBox->setVisible(
false );
687 mEncodingComboBox->setEnabled(
true );
694 mEncodingComboBox->setCurrentIndex( idx );
695 mEncodingComboBox->setDisabled(
true );
699 mEncodingComboBox->setEnabled(
true );
705 mEncodingComboBox->setEnabled(
true );
708 GDALDriverH hDriver = GDALGetDriverByName(
format().toUtf8().constData() );
711 const bool canReopen = GDALGetMetadataItem( hDriver, GDAL_DCAP_OPEN,
nullptr );
712 if ( mAddToCanvas->isEnabled() && !canReopen )
714 mAddToCanvasStateOnOpenCompatibleDriver = mAddToCanvas->isChecked();
715 mAddToCanvas->setChecked(
false );
716 mAddToCanvas->setEnabled(
false );
718 else if ( !mAddToCanvas->isEnabled() && canReopen )
720 mAddToCanvas->setChecked( mAddToCanvasStateOnOpenCompatibleDriver );
721 mAddToCanvas->setEnabled(
true );
726void QgsVectorLayerSaveAsDialog::mUseAliasesForExportedName_stateChanged(
int state )
728 const QSignalBlocker signalBlocker( mAttributeTable );
735 bool modifiedEntries =
false;
736 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
738 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->text()
739 != mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->data( Qt::UserRole ).toString() )
741 modifiedEntries =
true;
746 if ( modifiedEntries )
748 if ( QMessageBox::question(
this, tr(
"Modified names" ), tr(
"Some names were modified and will be overridden. Do you want to continue?" ) )
751 whileBlocking( mUseAliasesForExportedName )->setCheckState( Qt::PartiallyChecked );
756 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
758 mUseAliasesForExportedName->setTristate(
false );
759 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->setText( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->text() );
766 bool modifiedEntries =
false;
767 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
769 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->text()
770 != mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->text() )
771 modifiedEntries =
true;
774 if ( modifiedEntries )
776 if ( QMessageBox::question(
this, tr(
"Modified names" ), tr(
"Some names were modified and will be overridden. Do you want to continue?" ) )
779 whileBlocking( mUseAliasesForExportedName )->setCheckState( Qt::PartiallyChecked );
784 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
786 mUseAliasesForExportedName->setTristate(
false );
787 const QString alias = mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->data( Qt::UserRole ).toString();
788 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->setText( alias );
792 case Qt::PartiallyChecked:
798void QgsVectorLayerSaveAsDialog::mReplaceRawFieldValues_stateChanged(
int )
800 if ( mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
803 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
804 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
806 if ( mReplaceRawFieldValues->checkState() != Qt::PartiallyChecked )
808 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
810 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 )
812 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( mReplaceRawFieldValues->checkState() );
816 mReplaceRawFieldValues->setTristate(
false );
819void QgsVectorLayerSaveAsDialog::mAttributeTable_itemChanged( QTableWidgetItem *item )
821 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
822 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
824 int row = item->row();
825 int column = item->column();
827 switch (
static_cast<ColumnIndex
>( column ) )
829 case ColumnIndex::Name:
831 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 ) )
834 if ( mAttributeTable->item( row, column )->checkState() == Qt::Unchecked )
836 mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( Qt::Unchecked );
837 mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable );
838 bool checkBoxEnabled =
false;
839 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
841 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) && mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsEnabled )
843 checkBoxEnabled =
true;
847 mReplaceRawFieldValues->setEnabled( checkBoxEnabled );
848 if ( !checkBoxEnabled )
849 mReplaceRawFieldValues->setCheckState( Qt::Unchecked );
851 else if ( mAttributeTable->item( row, column )->checkState() == Qt::Checked )
853 mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsEnabled );
854 mReplaceRawFieldValues->setEnabled(
true );
858 case ColumnIndex::ExportName:
861 if ( item->text().isEmpty() )
863 QMessageBox::warning(
this, tr(
"Empty export name" ), tr(
"Empty export name are not allowed." ) );
869 while ( names.count( item->text() ) > 1 )
870 item->setText( QString(
"%1_2" ).arg( item->text() ) );
872 mUseAliasesForExportedName->setCheckState( Qt::PartiallyChecked );
875 case ColumnIndex::Type:
878 case ColumnIndex::ExportAsDisplayedValue:
880 if ( mAttributeTable->item( row, column )->flags() & Qt::ItemIsUserCheckable )
882 bool allChecked =
true;
883 bool allUnchecked =
true;
884 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
886 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) && mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsEnabled )
888 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->checkState() == Qt::Unchecked )
891 allUnchecked =
false;
894 mReplaceRawFieldValues->setCheckState( ( !allChecked && !allUnchecked ) ? Qt::PartiallyChecked : ( allChecked ) ? Qt::Checked
905 mExtentGroupBox->setOutputCrs( mSelectedCrs );
910 return mFilename->filePath();
915 return leLayername->text();
920 return mEncodingComboBox->currentText();
925 return mFormatComboBox->currentData().toString();
941 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
945 switch ( it.value()->type )
950 QSpinBox *sb = mDatasourceOptionsGroupBox->findChild<QSpinBox *>( it.key() );
952 options << QStringLiteral(
"%1=%2" ).arg( it.key() ).arg( sb->value() );
959 QComboBox *cb = mDatasourceOptionsGroupBox->findChild<QComboBox *>( it.key() );
960 if ( opt && cb && cb->itemData( cb->currentIndex() ) != opt->
defaultValue )
961 options << QStringLiteral(
"%1=%2" ).arg( it.key(), cb->currentText() );
968 QLineEdit *le = mDatasourceOptionsGroupBox->findChild<QLineEdit *>( it.key() );
970 options << QStringLiteral(
"%1=%2" ).arg( it.key(), le->text() );
977 if ( !opt->
mValue.isEmpty() )
978 options << QStringLiteral(
"%1=%2" ).arg( it.key(), opt->
mValue );
985 QString plainText = mOgrDatasourceOptions->toPlainText().trimmed();
986 if ( !plainText.isEmpty() )
987 options += plainText.split(
'\n' );
1000 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
1004 switch ( it.value()->type )
1009 QSpinBox *sb = mLayerOptionsGroupBox->findChild<QSpinBox *>( it.key() );
1011 options << QStringLiteral(
"%1=%2" ).arg( it.key() ).arg( sb->value() );
1018 QComboBox *cb = mLayerOptionsGroupBox->findChild<QComboBox *>( it.key() );
1019 if ( opt && cb && cb->itemData( cb->currentIndex() ) != opt->
defaultValue )
1020 options << QStringLiteral(
"%1=%2" ).arg( it.key(), cb->currentText() );
1027 QLineEdit *le = mLayerOptionsGroupBox->findChild<QLineEdit *>( it.key() );
1029 options << QStringLiteral(
"%1=%2" ).arg( it.key(), le->text() );
1036 if ( !opt->
mValue.isEmpty() )
1037 options << QStringLiteral(
"%1=%2" ).arg( it.key(), opt->
mValue );
1044 QString plainText = mOgrLayerOptions->toPlainText().trimmed();
1045 if ( !plainText.isEmpty() )
1046 options += plainText.split(
'\n' );
1055 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1057 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->checkState() == Qt::Checked )
1059 attributes.append( i );
1070 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1072 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 )
1074 attributes.append( i );
1083 QStringList exportNames;
1084 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1085 exportNames.append( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->text() );
1092 return mAddToCanvas->isChecked();
1097 mAddToCanvasStateOnOpenCompatibleDriver = enabled;
1098 if ( mAddToCanvas->isEnabled() )
1099 mAddToCanvas->setChecked( enabled );
1109 return mScaleWidget->scale();
1114 mMapCanvas = canvas;
1115 mScaleWidget->setMapCanvas( canvas );
1116 mScaleWidget->setShowCurrentScaleButton(
true );
1122 return mExtentGroupBox->isChecked();
1127 return mExtentGroupBox->outputExtent();
1137 return mSelectedOnly->isChecked();
1142 return mCheckPersistMetadata->isChecked();
1147 int currentIndexData = mGeometryTypeComboBox->currentData().toInt();
1148 if ( currentIndexData == -1 )
1159 int currentIndexData = mGeometryTypeComboBox->currentData().toInt();
1160 return currentIndexData == -1;
1165 return mForceMultiCheckBox->isChecked();
1170 mForceMultiCheckBox->setChecked( checked );
1175 return mIncludeZCheckBox->isChecked();
1180 return mActionOnExistingFile;
1185 mIncludeZCheckBox->setChecked( checked );
1188void QgsVectorLayerSaveAsDialog::mSymbologyExportComboBox_currentIndexChanged(
const QString &text )
1190 bool scaleEnabled =
true;
1191 if ( text == tr(
"No symbology" ) )
1193 scaleEnabled =
false;
1195 mScaleWidget->setEnabled( scaleEnabled );
1196 mScaleLabel->setEnabled( scaleEnabled );
1199void QgsVectorLayerSaveAsDialog::mGeometryTypeComboBox_currentIndexChanged(
int )
1205 mForceMultiCheckBox->setEnabled(
true );
1206 mIncludeZCheckBox->setEnabled(
true );
1210 mForceMultiCheckBox->setEnabled(
false );
1211 mForceMultiCheckBox->setChecked(
false );
1212 mIncludeZCheckBox->setEnabled(
false );
1213 mIncludeZCheckBox->setChecked(
false );
1217void QgsVectorLayerSaveAsDialog::mSelectAllAttributes_clicked()
1219 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
1220 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
1222 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1224 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->flags() & Qt::ItemIsEnabled )
1226 if ( !mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) && ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsUserCheckable ) )
1228 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsEnabled );
1230 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->setCheckState( Qt::Checked );
1233 if ( !mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
1235 mReplaceRawFieldValues->setEnabled(
true );
1239void QgsVectorLayerSaveAsDialog::mDeselectAllAttributes_clicked()
1241 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
1242 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
1244 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1246 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->setCheckState( Qt::Unchecked );
1247 if ( !mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) && ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsUserCheckable ) )
1249 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable );
1250 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( Qt::Unchecked );
1253 if ( !mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
1255 mReplaceRawFieldValues->setCheckState( Qt::Unchecked );
1256 mReplaceRawFieldValues->setEnabled(
false );
1260void QgsVectorLayerSaveAsDialog::showHelp()
1262 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.