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 );
153 mGeometryTypeComboBox->addItem( tr(
"Automatic" ), -1 );
159 mGeometryTypeComboBox->setCurrentIndex( mGeometryTypeComboBox->findData( -1 ) );
163 QString enc = settings.
value( QStringLiteral(
"UI/encoding" ),
"System" ).toString();
164 int idx = mEncodingComboBox->findText( enc );
167 mEncodingComboBox->insertItem( 0, enc );
171 mCrsSelector->setCrs( mSelectedCrs );
172 mCrsSelector->setLayerCrs( mSelectedCrs );
173 mCrsSelector->setMessage( tr(
"Select the coordinate reference system for the vector file. "
174 "The data points will be transformed from the layer coordinate reference system." ) );
176 mEncodingComboBox->setCurrentIndex( idx );
177 mFormatComboBox_currentIndexChanged( mFormatComboBox->currentIndex() );
183 mSymbologyExportComboBox_currentIndexChanged( mSymbologyExportComboBox->currentText() );
186 mExtentGroupBox->setOutputCrs( mSelectedCrs );
187 mExtentGroupBox->setOriginalExtent( mLayerExtent, mSelectedCrs );
188 mExtentGroupBox->setOutputExtentFromOriginal();
189 mExtentGroupBox->setCheckable(
true );
190 mExtentGroupBox->setChecked(
false );
191 mExtentGroupBox->setCollapsed(
true );
194 mFilename->setDialogTitle( tr(
"Save Layer As" ) );
195 mFilename->setDefaultRoot( settings.
value( QStringLiteral(
"UI/lastVectorFileFilterDir" ), QDir::homePath() ).toString() );
196 mFilename->setConfirmOverwrite(
false );
200 QFileInfo tmplFileInfo( filePath );
201 settings.
setValue( QStringLiteral(
"UI/lastVectorFileFilterDir" ), tmplFileInfo.absolutePath() );
203 const QFileInfo fileInfo( filePath );
205 if ( mDefaultOutputLayerNameFromInputLayerName.isEmpty() )
206 leLayername->setDefaultValue( suggestedLayerName );
209 if ( leLayername->text().isEmpty() && !filePath.isEmpty() && leLayername->isEnabled() )
211 leLayername->setText( suggestedLayerName );
213 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( !filePath.isEmpty() );
221 mCrsSelector->setSourceEnsemble( ensemble.
name() );
228 mCrsSelector->setShowAccuracyWarnings(
true );
231QList<QPair<QLabel *, QWidget *> > QgsVectorLayerSaveAsDialog::createControls(
const QMap<QString, QgsVectorFileWriter::Option *> &options )
233 QList<QPair<QLabel *, QWidget *> > controls;
234 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
236 for ( it = options.constBegin(); it != options.constEnd(); ++it )
239 QWidget *control =
nullptr;
240 switch ( option->
type )
247 QSpinBox *sb =
new QSpinBox();
248 sb->setObjectName( it.key() );
249 sb->setMaximum( std::numeric_limits<int>::max() );
261 QComboBox *cb =
new QComboBox();
262 cb->setObjectName( it.key() );
263 for (
const QString &val : std::as_const( opt->values ) )
265 cb->addItem( val, val );
272 cb->setCurrentIndex( idx );
284 le->setObjectName( it.key() );
297 QLabel *label =
new QLabel( it.key() );
300 label->setToolTip( QStringLiteral(
"<p>%1</p>" ).arg( option->
docString.toHtmlEscaped() ) );
301 control->setToolTip( QStringLiteral(
"<p>%1</p>" ).arg( option->
docString.toHtmlEscaped() ) );
303 controls << QPair<QLabel *, QWidget *>( label, control );
312#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3,9,0)
313 if (
format() == QLatin1String(
"OpenFileGDB" ) )
317 bool targetAll =
true;
320 if ( layerOption == QLatin1String(
"TARGET_ARCGIS_VERSION=ARCGIS_PRO_3_2_OR_LATER" ) )
327 for (
int i = 0; i < mLayer->
fields().
size(); ++i )
330 if ( fld.
type() == QMetaType::Type::LongLong )
332 if ( QMessageBox::question(
this,
333 tr(
"Save Vector Layer As" ),
334 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 )
349 if ( fld.
type() == QMetaType::Type::LongLong )
351 if ( QMessageBox::question(
this,
352 tr(
"Save Vector Layer As" ),
353 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 )
370 msgBox.setIcon( QMessageBox::Question );
371 msgBox.setWindowTitle( tr(
"Save Vector Layer As" ) );
372 QPushButton *overwriteFileButton = msgBox.addButton( tr(
"Overwrite File" ), QMessageBox::ActionRole );
373 QPushButton *overwriteLayerButton = msgBox.addButton( tr(
"Overwrite Layer" ), QMessageBox::ActionRole );
374 QPushButton *appendToLayerButton = msgBox.addButton( tr(
"Append to Layer" ), QMessageBox::ActionRole );
375 msgBox.setStandardButtons( QMessageBox::Cancel );
376 msgBox.setDefaultButton( QMessageBox::Cancel );
377 overwriteFileButton->hide();
378 overwriteLayerButton->hide();
379 appendToLayerButton->hide();
386 msgBox.setText( tr(
"The layer already exists. Do you want to overwrite the whole file or overwrite the layer?" ) );
387 overwriteFileButton->setVisible(
true );
388 overwriteLayerButton->setVisible(
true );
392 msgBox.setText( tr(
"The file already exists. Do you want to overwrite it?" ) );
393 overwriteFileButton->setVisible(
true );
398 msgBox.setText( tr(
"The layer already exists. Do you want to overwrite the whole file, overwrite the layer or append features to the layer?" ) );
399 appendToLayerButton->setVisible(
true );
400 overwriteFileButton->setVisible(
true );
401 overwriteLayerButton->setVisible(
true );
405 msgBox.setText( tr(
"The layer already exists. Do you want to overwrite the whole file or append features to the layer?" ) );
406 appendToLayerButton->setVisible(
true );
407 overwriteFileButton->setVisible(
true );
410 int ret = msgBox.exec();
411 if ( ret == QMessageBox::Cancel )
413 if ( msgBox.clickedButton() == overwriteFileButton )
415 else if ( msgBox.clickedButton() == overwriteLayerButton )
417 else if ( msgBox.clickedButton() == appendToLayerButton )
429 if ( QMessageBox::question(
this,
430 tr(
"Save Vector Layer As" ),
431 tr(
"The file already exists. Do you want to overwrite it?" ) ) != QMessageBox::Yes )
444 if ( QMessageBox::question(
this,
445 tr(
"Save Vector Layer As" ),
446 tr(
"The existing layer has additional fields. Do you want to add the missing fields to the layer?" ) ) == QMessageBox::Yes )
455 QStringList layerList;
456 layerList.reserve( sublayers.size() );
459 layerList.append( sublayer.name() );
461 if ( layerList.length() > 1 )
463 layerList.sort( Qt::CaseInsensitive );
465 msgBox.setIcon( QMessageBox::Warning );
466 msgBox.setWindowTitle( tr(
"Overwrite File" ) );
467 msgBox.setText( tr(
"This file contains %1 layers that will be lost!\n" ).arg( QLocale().toString( layerList.length() ) ) );
468 msgBox.setDetailedText( tr(
"The following layers will be permanently lost:\n\n%1" ).arg( layerList.join(
"\n" ) ) );
469 msgBox.setStandardButtons( QMessageBox::Ok | QMessageBox::Cancel );
470 if ( msgBox.exec() == QMessageBox::Cancel )
476 settings.
setValue( QStringLiteral(
"UI/lastVectorFileFilterDir" ), QFileInfo(
fileName() ).absolutePath() );
477 settings.
setValue( QStringLiteral(
"UI/lastVectorFormat" ),
format() );
482void QgsVectorLayerSaveAsDialog::mFormatComboBox_currentIndexChanged(
int idx )
486 mFilename->setEnabled(
true );
494 if (
format() == QLatin1String(
"OpenFileGDB" ) ||
format() == QLatin1String(
"FileGDB" ) )
495 filter = QStringLiteral(
"%1 (*.gdb *.GDB gdb)" ).arg( tr(
"ESRI File Geodatabase" ) );
496 mFilename->setFilter( filter );
500 if ( !mFilename->filePath().isEmpty() )
502 const thread_local QRegularExpression rx(
"\\.(.*?)[\\s]" );
503 const QString ext = rx.match( filter ).captured( 1 );
504 if ( !ext.isEmpty() )
506 QFileInfo fi( mFilename->filePath() );
507 mFilename->setFilePath( QStringLiteral(
"%1/%2.%3" ).arg( fi.path(), fi.baseName(), ext ) );
511 bool selectAllFields =
true;
516 bool isFormatForFieldsAsDisplayedValues =
false;
518 const QString sFormat(
format() );
519 if ( sFormat == QLatin1String(
"DXF" ) || sFormat == QLatin1String(
"DGN" ) )
521 mAttributesSelection->setVisible(
false );
522 selectAllFields =
false;
528 mAttributesSelection->setVisible(
true );
529 isFormatForFieldsAsDisplayedValues = ( sFormat == QLatin1String(
"CSV" ) ||
530 sFormat == QLatin1String(
"XLS" ) ||
531 sFormat == QLatin1String(
"XLSX" ) ||
532 sFormat == QLatin1String(
"ODS" ) );
539 mSymbologyExportLabel->setVisible(
true );
540 mSymbologyExportComboBox->setVisible(
true );
541 mScaleLabel->setVisible(
true );
542 mScaleWidget->setVisible(
true );
546 mSymbologyExportLabel->hide();
547 mSymbologyExportComboBox->hide();
549 mScaleWidget->hide();
552 leLayername->setEnabled( sFormat == QLatin1String(
"KML" ) ||
553 sFormat == QLatin1String(
"GPKG" ) ||
554 sFormat == QLatin1String(
"XLSX" ) ||
555 sFormat == QLatin1String(
"ODS" ) ||
556 sFormat == QLatin1String(
"FileGDB" ) ||
557 sFormat == QLatin1String(
"OpenFileGDB" ) ||
558 sFormat == QLatin1String(
"SQLite" ) ||
559 sFormat == QLatin1String(
"SpatiaLite" ) );
561 if ( sFormat == QLatin1String(
"XLSX" ) )
562 leLayername->setMaxLength( 31 );
563 else if ( leLayername->isEnabled() )
564 leLayername->setMaxLength( 32767 );
566 if ( !leLayername->isEnabled() )
567 leLayername->setText( QString() );
568 else if ( leLayername->text().isEmpty() )
570 QString
layerName = mDefaultOutputLayerNameFromInputLayerName;
571 if (
layerName.isEmpty() && !mFilename->filePath().isEmpty() )
573 layerName = QFileInfo( mFilename->filePath() ).baseName();
574 leLayername->setDefaultValue(
layerName );
583 mAttributeTable->setRowCount( mLayer->
fields().
count() );
585 QStringList horizontalHeaders = QStringList() << tr(
"Name" ) << tr(
"Export name" ) << tr(
"Type" ) << tr(
"Replace with displayed values" );
586 mAttributeTable->setColumnCount( horizontalHeaders.size() );
587 mAttributeTable->setHorizontalHeaderLabels( horizontalHeaders );
589 bool foundFieldThatCanBeExportedAsDisplayedValue =
false;
590 for (
int i = 0; i < mLayer->
fields().size(); ++i )
593 if ( setup.
type() != QLatin1String(
"TextEdit" ) &&
596 foundFieldThatCanBeExportedAsDisplayedValue =
true;
600 mAttributeTable->setColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ),
601 ! foundFieldThatCanBeExportedAsDisplayedValue );
603 bool checkReplaceRawFieldValues = selectAllFields && isFormatForFieldsAsDisplayedValues;
604 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
606 for (
int i = 0; i < mLayer->
fields().size(); ++i )
609 Qt::ItemFlags flags = mLayer->
providerType() != QLatin1String(
"oracle" ) || !fld.
typeName().contains( QLatin1String(
"SDO_GEOMETRY" ) ) ? Qt::ItemIsEnabled : Qt::NoItemFlags;
610 QTableWidgetItem *item =
nullptr;
611 item =
new QTableWidgetItem( fld.
name() );
612 item->setFlags( flags | Qt::ItemIsUserCheckable );
613 item->setCheckState( ( selectAllFields ) ? Qt::Checked : Qt::Unchecked );
614 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::Name ), item );
616 item =
new QTableWidgetItem( fld.
name() );
617 item->setFlags( flags | Qt::ItemIsEditable );
619 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::ExportName ), item );
621 item =
new QTableWidgetItem( fld.
typeName() );
622 item->setFlags( flags );
623 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::Type ), item );
625 if ( foundFieldThatCanBeExportedAsDisplayedValue )
629 const QString widgetId( setup.
type() );
630 if ( flags == Qt::ItemIsEnabled &&
631 widgetId != QLatin1String(
"TextEdit" ) &&
634 item =
new QTableWidgetItem( tr(
"Use %1" ).arg( factory->
name() ) );
635 item->setFlags( ( selectAllFields ) ? ( Qt::ItemIsEnabled | Qt::ItemIsUserCheckable ) : Qt::ItemIsUserCheckable );
636 const bool checkItem = ( selectAllFields && isFormatForFieldsAsDisplayedValues &&
637 ( widgetId == QLatin1String(
"ValueMap" ) ||
638 widgetId == QLatin1String(
"ValueRelation" ) ||
639 widgetId == QLatin1String(
"CheckBox" ) ||
640 widgetId == QLatin1String(
"RelationReference" ) ) );
641 checkReplaceRawFieldValues &= checkItem;
642 item->setCheckState( checkItem ?
643 Qt::Checked : Qt::Unchecked );
644 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ), item );
648 item =
new QTableWidgetItem();
649 item->setFlags( Qt::NoItemFlags );
650 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ), item );
656 whileBlocking( mReplaceRawFieldValues )->setChecked( checkReplaceRawFieldValues );
657 mReplaceRawFieldValues->setEnabled( selectAllFields );
658 mReplaceRawFieldValues->setVisible( foundFieldThatCanBeExportedAsDisplayedValue );
660 mAttributeTable->resizeColumnsToContents();
665 while ( mDatasourceOptionsGroupBox->layout()->count() )
667 QLayoutItem *item = mDatasourceOptionsGroupBox->layout()->takeAt( 0 );
668 delete item->widget();
672 while ( mLayerOptionsGroupBox->layout()->count() )
674 QLayoutItem *item = mLayerOptionsGroupBox->layout()->takeAt( 0 );
675 delete item->widget();
679 typedef QPair<QLabel *, QWidget *> LabelControlPair;
685 mDatasourceOptionsGroupBox->setVisible(
true );
686 QList<QPair<QLabel *, QWidget *> > controls = createControls( driverMetaData.
driverOptions );
688 QFormLayout *datasourceLayout =
dynamic_cast<QFormLayout *
>( mDatasourceOptionsGroupBox->layout() );
690 const auto constControls = controls;
691 for ( LabelControlPair control : constControls )
693 datasourceLayout->addRow( control.first, control.second );
698 mDatasourceOptionsGroupBox->setVisible(
false );
703 mLayerOptionsGroupBox->setVisible(
true );
704 QList<QPair<QLabel *, QWidget *> > controls = createControls( driverMetaData.
layerOptions );
706 QFormLayout *layerOptionsLayout =
dynamic_cast<QFormLayout *
>( mLayerOptionsGroupBox->layout() );
708 const auto constControls = controls;
709 for ( LabelControlPair control : constControls )
711 layerOptionsLayout->addRow( control.first, control.second );
716 mLayerOptionsGroupBox->setVisible(
false );
721 mEncodingComboBox->setEnabled(
true );
728 mEncodingComboBox->setCurrentIndex( idx );
729 mEncodingComboBox->setDisabled(
true );
733 mEncodingComboBox->setEnabled(
true );
740 mEncodingComboBox->setEnabled(
true );
743 GDALDriverH hDriver = GDALGetDriverByName(
format().toUtf8().constData() );
746 const bool canReopen = GDALGetMetadataItem( hDriver, GDAL_DCAP_OPEN,
nullptr );
747 if ( mAddToCanvas->isEnabled() && !canReopen )
749 mAddToCanvasStateOnOpenCompatibleDriver = mAddToCanvas->isChecked();
750 mAddToCanvas->setChecked(
false );
751 mAddToCanvas->setEnabled(
false );
753 else if ( !mAddToCanvas->isEnabled() && canReopen )
755 mAddToCanvas->setChecked( mAddToCanvasStateOnOpenCompatibleDriver );
756 mAddToCanvas->setEnabled(
true );
761void QgsVectorLayerSaveAsDialog::mUseAliasesForExportedName_stateChanged(
int state )
763 const QSignalBlocker signalBlocker( mAttributeTable );
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::ExportName ) )->data( Qt::UserRole ).toString() )
776 modifiedEntries =
true;
781 if ( modifiedEntries )
783 if ( QMessageBox::question(
this,
784 tr(
"Modified names" ),
785 tr(
"Some names were modified and will be overridden. Do you want to continue?" ) )
788 whileBlocking( mUseAliasesForExportedName )->setCheckState( Qt::PartiallyChecked );
793 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
795 mUseAliasesForExportedName->setTristate(
false );
796 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->setText( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->text() );
803 bool modifiedEntries =
false;
804 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
806 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->text()
807 != mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->text() )
808 modifiedEntries =
true;
811 if ( modifiedEntries )
813 if ( QMessageBox::question(
this,
814 tr(
"Modified names" ),
815 tr(
"Some names were modified and will be overridden. Do you want to continue?" ) )
818 whileBlocking( mUseAliasesForExportedName )->setCheckState( Qt::PartiallyChecked );
823 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
825 mUseAliasesForExportedName->setTristate(
false );
826 const QString alias = mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->data( Qt::UserRole ).toString();
827 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->setText( alias );
831 case Qt::PartiallyChecked:
837void QgsVectorLayerSaveAsDialog::mReplaceRawFieldValues_stateChanged(
int )
839 if ( mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
842 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
843 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
845 if ( mReplaceRawFieldValues->checkState() != Qt::PartiallyChecked )
847 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
849 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->checkState() == Qt::Checked &&
850 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
851 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsEnabled )
853 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( mReplaceRawFieldValues->checkState() );
857 mReplaceRawFieldValues->setTristate(
false );
860void QgsVectorLayerSaveAsDialog::mAttributeTable_itemChanged( QTableWidgetItem *item )
862 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
863 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
865 int row = item->row();
866 int column = item->column();
868 switch (
static_cast<ColumnIndex
>( column ) )
870 case ColumnIndex::Name:
872 if ( mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) ||
873 ! mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) ||
874 !( mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsUserCheckable ) )
877 if ( mAttributeTable->item( row, column )->checkState() == Qt::Unchecked )
879 mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( Qt::Unchecked );
880 mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable );
881 bool checkBoxEnabled =
false;
882 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
884 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
885 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsEnabled )
887 checkBoxEnabled =
true;
891 mReplaceRawFieldValues->setEnabled( checkBoxEnabled );
892 if ( !checkBoxEnabled )
893 mReplaceRawFieldValues->setCheckState( Qt::Unchecked );
895 else if ( mAttributeTable->item( row, column )->checkState() == Qt::Checked )
897 mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsEnabled );
898 mReplaceRawFieldValues->setEnabled(
true );
902 case ColumnIndex::ExportName:
905 if ( item->text().isEmpty() )
907 QMessageBox::warning(
this,
908 tr(
"Empty export name" ),
909 tr(
"Empty export name are not allowed." ) );
915 while ( names.count( item->text() ) > 1 )
916 item->setText( QString(
"%1_2" ).arg( item->text() ) );
918 mUseAliasesForExportedName->setCheckState( Qt::PartiallyChecked );
921 case ColumnIndex::Type:
924 case ColumnIndex::ExportAsDisplayedValue:
926 if ( mAttributeTable->item( row, column )->flags() & Qt::ItemIsUserCheckable )
928 bool allChecked =
true;
929 bool allUnchecked =
true;
930 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
932 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
933 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsEnabled )
935 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->checkState() == Qt::Unchecked )
938 allUnchecked =
false;
941 mReplaceRawFieldValues->setCheckState( ( !allChecked && !allUnchecked ) ? Qt::PartiallyChecked : ( allChecked ) ? Qt::Checked : Qt::Unchecked );
951 mExtentGroupBox->setOutputCrs( mSelectedCrs );
956 return mFilename->filePath();
961 return leLayername->text();
966 return mEncodingComboBox->currentText();
971 return mFormatComboBox->currentData().toString();
987 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
991 switch ( it.value()->type )
996 QSpinBox *sb = mDatasourceOptionsGroupBox->findChild<QSpinBox *>( it.key() );
998 options << QStringLiteral(
"%1=%2" ).arg( it.key() ).arg( sb->value() );
1005 QComboBox *cb = mDatasourceOptionsGroupBox->findChild<QComboBox *>( it.key() );
1006 if ( opt && cb && cb->itemData( cb->currentIndex() ) != opt->
defaultValue )
1007 options << QStringLiteral(
"%1=%2" ).arg( it.key(), cb->currentText() );
1014 QLineEdit *le = mDatasourceOptionsGroupBox->findChild<QLineEdit *>( it.key() );
1016 options << QStringLiteral(
"%1=%2" ).arg( it.key(), le->text() );
1024 if ( !opt->
mValue.isEmpty() )
1025 options << QStringLiteral(
"%1=%2" ).arg( it.key(), opt->
mValue );
1032 QString plainText = mOgrDatasourceOptions->toPlainText().trimmed();
1033 if ( !plainText.isEmpty() )
1034 options += plainText.split(
'\n' );
1041 QStringList options;
1047 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
1051 switch ( it.value()->type )
1056 QSpinBox *sb = mLayerOptionsGroupBox->findChild<QSpinBox *>( it.key() );
1058 options << QStringLiteral(
"%1=%2" ).arg( it.key() ).arg( sb->value() );
1065 QComboBox *cb = mLayerOptionsGroupBox->findChild<QComboBox *>( it.key() );
1066 if ( opt && cb && cb->itemData( cb->currentIndex() ) != opt->
defaultValue )
1067 options << QStringLiteral(
"%1=%2" ).arg( it.key(), cb->currentText() );
1074 QLineEdit *le = mLayerOptionsGroupBox->findChild<QLineEdit *>( it.key() );
1076 options << QStringLiteral(
"%1=%2" ).arg( it.key(), le->text() );
1084 if ( !opt->
mValue.isEmpty() )
1085 options << QStringLiteral(
"%1=%2" ).arg( it.key(), opt->
mValue );
1092 QString plainText = mOgrLayerOptions->toPlainText().trimmed();
1093 if ( !plainText.isEmpty() )
1094 options += plainText.split(
'\n' );
1103 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1105 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->checkState() == Qt::Checked )
1107 attributes.append( i );
1118 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1120 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->checkState() == Qt::Checked &&
1121 ! mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
1122 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->checkState() == Qt::Checked )
1124 attributes.append( i );
1133 QStringList exportNames;
1134 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1135 exportNames.append( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->text() );
1142 return mAddToCanvas->isChecked();
1147 mAddToCanvasStateOnOpenCompatibleDriver = enabled;
1148 if ( mAddToCanvas->isEnabled() )
1149 mAddToCanvas->setChecked( enabled );
1159 return mScaleWidget->scale();
1164 mMapCanvas = canvas;
1165 mScaleWidget->setMapCanvas( canvas );
1166 mScaleWidget->setShowCurrentScaleButton(
true );
1172 return mExtentGroupBox->isChecked();
1177 return mExtentGroupBox->outputExtent();
1187 return mSelectedOnly->isChecked();
1192 return mCheckPersistMetadata->isChecked();
1197 int currentIndexData = mGeometryTypeComboBox->currentData().toInt();
1198 if ( currentIndexData == -1 )
1209 int currentIndexData = mGeometryTypeComboBox->currentData().toInt();
1210 return currentIndexData == -1;
1215 return mForceMultiCheckBox->isChecked();
1220 mForceMultiCheckBox->setChecked( checked );
1225 return mIncludeZCheckBox->isChecked();
1230 return mActionOnExistingFile;
1235 mIncludeZCheckBox->setChecked( checked );
1238void QgsVectorLayerSaveAsDialog::mSymbologyExportComboBox_currentIndexChanged(
const QString &text )
1240 bool scaleEnabled =
true;
1241 if ( text == tr(
"No symbology" ) )
1243 scaleEnabled =
false;
1245 mScaleWidget->setEnabled( scaleEnabled );
1246 mScaleLabel->setEnabled( scaleEnabled );
1249void QgsVectorLayerSaveAsDialog::mGeometryTypeComboBox_currentIndexChanged(
int )
1255 mForceMultiCheckBox->setEnabled(
true );
1256 mIncludeZCheckBox->setEnabled(
true );
1260 mForceMultiCheckBox->setEnabled(
false );
1261 mForceMultiCheckBox->setChecked(
false );
1262 mIncludeZCheckBox->setEnabled(
false );
1263 mIncludeZCheckBox->setChecked(
false );
1267void QgsVectorLayerSaveAsDialog::mSelectAllAttributes_clicked()
1269 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
1270 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
1272 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1274 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->flags() & Qt::ItemIsEnabled )
1276 if ( ! mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
1277 ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsUserCheckable ) )
1279 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsEnabled );
1281 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->setCheckState( Qt::Checked );
1284 if ( ! mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
1286 mReplaceRawFieldValues->setEnabled(
true );
1290void QgsVectorLayerSaveAsDialog::mDeselectAllAttributes_clicked()
1292 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
1293 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
1295 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1297 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->setCheckState( Qt::Unchecked );
1298 if ( ! mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
1299 ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsUserCheckable ) )
1301 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable );
1302 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( Qt::Unchecked );
1305 if ( ! mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
1307 mReplaceRawFieldValues->setCheckState( Qt::Unchecked );
1308 mReplaceRawFieldValues->setEnabled(
false );
1312void QgsVectorLayerSaveAsDialog::showHelp()
1314 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.