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() );
180 mSymbologyExportComboBox->addItem( tr(
"Feature Symbology" ), QVariant::fromValue( Qgis::FeatureSymbologyExport::PerFeature ) );
181 mSymbologyExportComboBox->addItem( tr(
"Symbol Layer Symbology" ), QVariant::fromValue( Qgis::FeatureSymbologyExport::PerSymbolLayer ) );
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 QLabel *label =
new QLabel( it.key() );
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 );
268 cb->addItem( tr(
"<Default>" ), QVariant( QVariant::String ) );
271 idx = cb->findData( QVariant( QVariant::String ) );
272 cb->setCurrentIndex( idx );
284 le->setObjectName( 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 );
312 QgsVectorFileWriter::EditionCapabilities caps =
317 msgBox.setIcon( QMessageBox::Question );
318 msgBox.setWindowTitle( tr(
"Save Vector Layer As" ) );
319 QPushButton *overwriteFileButton = msgBox.addButton( tr(
"Overwrite File" ), QMessageBox::ActionRole );
320 QPushButton *overwriteLayerButton = msgBox.addButton( tr(
"Overwrite Layer" ), QMessageBox::ActionRole );
321 QPushButton *appendToLayerButton = msgBox.addButton( tr(
"Append to Layer" ), QMessageBox::ActionRole );
322 msgBox.setStandardButtons( QMessageBox::Cancel );
323 msgBox.setDefaultButton( QMessageBox::Cancel );
324 overwriteFileButton->hide();
325 overwriteLayerButton->hide();
326 appendToLayerButton->hide();
333 msgBox.setText( tr(
"The layer already exists. Do you want to overwrite the whole file or overwrite the layer?" ) );
334 overwriteFileButton->setVisible(
true );
335 overwriteLayerButton->setVisible(
true );
339 msgBox.setText( tr(
"The file already exists. Do you want to overwrite it?" ) );
340 overwriteFileButton->setVisible(
true );
345 msgBox.setText( tr(
"The layer already exists. Do you want to overwrite the whole file, overwrite the layer or append features to the layer?" ) );
346 appendToLayerButton->setVisible(
true );
347 overwriteFileButton->setVisible(
true );
348 overwriteLayerButton->setVisible(
true );
352 msgBox.setText( tr(
"The layer already exists. Do you want to overwrite the whole file or append features to the layer?" ) );
353 appendToLayerButton->setVisible(
true );
354 overwriteFileButton->setVisible(
true );
357 int ret = msgBox.exec();
358 if ( ret == QMessageBox::Cancel )
360 if ( msgBox.clickedButton() == overwriteFileButton )
362 else if ( msgBox.clickedButton() == overwriteLayerButton )
364 else if ( msgBox.clickedButton() == appendToLayerButton )
376 if ( QMessageBox::question(
this,
377 tr(
"Save Vector Layer As" ),
378 tr(
"The file already exists. Do you want to overwrite it?" ) ) == QMessageBox::NoButton )
391 if ( QMessageBox::question(
this,
392 tr(
"Save Vector Layer As" ),
393 tr(
"The existing layer has additional fields. Do you want to add the missing fields to the layer?" ) ) == QMessageBox::Yes )
402 QStringList layerList;
403 layerList.reserve( sublayers.size() );
406 layerList.append( sublayer.name() );
408 if ( layerList.length() > 1 )
410 layerList.sort( Qt::CaseInsensitive );
412 msgBox.setIcon( QMessageBox::Warning );
413 msgBox.setWindowTitle( tr(
"Overwrite File" ) );
414 msgBox.setText( tr(
"This file contains %1 layers that will be lost!\n" ).arg( QLocale().toString( layerList.length() ) ) );
415 msgBox.setDetailedText( tr(
"The following layers will be permanently lost:\n\n%1" ).arg( layerList.join(
"\n" ) ) );
416 msgBox.setStandardButtons( QMessageBox::Ok | QMessageBox::Cancel );
417 if ( msgBox.exec() == QMessageBox::Cancel )
423 settings.
setValue( QStringLiteral(
"UI/lastVectorFileFilterDir" ), QFileInfo(
fileName() ).absolutePath() );
424 settings.
setValue( QStringLiteral(
"UI/lastVectorFormat" ),
format() );
429void QgsVectorLayerSaveAsDialog::mFormatComboBox_currentIndexChanged(
int idx )
433 mFilename->setEnabled(
true );
438 if ( !mFilename->filePath().isEmpty() )
440 const thread_local QRegularExpression rx(
"\\.(.*?)[\\s]" );
442 if ( !ext.isEmpty() )
444 QFileInfo fi( mFilename->filePath() );
445 mFilename->setFilePath( QStringLiteral(
"%1/%2.%3" ).arg( fi.path(), fi.baseName(), ext ) );
449 bool selectAllFields =
true;
454 bool isFormatForFieldsAsDisplayedValues =
false;
456 const QString sFormat(
format() );
457 if ( sFormat == QLatin1String(
"DXF" ) || sFormat == QLatin1String(
"DGN" ) )
459 mAttributesSelection->setVisible(
false );
460 selectAllFields =
false;
466 mAttributesSelection->setVisible(
true );
467 isFormatForFieldsAsDisplayedValues = ( sFormat == QLatin1String(
"CSV" ) ||
468 sFormat == QLatin1String(
"XLS" ) ||
469 sFormat == QLatin1String(
"XLSX" ) ||
470 sFormat == QLatin1String(
"ODS" ) );
477 mSymbologyExportLabel->setVisible(
true );
478 mSymbologyExportComboBox->setVisible(
true );
479 mScaleLabel->setVisible(
true );
480 mScaleWidget->setVisible(
true );
484 mSymbologyExportLabel->hide();
485 mSymbologyExportComboBox->hide();
487 mScaleWidget->hide();
490 leLayername->setEnabled( sFormat == QLatin1String(
"KML" ) ||
491 sFormat == QLatin1String(
"GPKG" ) ||
492 sFormat == QLatin1String(
"XLSX" ) ||
493 sFormat == QLatin1String(
"ODS" ) ||
494 sFormat == QLatin1String(
"FileGDB" ) ||
495 sFormat == QLatin1String(
"OpenFileGDB" ) ||
496 sFormat == QLatin1String(
"SQLite" ) ||
497 sFormat == QLatin1String(
"SpatiaLite" ) );
499 if ( sFormat == QLatin1String(
"XLSX" ) )
500 leLayername->setMaxLength( 31 );
501 else if ( leLayername->isEnabled() )
502 leLayername->setMaxLength( 32767 );
504 if ( !leLayername->isEnabled() )
505 leLayername->setText( QString() );
506 else if ( leLayername->text().isEmpty() )
508 QString
layerName = mDefaultOutputLayerNameFromInputLayerName;
509 if (
layerName.isEmpty() && !mFilename->filePath().isEmpty() )
511 layerName = QFileInfo( mFilename->filePath() ).baseName();
512 leLayername->setDefaultValue(
layerName );
521 mAttributeTable->setRowCount( mLayer->
fields().
count() );
523 QStringList horizontalHeaders = QStringList() << tr(
"Name" ) << tr(
"Export name" ) << tr(
"Type" ) << tr(
"Replace with displayed values" );
524 mAttributeTable->setColumnCount( horizontalHeaders.size() );
525 mAttributeTable->setHorizontalHeaderLabels( horizontalHeaders );
527 bool foundFieldThatCanBeExportedAsDisplayedValue =
false;
528 for (
int i = 0; i < mLayer->
fields().size(); ++i )
531 if ( setup.
type() != QLatin1String(
"TextEdit" ) &&
534 foundFieldThatCanBeExportedAsDisplayedValue =
true;
538 mAttributeTable->setColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ),
539 ! foundFieldThatCanBeExportedAsDisplayedValue );
541 bool checkReplaceRawFieldValues = selectAllFields && isFormatForFieldsAsDisplayedValues;
542 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
544 for (
int i = 0; i < mLayer->
fields().size(); ++i )
547 Qt::ItemFlags flags = mLayer->
providerType() != QLatin1String(
"oracle" ) || !fld.
typeName().contains( QLatin1String(
"SDO_GEOMETRY" ) ) ? Qt::ItemIsEnabled : Qt::NoItemFlags;
548 QTableWidgetItem *item =
nullptr;
549 item =
new QTableWidgetItem( fld.
name() );
550 item->setFlags( flags | Qt::ItemIsUserCheckable );
551 item->setCheckState( ( selectAllFields ) ? Qt::Checked : Qt::Unchecked );
552 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::Name ), item );
554 item =
new QTableWidgetItem( fld.
name() );
555 item->setFlags( flags | Qt::ItemIsEditable );
557 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::ExportName ), item );
559 item =
new QTableWidgetItem( fld.
typeName() );
560 item->setFlags( flags );
561 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::Type ), item );
563 if ( foundFieldThatCanBeExportedAsDisplayedValue )
567 const QString widgetId( setup.
type() );
568 if ( flags == Qt::ItemIsEnabled &&
569 widgetId != QLatin1String(
"TextEdit" ) &&
572 item =
new QTableWidgetItem( tr(
"Use %1" ).arg( factory->
name() ) );
573 item->setFlags( ( selectAllFields ) ? ( Qt::ItemIsEnabled | Qt::ItemIsUserCheckable ) : Qt::ItemIsUserCheckable );
574 const bool checkItem = ( selectAllFields && isFormatForFieldsAsDisplayedValues &&
575 ( widgetId == QLatin1String(
"ValueMap" ) ||
576 widgetId == QLatin1String(
"ValueRelation" ) ||
577 widgetId == QLatin1String(
"CheckBox" ) ||
578 widgetId == QLatin1String(
"RelationReference" ) ) );
579 checkReplaceRawFieldValues &= checkItem;
580 item->setCheckState( checkItem ?
581 Qt::Checked : Qt::Unchecked );
582 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ), item );
586 item =
new QTableWidgetItem();
587 item->setFlags( Qt::NoItemFlags );
588 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ), item );
594 whileBlocking( mReplaceRawFieldValues )->setChecked( checkReplaceRawFieldValues );
595 mReplaceRawFieldValues->setEnabled( selectAllFields );
596 mReplaceRawFieldValues->setVisible( foundFieldThatCanBeExportedAsDisplayedValue );
598 mAttributeTable->resizeColumnsToContents();
603 while ( mDatasourceOptionsGroupBox->layout()->count() )
605 QLayoutItem *item = mDatasourceOptionsGroupBox->layout()->takeAt( 0 );
606 delete item->widget();
610 while ( mLayerOptionsGroupBox->layout()->count() )
612 QLayoutItem *item = mLayerOptionsGroupBox->layout()->takeAt( 0 );
613 delete item->widget();
617 typedef QPair<QLabel *, QWidget *> LabelControlPair;
623 mDatasourceOptionsGroupBox->setVisible(
true );
624 QList<QPair<QLabel *, QWidget *> > controls = createControls( driverMetaData.
driverOptions );
626 QFormLayout *datasourceLayout =
dynamic_cast<QFormLayout *
>( mDatasourceOptionsGroupBox->layout() );
628 const auto constControls = controls;
629 for ( LabelControlPair control : constControls )
631 datasourceLayout->addRow( control.first, control.second );
636 mDatasourceOptionsGroupBox->setVisible(
false );
641 mLayerOptionsGroupBox->setVisible(
true );
642 QList<QPair<QLabel *, QWidget *> > controls = createControls( driverMetaData.
layerOptions );
644 QFormLayout *layerOptionsLayout =
dynamic_cast<QFormLayout *
>( mLayerOptionsGroupBox->layout() );
646 const auto constControls = controls;
647 for ( LabelControlPair control : constControls )
649 layerOptionsLayout->addRow( control.first, control.second );
654 mLayerOptionsGroupBox->setVisible(
false );
659 mEncodingComboBox->setEnabled(
true );
666 mEncodingComboBox->setCurrentIndex( idx );
667 mEncodingComboBox->setDisabled(
true );
671 mEncodingComboBox->setEnabled(
true );
678 mEncodingComboBox->setEnabled(
true );
681 GDALDriverH hDriver = GDALGetDriverByName(
format().toUtf8().constData() );
684 mAddToCanvas->setEnabled( GDALGetMetadataItem( hDriver, GDAL_DCAP_OPEN,
nullptr ) !=
nullptr );
688void QgsVectorLayerSaveAsDialog::mUseAliasesForExportedName_stateChanged(
int state )
690 const QSignalBlocker signalBlocker( mAttributeTable );
697 bool modifiedEntries =
false;
698 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
700 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->text()
701 != mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->data( Qt::UserRole ).toString() )
703 modifiedEntries =
true;
708 if ( modifiedEntries )
710 if ( QMessageBox::question(
this,
711 tr(
"Modified names" ),
712 tr(
"Some names were modified and will be overridden. Do you want to continue?" ) )
715 whileBlocking( mUseAliasesForExportedName )->setCheckState( Qt::PartiallyChecked );
720 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
722 mUseAliasesForExportedName->setTristate(
false );
723 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->setText( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->text() );
730 bool modifiedEntries =
false;
731 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
733 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->text()
734 != mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->text() )
735 modifiedEntries =
true;
738 if ( modifiedEntries )
740 if ( QMessageBox::question(
this,
741 tr(
"Modified names" ),
742 tr(
"Some names were modified and will be overridden. Do you want to continue?" ) )
745 whileBlocking( mUseAliasesForExportedName )->setCheckState( Qt::PartiallyChecked );
750 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
752 mUseAliasesForExportedName->setTristate(
false );
753 const QString alias = mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->data( Qt::UserRole ).toString();
754 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->setText( alias );
758 case Qt::PartiallyChecked:
764void QgsVectorLayerSaveAsDialog::mReplaceRawFieldValues_stateChanged(
int )
766 if ( mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
769 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
770 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
772 if ( mReplaceRawFieldValues->checkState() != Qt::PartiallyChecked )
774 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
776 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->checkState() == Qt::Checked &&
777 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
778 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsEnabled )
780 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( mReplaceRawFieldValues->checkState() );
784 mReplaceRawFieldValues->setTristate(
false );
787void QgsVectorLayerSaveAsDialog::mAttributeTable_itemChanged( QTableWidgetItem *item )
789 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
790 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
792 int row = item->row();
793 int column = item->column();
795 switch (
static_cast<ColumnIndex
>( column ) )
797 case ColumnIndex::Name:
799 if ( mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) ||
800 ! mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) ||
801 !( mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsUserCheckable ) )
804 if ( mAttributeTable->item( row, column )->checkState() == Qt::Unchecked )
806 mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( Qt::Unchecked );
807 mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable );
808 bool checkBoxEnabled =
false;
809 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
811 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
812 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsEnabled )
814 checkBoxEnabled =
true;
818 mReplaceRawFieldValues->setEnabled( checkBoxEnabled );
819 if ( !checkBoxEnabled )
820 mReplaceRawFieldValues->setCheckState( Qt::Unchecked );
822 else if ( mAttributeTable->item( row, column )->checkState() == Qt::Checked )
824 mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsEnabled );
825 mReplaceRawFieldValues->setEnabled(
true );
829 case ColumnIndex::ExportName:
832 if ( item->text().isEmpty() )
834 QMessageBox::warning(
this,
835 tr(
"Empty export name" ),
836 tr(
"Empty export name are not allowed." ) );
842 while ( names.count( item->text() ) > 1 )
843 item->setText( QString(
"%1_2" ).arg( item->text() ) );
845 mUseAliasesForExportedName->setCheckState( Qt::PartiallyChecked );
848 case ColumnIndex::Type:
851 case ColumnIndex::ExportAsDisplayedValue:
853 if ( mAttributeTable->item( row, column )->flags() & Qt::ItemIsUserCheckable )
855 bool allChecked =
true;
856 bool allUnchecked =
true;
857 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
859 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
860 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsEnabled )
862 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->checkState() == Qt::Unchecked )
865 allUnchecked =
false;
868 mReplaceRawFieldValues->setCheckState( ( !allChecked && !allUnchecked ) ? Qt::PartiallyChecked : ( allChecked ) ? Qt::Checked : Qt::Unchecked );
878 mExtentGroupBox->setOutputCrs( mSelectedCrs );
883 return mFilename->filePath();
888 return leLayername->text();
893 return mEncodingComboBox->currentText();
898 return mFormatComboBox->currentData().toString();
914 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
918 switch ( it.value()->type )
923 QSpinBox *sb = mDatasourceOptionsGroupBox->findChild<QSpinBox *>( it.key() );
925 options << QStringLiteral(
"%1=%2" ).arg( it.key() ).arg( sb->value() );
932 QComboBox *cb = mDatasourceOptionsGroupBox->findChild<QComboBox *>( it.key() );
933 if ( opt && cb && cb->itemData( cb->currentIndex() ) != opt->
defaultValue )
934 options << QStringLiteral(
"%1=%2" ).arg( it.key(), cb->currentText() );
941 QLineEdit *le = mDatasourceOptionsGroupBox->findChild<QLineEdit *>( it.key() );
943 options << QStringLiteral(
"%1=%2" ).arg( it.key(), le->text() );
951 options << QStringLiteral(
"%1=%2" ).arg( it.key(), opt->
mValue );
958 QString plainText = mOgrDatasourceOptions->toPlainText().trimmed();
959 if ( !plainText.isEmpty() )
960 options += plainText.split(
'\n' );
973 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
977 switch ( it.value()->type )
982 QSpinBox *sb = mLayerOptionsGroupBox->findChild<QSpinBox *>( it.key() );
984 options << QStringLiteral(
"%1=%2" ).arg( it.key() ).arg( sb->value() );
991 QComboBox *cb = mLayerOptionsGroupBox->findChild<QComboBox *>( it.key() );
992 if ( opt && cb && cb->itemData( cb->currentIndex() ) != opt->
defaultValue )
993 options << QStringLiteral(
"%1=%2" ).arg( it.key(), cb->currentText() );
1000 QLineEdit *le = mLayerOptionsGroupBox->findChild<QLineEdit *>( it.key() );
1002 options << QStringLiteral(
"%1=%2" ).arg( it.key(), le->text() );
1010 options << QStringLiteral(
"%1=%2" ).arg( it.key(), opt->
mValue );
1017 QString plainText = mOgrLayerOptions->toPlainText().trimmed();
1018 if ( !plainText.isEmpty() )
1019 options += plainText.split(
'\n' );
1028 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1030 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->checkState() == Qt::Checked )
1032 attributes.append( i );
1043 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1045 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->checkState() == Qt::Checked &&
1046 ! mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
1047 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->checkState() == Qt::Checked )
1049 attributes.append( i );
1058 QStringList exportNames;
1059 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1060 exportNames.append( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->text() );
1067 return mAddToCanvas->isChecked() && mAddToCanvas->isEnabled();
1072 mAddToCanvas->setChecked( enabled );
1082 return mScaleWidget->scale();
1087 mMapCanvas = canvas;
1088 mScaleWidget->setMapCanvas( canvas );
1089 mScaleWidget->setShowCurrentScaleButton(
true );
1095 return mExtentGroupBox->isChecked();
1100 return mExtentGroupBox->outputExtent();
1110 return mSelectedOnly->isChecked();
1115 return mCheckPersistMetadata->isChecked();
1120 int currentIndexData = mGeometryTypeComboBox->currentData().toInt();
1121 if ( currentIndexData == -1 )
1132 int currentIndexData = mGeometryTypeComboBox->currentData().toInt();
1133 return currentIndexData == -1;
1138 return mForceMultiCheckBox->isChecked();
1143 mForceMultiCheckBox->setChecked( checked );
1148 return mIncludeZCheckBox->isChecked();
1153 return mActionOnExistingFile;
1158 mIncludeZCheckBox->setChecked( checked );
1161void QgsVectorLayerSaveAsDialog::mSymbologyExportComboBox_currentIndexChanged(
const QString &text )
1163 bool scaleEnabled =
true;
1164 if ( text == tr(
"No symbology" ) )
1166 scaleEnabled =
false;
1168 mScaleWidget->setEnabled( scaleEnabled );
1169 mScaleLabel->setEnabled( scaleEnabled );
1172void QgsVectorLayerSaveAsDialog::mGeometryTypeComboBox_currentIndexChanged(
int )
1178 mForceMultiCheckBox->setEnabled(
true );
1179 mIncludeZCheckBox->setEnabled(
true );
1183 mForceMultiCheckBox->setEnabled(
false );
1184 mForceMultiCheckBox->setChecked(
false );
1185 mIncludeZCheckBox->setEnabled(
false );
1186 mIncludeZCheckBox->setChecked(
false );
1190void QgsVectorLayerSaveAsDialog::mSelectAllAttributes_clicked()
1192 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
1193 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
1195 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1197 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->flags() & Qt::ItemIsEnabled )
1199 if ( ! mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
1200 ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsUserCheckable ) )
1202 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsEnabled );
1204 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->setCheckState( Qt::Checked );
1207 if ( ! mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
1209 mReplaceRawFieldValues->setEnabled(
true );
1213void QgsVectorLayerSaveAsDialog::mDeselectAllAttributes_clicked()
1215 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
1216 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
1218 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1220 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->setCheckState( Qt::Unchecked );
1221 if ( ! mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
1222 ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsUserCheckable ) )
1224 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable );
1225 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( Qt::Unchecked );
1228 if ( ! mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
1230 mReplaceRawFieldValues->setCheckState( Qt::Unchecked );
1231 mReplaceRawFieldValues->setEnabled(
false );
1235void QgsVectorLayerSaveAsDialog::showHelp()
1237 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.
@ NoSymbology
Export only data.
This class represents a coordinate reference system (CRS).
QgsDatumEnsemble datumEnsemble() const SIP_THROW(QgsNotSupportedException)
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 count() 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 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.
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
Combination of CanAddNewLayer, CanAppendToExistingLayer, CanAddNewFieldsToExistingLayer or CanDeleteL...
@ 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())
Available dialog options.
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.
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.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
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) SIP_HOLDGIL
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.