33#include <QRegularExpression>
42 : QDialog( parent, fl )
50 : QDialog( parent, fl )
57 mSelectedCrs = layer->
crs();
58 mLayerExtent = layer->
extent();
65 leLayername->setDefaultValue( mDefaultOutputLayerNameFromInputLayerName );
67 if ( leLayername->isEnabled() )
68 leLayername->setText( mDefaultOutputLayerNameFromInputLayerName );
73 mSymbologyExportLabel->hide();
74 mSymbologyExportComboBox->hide();
85 mAttributesSelection->hide();
88 mSelectedOnly->hide();
94 mGeometryGroupBox->hide();
97 mExtentGroupBox->hide();
101 mCheckPersistMetadata->setChecked(
false );
102 mCheckPersistMetadata->hide();
106 mButtonBox->button( QDialogButtonBox::Ok )->setDisabled(
true );
109void QgsVectorLayerSaveAsDialog::setup()
114 connect( mFormatComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsVectorLayerSaveAsDialog::mFormatComboBox_currentIndexChanged );
116 connect( mSymbologyExportComboBox, &QComboBox::currentTextChanged,
this, &QgsVectorLayerSaveAsDialog::mSymbologyExportComboBox_currentIndexChanged );
117 connect( mGeometryTypeComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsVectorLayerSaveAsDialog::mGeometryTypeComboBox_currentIndexChanged );
118 connect( mSelectAllAttributes, &QPushButton::clicked,
this, &QgsVectorLayerSaveAsDialog::mSelectAllAttributes_clicked );
119 connect( mDeselectAllAttributes, &QPushButton::clicked,
this, &QgsVectorLayerSaveAsDialog::mDeselectAllAttributes_clicked );
120 connect( mUseAliasesForExportedName, &QCheckBox::stateChanged,
this, &QgsVectorLayerSaveAsDialog::mUseAliasesForExportedName_stateChanged );
121 connect( mReplaceRawFieldValues, &QCheckBox::stateChanged,
this, &QgsVectorLayerSaveAsDialog::mReplaceRawFieldValues_stateChanged );
122 connect( mAttributeTable, &QTableWidget::itemChanged,
this, &QgsVectorLayerSaveAsDialog::mAttributeTable_itemChanged );
125 mHelpButtonBox->setVisible(
false );
126 mButtonBox->addButton( QDialogButtonBox::Help );
127 connect( mButtonBox, &QDialogButtonBox::helpRequested,
this, &QgsVectorLayerSaveAsDialog::showHelp );
129 connect( mHelpButtonBox, &QDialogButtonBox::helpRequested,
this, &QgsVectorLayerSaveAsDialog::showHelp );
132 connect( mButtonBox, &QDialogButtonBox::rejected,
this, &QgsVectorLayerSaveAsDialog::reject );
135 mFormatComboBox->blockSignals(
true );
138 mFormatComboBox->addItem( driver.longName, driver.driverName );
142 QString
format = settings.
value( QStringLiteral(
"UI/lastVectorFormat" ),
"GPKG" ).toString();
143 mFormatComboBox->setCurrentIndex( mFormatComboBox->findData(
format ) );
144 mFormatComboBox->blockSignals(
false );
152 mGeometryTypeComboBox->addItem( tr(
"Automatic" ), -1 );
158 mGeometryTypeComboBox->setCurrentIndex( mGeometryTypeComboBox->findData( -1 ) );
162 QString enc = settings.
value( QStringLiteral(
"UI/encoding" ),
"System" ).toString();
163 int idx = mEncodingComboBox->findText( enc );
166 mEncodingComboBox->insertItem( 0, enc );
170 mCrsSelector->setCrs( mSelectedCrs );
171 mCrsSelector->setLayerCrs( mSelectedCrs );
172 mCrsSelector->setMessage( tr(
"Select the coordinate reference system for the vector file. "
173 "The data points will be transformed from the layer coordinate reference system." ) );
175 mEncodingComboBox->setCurrentIndex( idx );
176 mFormatComboBox_currentIndexChanged( mFormatComboBox->currentIndex() );
182 mSymbologyExportComboBox_currentIndexChanged( mSymbologyExportComboBox->currentText() );
185 mExtentGroupBox->setOutputCrs( mSelectedCrs );
186 mExtentGroupBox->setOriginalExtent( mLayerExtent, mSelectedCrs );
187 mExtentGroupBox->setOutputExtentFromOriginal();
188 mExtentGroupBox->setCheckable(
true );
189 mExtentGroupBox->setChecked(
false );
190 mExtentGroupBox->setCollapsed(
true );
193 mFilename->setDialogTitle( tr(
"Save Layer As" ) );
194 mFilename->setDefaultRoot( settings.
value( QStringLiteral(
"UI/lastVectorFileFilterDir" ), QDir::homePath() ).toString() );
195 mFilename->setConfirmOverwrite(
false );
199 QFileInfo tmplFileInfo( filePath );
200 settings.
setValue( QStringLiteral(
"UI/lastVectorFileFilterDir" ), tmplFileInfo.absolutePath() );
202 const QFileInfo fileInfo( filePath );
204 if ( mDefaultOutputLayerNameFromInputLayerName.isEmpty() )
205 leLayername->setDefaultValue( suggestedLayerName );
208 if ( leLayername->text().isEmpty() && !filePath.isEmpty() && leLayername->isEnabled() )
210 leLayername->setText( suggestedLayerName );
212 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( !filePath.isEmpty() );
220 mCrsSelector->setSourceEnsemble( ensemble.
name() );
227 mCrsSelector->setShowAccuracyWarnings(
true );
230QList<QPair<QLabel *, QWidget *> > QgsVectorLayerSaveAsDialog::createControls(
const QMap<QString, QgsVectorFileWriter::Option *> &options )
232 QList<QPair<QLabel *, QWidget *> > controls;
233 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
235 for ( it = options.constBegin(); it != options.constEnd(); ++it )
238 QWidget *control =
nullptr;
239 switch ( option->
type )
246 QSpinBox *sb =
new QSpinBox();
247 sb->setObjectName( it.key() );
248 sb->setMaximum( std::numeric_limits<int>::max() );
260 QComboBox *cb =
new QComboBox();
261 cb->setObjectName( it.key() );
262 for (
const QString &val : std::as_const( opt->values ) )
264 cb->addItem( val, val );
267 cb->addItem( tr(
"<Default>" ), QVariant( QVariant::String ) );
270 idx = cb->findData( QVariant( QVariant::String ) );
271 cb->setCurrentIndex( idx );
283 le->setObjectName( it.key() );
296 QLabel *label =
new QLabel( it.key() );
299 label->setToolTip( QStringLiteral(
"<p>%1</p>" ).arg( option->
docString.toHtmlEscaped() ) );
300 control->setToolTip( QStringLiteral(
"<p>%1</p>" ).arg( option->
docString.toHtmlEscaped() ) );
302 controls << QPair<QLabel *, QWidget *>( label, control );
313 QgsVectorFileWriter::EditionCapabilities caps =
318 msgBox.setIcon( QMessageBox::Question );
319 msgBox.setWindowTitle( tr(
"Save Vector Layer As" ) );
320 QPushButton *overwriteFileButton = msgBox.addButton( tr(
"Overwrite File" ), QMessageBox::ActionRole );
321 QPushButton *overwriteLayerButton = msgBox.addButton( tr(
"Overwrite Layer" ), QMessageBox::ActionRole );
322 QPushButton *appendToLayerButton = msgBox.addButton( tr(
"Append to Layer" ), QMessageBox::ActionRole );
323 msgBox.setStandardButtons( QMessageBox::Cancel );
324 msgBox.setDefaultButton( QMessageBox::Cancel );
325 overwriteFileButton->hide();
326 overwriteLayerButton->hide();
327 appendToLayerButton->hide();
334 msgBox.setText( tr(
"The layer already exists. Do you want to overwrite the whole file or overwrite the layer?" ) );
335 overwriteFileButton->setVisible(
true );
336 overwriteLayerButton->setVisible(
true );
340 msgBox.setText( tr(
"The file already exists. Do you want to overwrite it?" ) );
341 overwriteFileButton->setVisible(
true );
346 msgBox.setText( tr(
"The layer already exists. Do you want to overwrite the whole file, overwrite the layer or append features to the layer?" ) );
347 appendToLayerButton->setVisible(
true );
348 overwriteFileButton->setVisible(
true );
349 overwriteLayerButton->setVisible(
true );
353 msgBox.setText( tr(
"The layer already exists. Do you want to overwrite the whole file or append features to the layer?" ) );
354 appendToLayerButton->setVisible(
true );
355 overwriteFileButton->setVisible(
true );
358 int ret = msgBox.exec();
359 if ( ret == QMessageBox::Cancel )
361 if ( msgBox.clickedButton() == overwriteFileButton )
363 else if ( msgBox.clickedButton() == overwriteLayerButton )
365 else if ( msgBox.clickedButton() == appendToLayerButton )
377 if ( QMessageBox::question(
this,
378 tr(
"Save Vector Layer As" ),
379 tr(
"The file already exists. Do you want to overwrite it?" ) ) == QMessageBox::NoButton )
392 if ( QMessageBox::question(
this,
393 tr(
"Save Vector Layer As" ),
394 tr(
"The existing layer has additional fields. Do you want to add the missing fields to the layer?" ) ) == QMessageBox::Yes )
403 QStringList layerList;
404 layerList.reserve( sublayers.size() );
407 layerList.append( sublayer.name() );
409 if ( layerList.length() > 1 )
411 layerList.sort( Qt::CaseInsensitive );
413 msgBox.setIcon( QMessageBox::Warning );
414 msgBox.setWindowTitle( tr(
"Overwrite File" ) );
415 msgBox.setText( tr(
"This file contains %1 layers that will be lost!\n" ).arg( QLocale().toString( layerList.length() ) ) );
416 msgBox.setDetailedText( tr(
"The following layers will be permanently lost:\n\n%1" ).arg( layerList.join(
"\n" ) ) );
417 msgBox.setStandardButtons( QMessageBox::Ok | QMessageBox::Cancel );
418 if ( msgBox.exec() == QMessageBox::Cancel )
424 settings.
setValue( QStringLiteral(
"UI/lastVectorFileFilterDir" ), QFileInfo(
fileName() ).absolutePath() );
425 settings.
setValue( QStringLiteral(
"UI/lastVectorFormat" ),
format() );
430void QgsVectorLayerSaveAsDialog::mFormatComboBox_currentIndexChanged(
int idx )
434 mFilename->setEnabled(
true );
442 if (
format() == QLatin1String(
"OpenFileGDB" ) ||
format() == QLatin1String(
"FileGDB" ) )
443 filter = QStringLiteral(
"%1 (*.gdb *.GDB gdb)" ).arg( tr(
"ESRI File Geodatabase" ) );
444 mFilename->setFilter( filter );
448 if ( !mFilename->filePath().isEmpty() )
450 const thread_local QRegularExpression rx(
"\\.(.*?)[\\s]" );
451 const QString ext = rx.match( filter ).captured( 1 );
452 if ( !ext.isEmpty() )
454 QFileInfo fi( mFilename->filePath() );
455 mFilename->setFilePath( QStringLiteral(
"%1/%2.%3" ).arg( fi.path(), fi.baseName(), ext ) );
459 bool selectAllFields =
true;
464 bool isFormatForFieldsAsDisplayedValues =
false;
466 const QString sFormat(
format() );
467 if ( sFormat == QLatin1String(
"DXF" ) || sFormat == QLatin1String(
"DGN" ) )
469 mAttributesSelection->setVisible(
false );
470 selectAllFields =
false;
476 mAttributesSelection->setVisible(
true );
477 isFormatForFieldsAsDisplayedValues = ( sFormat == QLatin1String(
"CSV" ) ||
478 sFormat == QLatin1String(
"XLS" ) ||
479 sFormat == QLatin1String(
"XLSX" ) ||
480 sFormat == QLatin1String(
"ODS" ) );
487 mSymbologyExportLabel->setVisible(
true );
488 mSymbologyExportComboBox->setVisible(
true );
489 mScaleLabel->setVisible(
true );
490 mScaleWidget->setVisible(
true );
494 mSymbologyExportLabel->hide();
495 mSymbologyExportComboBox->hide();
497 mScaleWidget->hide();
500 leLayername->setEnabled( sFormat == QLatin1String(
"KML" ) ||
501 sFormat == QLatin1String(
"GPKG" ) ||
502 sFormat == QLatin1String(
"XLSX" ) ||
503 sFormat == QLatin1String(
"ODS" ) ||
504 sFormat == QLatin1String(
"FileGDB" ) ||
505 sFormat == QLatin1String(
"OpenFileGDB" ) ||
506 sFormat == QLatin1String(
"SQLite" ) ||
507 sFormat == QLatin1String(
"SpatiaLite" ) );
509 if ( sFormat == QLatin1String(
"XLSX" ) )
510 leLayername->setMaxLength( 31 );
511 else if ( leLayername->isEnabled() )
512 leLayername->setMaxLength( 32767 );
514 if ( !leLayername->isEnabled() )
515 leLayername->setText( QString() );
516 else if ( leLayername->text().isEmpty() )
518 QString
layerName = mDefaultOutputLayerNameFromInputLayerName;
519 if (
layerName.isEmpty() && !mFilename->filePath().isEmpty() )
521 layerName = QFileInfo( mFilename->filePath() ).baseName();
522 leLayername->setDefaultValue(
layerName );
531 mAttributeTable->setRowCount( mLayer->
fields().
count() );
533 QStringList horizontalHeaders = QStringList() << tr(
"Name" ) << tr(
"Export name" ) << tr(
"Type" ) << tr(
"Replace with displayed values" );
534 mAttributeTable->setColumnCount( horizontalHeaders.size() );
535 mAttributeTable->setHorizontalHeaderLabels( horizontalHeaders );
537 bool foundFieldThatCanBeExportedAsDisplayedValue =
false;
538 for (
int i = 0; i < mLayer->
fields().size(); ++i )
541 if ( setup.
type() != QLatin1String(
"TextEdit" ) &&
544 foundFieldThatCanBeExportedAsDisplayedValue =
true;
548 mAttributeTable->setColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ),
549 ! foundFieldThatCanBeExportedAsDisplayedValue );
551 bool checkReplaceRawFieldValues = selectAllFields && isFormatForFieldsAsDisplayedValues;
552 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
554 for (
int i = 0; i < mLayer->
fields().size(); ++i )
557 Qt::ItemFlags flags = mLayer->
providerType() != QLatin1String(
"oracle" ) || !fld.
typeName().contains( QLatin1String(
"SDO_GEOMETRY" ) ) ? Qt::ItemIsEnabled : Qt::NoItemFlags;
558 QTableWidgetItem *item =
nullptr;
559 item =
new QTableWidgetItem( fld.
name() );
560 item->setFlags( flags | Qt::ItemIsUserCheckable );
561 item->setCheckState( ( selectAllFields ) ? Qt::Checked : Qt::Unchecked );
562 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::Name ), item );
564 item =
new QTableWidgetItem( fld.
name() );
565 item->setFlags( flags | Qt::ItemIsEditable );
567 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::ExportName ), item );
569 item =
new QTableWidgetItem( fld.
typeName() );
570 item->setFlags( flags );
571 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::Type ), item );
573 if ( foundFieldThatCanBeExportedAsDisplayedValue )
577 const QString widgetId( setup.
type() );
578 if ( flags == Qt::ItemIsEnabled &&
579 widgetId != QLatin1String(
"TextEdit" ) &&
582 item =
new QTableWidgetItem( tr(
"Use %1" ).arg( factory->
name() ) );
583 item->setFlags( ( selectAllFields ) ? ( Qt::ItemIsEnabled | Qt::ItemIsUserCheckable ) : Qt::ItemIsUserCheckable );
584 const bool checkItem = ( selectAllFields && isFormatForFieldsAsDisplayedValues &&
585 ( widgetId == QLatin1String(
"ValueMap" ) ||
586 widgetId == QLatin1String(
"ValueRelation" ) ||
587 widgetId == QLatin1String(
"CheckBox" ) ||
588 widgetId == QLatin1String(
"RelationReference" ) ) );
589 checkReplaceRawFieldValues &= checkItem;
590 item->setCheckState( checkItem ?
591 Qt::Checked : Qt::Unchecked );
592 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ), item );
596 item =
new QTableWidgetItem();
597 item->setFlags( Qt::NoItemFlags );
598 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ), item );
604 whileBlocking( mReplaceRawFieldValues )->setChecked( checkReplaceRawFieldValues );
605 mReplaceRawFieldValues->setEnabled( selectAllFields );
606 mReplaceRawFieldValues->setVisible( foundFieldThatCanBeExportedAsDisplayedValue );
608 mAttributeTable->resizeColumnsToContents();
613 while ( mDatasourceOptionsGroupBox->layout()->count() )
615 QLayoutItem *item = mDatasourceOptionsGroupBox->layout()->takeAt( 0 );
616 delete item->widget();
620 while ( mLayerOptionsGroupBox->layout()->count() )
622 QLayoutItem *item = mLayerOptionsGroupBox->layout()->takeAt( 0 );
623 delete item->widget();
627 typedef QPair<QLabel *, QWidget *> LabelControlPair;
633 mDatasourceOptionsGroupBox->setVisible(
true );
634 QList<QPair<QLabel *, QWidget *> > controls = createControls( driverMetaData.
driverOptions );
636 QFormLayout *datasourceLayout =
dynamic_cast<QFormLayout *
>( mDatasourceOptionsGroupBox->layout() );
638 const auto constControls = controls;
639 for ( LabelControlPair control : constControls )
641 datasourceLayout->addRow( control.first, control.second );
646 mDatasourceOptionsGroupBox->setVisible(
false );
651 mLayerOptionsGroupBox->setVisible(
true );
652 QList<QPair<QLabel *, QWidget *> > controls = createControls( driverMetaData.
layerOptions );
654 QFormLayout *layerOptionsLayout =
dynamic_cast<QFormLayout *
>( mLayerOptionsGroupBox->layout() );
656 const auto constControls = controls;
657 for ( LabelControlPair control : constControls )
659 layerOptionsLayout->addRow( control.first, control.second );
664 mLayerOptionsGroupBox->setVisible(
false );
669 mEncodingComboBox->setEnabled(
true );
676 mEncodingComboBox->setCurrentIndex( idx );
677 mEncodingComboBox->setDisabled(
true );
681 mEncodingComboBox->setEnabled(
true );
688 mEncodingComboBox->setEnabled(
true );
691 GDALDriverH hDriver = GDALGetDriverByName(
format().toUtf8().constData() );
694 const bool canReopen = GDALGetMetadataItem( hDriver, GDAL_DCAP_OPEN,
nullptr ) !=
nullptr;
695 if ( mAddToCanvas->isEnabled() && !canReopen )
697 mAddToCanvasStateOnOpenCompatibleDriver = mAddToCanvas->isChecked();
698 mAddToCanvas->setChecked(
false );
699 mAddToCanvas->setEnabled(
false );
701 else if ( !mAddToCanvas->isEnabled() && canReopen )
703 mAddToCanvas->setChecked( mAddToCanvasStateOnOpenCompatibleDriver );
704 mAddToCanvas->setEnabled(
true );
709void QgsVectorLayerSaveAsDialog::mUseAliasesForExportedName_stateChanged(
int state )
711 const QSignalBlocker signalBlocker( mAttributeTable );
718 bool modifiedEntries =
false;
719 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
721 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->text()
722 != mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->data( Qt::UserRole ).toString() )
724 modifiedEntries =
true;
729 if ( modifiedEntries )
731 if ( QMessageBox::question(
this,
732 tr(
"Modified names" ),
733 tr(
"Some names were modified and will be overridden. Do you want to continue?" ) )
736 whileBlocking( mUseAliasesForExportedName )->setCheckState( Qt::PartiallyChecked );
741 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
743 mUseAliasesForExportedName->setTristate(
false );
744 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->setText( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->text() );
751 bool modifiedEntries =
false;
752 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
754 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->text()
755 != mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->text() )
756 modifiedEntries =
true;
759 if ( modifiedEntries )
761 if ( QMessageBox::question(
this,
762 tr(
"Modified names" ),
763 tr(
"Some names were modified and will be overridden. Do you want to continue?" ) )
766 whileBlocking( mUseAliasesForExportedName )->setCheckState( Qt::PartiallyChecked );
771 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
773 mUseAliasesForExportedName->setTristate(
false );
774 const QString alias = mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->data( Qt::UserRole ).toString();
775 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->setText( alias );
779 case Qt::PartiallyChecked:
785void QgsVectorLayerSaveAsDialog::mReplaceRawFieldValues_stateChanged(
int )
787 if ( mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
790 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
791 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
793 if ( mReplaceRawFieldValues->checkState() != Qt::PartiallyChecked )
795 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
797 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->checkState() == Qt::Checked &&
798 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
799 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsEnabled )
801 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( mReplaceRawFieldValues->checkState() );
805 mReplaceRawFieldValues->setTristate(
false );
808void QgsVectorLayerSaveAsDialog::mAttributeTable_itemChanged( QTableWidgetItem *item )
810 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
811 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
813 int row = item->row();
814 int column = item->column();
816 switch (
static_cast<ColumnIndex
>( column ) )
818 case ColumnIndex::Name:
820 if ( mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) ||
821 ! mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) ||
822 !( mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsUserCheckable ) )
825 if ( mAttributeTable->item( row, column )->checkState() == Qt::Unchecked )
827 mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( Qt::Unchecked );
828 mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable );
829 bool checkBoxEnabled =
false;
830 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
832 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
833 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsEnabled )
835 checkBoxEnabled =
true;
839 mReplaceRawFieldValues->setEnabled( checkBoxEnabled );
840 if ( !checkBoxEnabled )
841 mReplaceRawFieldValues->setCheckState( Qt::Unchecked );
843 else if ( mAttributeTable->item( row, column )->checkState() == Qt::Checked )
845 mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsEnabled );
846 mReplaceRawFieldValues->setEnabled(
true );
850 case ColumnIndex::ExportName:
853 if ( item->text().isEmpty() )
855 QMessageBox::warning(
this,
856 tr(
"Empty export name" ),
857 tr(
"Empty export name are not allowed." ) );
863 while ( names.count( item->text() ) > 1 )
864 item->setText( QString(
"%1_2" ).arg( item->text() ) );
866 mUseAliasesForExportedName->setCheckState( Qt::PartiallyChecked );
869 case ColumnIndex::Type:
872 case ColumnIndex::ExportAsDisplayedValue:
874 if ( mAttributeTable->item( row, column )->flags() & Qt::ItemIsUserCheckable )
876 bool allChecked =
true;
877 bool allUnchecked =
true;
878 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
880 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
881 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsEnabled )
883 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->checkState() == Qt::Unchecked )
886 allUnchecked =
false;
889 mReplaceRawFieldValues->setCheckState( ( !allChecked && !allUnchecked ) ? Qt::PartiallyChecked : ( allChecked ) ? Qt::Checked : Qt::Unchecked );
899 mExtentGroupBox->setOutputCrs( mSelectedCrs );
904 return mFilename->filePath();
909 return leLayername->text();
914 return mEncodingComboBox->currentText();
919 return mFormatComboBox->currentData().toString();
935 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
939 switch ( it.value()->type )
944 QSpinBox *sb = mDatasourceOptionsGroupBox->findChild<QSpinBox *>( it.key() );
946 options << QStringLiteral(
"%1=%2" ).arg( it.key() ).arg( sb->value() );
953 QComboBox *cb = mDatasourceOptionsGroupBox->findChild<QComboBox *>( it.key() );
954 if ( opt && cb && cb->itemData( cb->currentIndex() ) != opt->
defaultValue )
955 options << QStringLiteral(
"%1=%2" ).arg( it.key(), cb->currentText() );
962 QLineEdit *le = mDatasourceOptionsGroupBox->findChild<QLineEdit *>( it.key() );
964 options << QStringLiteral(
"%1=%2" ).arg( it.key(), le->text() );
972 if ( !opt->
mValue.isEmpty() )
973 options << QStringLiteral(
"%1=%2" ).arg( it.key(), opt->
mValue );
980 QString plainText = mOgrDatasourceOptions->toPlainText().trimmed();
981 if ( !plainText.isEmpty() )
982 options += plainText.split(
'\n' );
995 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
999 switch ( it.value()->type )
1004 QSpinBox *sb = mLayerOptionsGroupBox->findChild<QSpinBox *>( it.key() );
1006 options << QStringLiteral(
"%1=%2" ).arg( it.key() ).arg( sb->value() );
1013 QComboBox *cb = mLayerOptionsGroupBox->findChild<QComboBox *>( it.key() );
1014 if ( opt && cb && cb->itemData( cb->currentIndex() ) != opt->
defaultValue )
1015 options << QStringLiteral(
"%1=%2" ).arg( it.key(), cb->currentText() );
1022 QLineEdit *le = mLayerOptionsGroupBox->findChild<QLineEdit *>( it.key() );
1024 options << QStringLiteral(
"%1=%2" ).arg( it.key(), le->text() );
1032 if ( !opt->
mValue.isEmpty() )
1033 options << QStringLiteral(
"%1=%2" ).arg( it.key(), opt->
mValue );
1040 QString plainText = mOgrLayerOptions->toPlainText().trimmed();
1041 if ( !plainText.isEmpty() )
1042 options += plainText.split(
'\n' );
1051 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1053 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->checkState() == Qt::Checked )
1055 attributes.append( i );
1066 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1068 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->checkState() == Qt::Checked &&
1069 ! mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
1070 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->checkState() == Qt::Checked )
1072 attributes.append( i );
1081 QStringList exportNames;
1082 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1083 exportNames.append( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->text() );
1090 return mAddToCanvas->isChecked();
1095 mAddToCanvasStateOnOpenCompatibleDriver = enabled;
1096 if ( mAddToCanvas->isEnabled() )
1097 mAddToCanvas->setChecked( enabled );
1107 return mScaleWidget->scale();
1112 mMapCanvas = canvas;
1113 mScaleWidget->setMapCanvas( canvas );
1114 mScaleWidget->setShowCurrentScaleButton(
true );
1120 return mExtentGroupBox->isChecked();
1125 return mExtentGroupBox->outputExtent();
1135 return mSelectedOnly->isChecked();
1140 return mCheckPersistMetadata->isChecked();
1145 int currentIndexData = mGeometryTypeComboBox->currentData().toInt();
1146 if ( currentIndexData == -1 )
1157 int currentIndexData = mGeometryTypeComboBox->currentData().toInt();
1158 return currentIndexData == -1;
1163 return mForceMultiCheckBox->isChecked();
1168 mForceMultiCheckBox->setChecked( checked );
1173 return mIncludeZCheckBox->isChecked();
1178 return mActionOnExistingFile;
1183 mIncludeZCheckBox->setChecked( checked );
1186void QgsVectorLayerSaveAsDialog::mSymbologyExportComboBox_currentIndexChanged(
const QString &text )
1188 bool scaleEnabled =
true;
1189 if ( text == tr(
"No symbology" ) )
1191 scaleEnabled =
false;
1193 mScaleWidget->setEnabled( scaleEnabled );
1194 mScaleLabel->setEnabled( scaleEnabled );
1197void QgsVectorLayerSaveAsDialog::mGeometryTypeComboBox_currentIndexChanged(
int )
1203 mForceMultiCheckBox->setEnabled(
true );
1204 mIncludeZCheckBox->setEnabled(
true );
1208 mForceMultiCheckBox->setEnabled(
false );
1209 mForceMultiCheckBox->setChecked(
false );
1210 mIncludeZCheckBox->setEnabled(
false );
1211 mIncludeZCheckBox->setChecked(
false );
1215void QgsVectorLayerSaveAsDialog::mSelectAllAttributes_clicked()
1217 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
1218 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
1220 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1222 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->flags() & Qt::ItemIsEnabled )
1224 if ( ! mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
1225 ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsUserCheckable ) )
1227 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsEnabled );
1229 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->setCheckState( Qt::Checked );
1232 if ( ! mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
1234 mReplaceRawFieldValues->setEnabled(
true );
1238void QgsVectorLayerSaveAsDialog::mDeselectAllAttributes_clicked()
1240 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
1241 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
1243 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1245 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->setCheckState( Qt::Unchecked );
1246 if ( ! mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
1247 ( 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 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)
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.