29 #include <QMessageBox>
30 #include <QFileDialog>
33 #include <QRegularExpression>
41 : QDialog( parent, fl )
49 : QDialog( parent, fl )
56 mSelectedCrs = layer->
crs();
57 mLayerExtent = layer->
extent();
63 mSymbologyExportLabel->hide();
64 mSymbologyExportComboBox->hide();
74 if ( !( mOptions &
Fields ) )
75 mAttributesSelection->hide();
78 mSelectedOnly->hide();
84 mGeometryGroupBox->hide();
86 if ( !( mOptions &
Extent ) )
87 mExtentGroupBox->hide();
91 mCheckPersistMetadata->setChecked(
false );
92 mCheckPersistMetadata->hide();
96 mButtonBox->button( QDialogButtonBox::Ok )->setDisabled(
true );
99 void QgsVectorLayerSaveAsDialog::setup()
104 connect( mFormatComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsVectorLayerSaveAsDialog::mFormatComboBox_currentIndexChanged );
106 connect( mSymbologyExportComboBox, &QComboBox::currentTextChanged,
this, &QgsVectorLayerSaveAsDialog::mSymbologyExportComboBox_currentIndexChanged );
107 connect( mGeometryTypeComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsVectorLayerSaveAsDialog::mGeometryTypeComboBox_currentIndexChanged );
108 connect( mSelectAllAttributes, &QPushButton::clicked,
this, &QgsVectorLayerSaveAsDialog::mSelectAllAttributes_clicked );
109 connect( mDeselectAllAttributes, &QPushButton::clicked,
this, &QgsVectorLayerSaveAsDialog::mDeselectAllAttributes_clicked );
110 connect( mUseAliasesForExportedName, &QCheckBox::stateChanged,
this, &QgsVectorLayerSaveAsDialog::mUseAliasesForExportedName_stateChanged );
111 connect( mReplaceRawFieldValues, &QCheckBox::stateChanged,
this, &QgsVectorLayerSaveAsDialog::mReplaceRawFieldValues_stateChanged );
112 connect( mAttributeTable, &QTableWidget::itemChanged,
this, &QgsVectorLayerSaveAsDialog::mAttributeTable_itemChanged );
115 mHelpButtonBox->setVisible(
false );
116 mButtonBox->addButton( QDialogButtonBox::Help );
117 connect( mButtonBox, &QDialogButtonBox::helpRequested,
this, &QgsVectorLayerSaveAsDialog::showHelp );
119 connect( mHelpButtonBox, &QDialogButtonBox::helpRequested,
this, &QgsVectorLayerSaveAsDialog::showHelp );
121 connect( mButtonBox, &QDialogButtonBox::accepted,
this, &QgsVectorLayerSaveAsDialog::accept );
122 connect( mButtonBox, &QDialogButtonBox::rejected,
this, &QgsVectorLayerSaveAsDialog::reject );
125 mFormatComboBox->blockSignals(
true );
128 mFormatComboBox->addItem( driver.longName, driver.driverName );
132 QString
format = settings.
value( QStringLiteral(
"UI/lastVectorFormat" ),
"GPKG" ).toString();
133 mFormatComboBox->setCurrentIndex( mFormatComboBox->findData(
format ) );
134 mFormatComboBox->blockSignals(
false );
142 mGeometryTypeComboBox->addItem( tr(
"Automatic" ), -1 );
148 mGeometryTypeComboBox->setCurrentIndex( mGeometryTypeComboBox->findData( -1 ) );
152 QString enc = settings.
value( QStringLiteral(
"UI/encoding" ),
"System" ).toString();
153 int idx = mEncodingComboBox->findText( enc );
156 mEncodingComboBox->insertItem( 0, enc );
160 mCrsSelector->setCrs( mSelectedCrs );
161 mCrsSelector->setLayerCrs( mSelectedCrs );
162 mCrsSelector->setMessage( tr(
"Select the coordinate reference system for the vector file. "
163 "The data points will be transformed from the layer coordinate reference system." ) );
165 mEncodingComboBox->setCurrentIndex( idx );
166 mFormatComboBox_currentIndexChanged( mFormatComboBox->currentIndex() );
172 mSymbologyExportComboBox_currentIndexChanged( mSymbologyExportComboBox->currentText() );
175 mExtentGroupBox->setOutputCrs( mSelectedCrs );
176 mExtentGroupBox->setOriginalExtent( mLayerExtent, mSelectedCrs );
177 mExtentGroupBox->setOutputExtentFromOriginal();
178 mExtentGroupBox->setCheckable(
true );
179 mExtentGroupBox->setChecked(
false );
180 mExtentGroupBox->setCollapsed(
true );
183 mFilename->setDialogTitle( tr(
"Save Layer As" ) );
184 mFilename->setDefaultRoot( settings.
value( QStringLiteral(
"UI/lastVectorFileFilterDir" ), QDir::homePath() ).toString() );
185 mFilename->setConfirmOverwrite(
false );
189 QFileInfo tmplFileInfo( filePath );
190 settings.
setValue( QStringLiteral(
"UI/lastVectorFileFilterDir" ), tmplFileInfo.absolutePath() );
191 if ( !filePath.isEmpty() && leLayername->isEnabled() )
193 QFileInfo fileInfo( filePath );
194 leLayername->setText( fileInfo.completeBaseName() );
196 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( !filePath.isEmpty() );
204 mCrsSelector->setSourceEnsemble( ensemble.
name() );
211 mCrsSelector->setShowAccuracyWarnings(
true );
214 QList<QPair<QLabel *, QWidget *> > QgsVectorLayerSaveAsDialog::createControls(
const QMap<QString, QgsVectorFileWriter::Option *> &options )
216 QList<QPair<QLabel *, QWidget *> > controls;
217 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
219 for ( it = options.constBegin(); it != options.constEnd(); ++it )
222 QLabel *label =
new QLabel( it.key() );
223 QWidget *control =
nullptr;
224 switch ( option->
type )
231 QSpinBox *sb =
new QSpinBox();
232 sb->setObjectName( it.key() );
244 QComboBox *cb =
new QComboBox();
245 cb->setObjectName( it.key() );
246 for (
const QString &val : std::as_const( opt->
values ) )
248 cb->addItem( val, val );
251 cb->addItem( tr(
"<Default>" ), QVariant( QVariant::String ) );
254 idx = cb->findData( QVariant( QVariant::String ) );
255 cb->setCurrentIndex( idx );
267 le->setObjectName( it.key() );
281 label->setToolTip( QStringLiteral(
"<p>%1</p>" ).arg( option->
docString.toHtmlEscaped() ) );
282 control->setToolTip( QStringLiteral(
"<p>%1</p>" ).arg( option->
docString.toHtmlEscaped() ) );
284 controls << QPair<QLabel *, QWidget *>( label, control );
291 void QgsVectorLayerSaveAsDialog::accept()
295 QgsVectorFileWriter::EditionCapabilities caps =
300 msgBox.setIcon( QMessageBox::Question );
301 msgBox.setWindowTitle( tr(
"Save Vector Layer As" ) );
302 QPushButton *overwriteFileButton = msgBox.addButton( tr(
"Overwrite File" ), QMessageBox::ActionRole );
303 QPushButton *overwriteLayerButton = msgBox.addButton( tr(
"Overwrite Layer" ), QMessageBox::ActionRole );
304 QPushButton *appendToLayerButton = msgBox.addButton( tr(
"Append to Layer" ), QMessageBox::ActionRole );
305 msgBox.setStandardButtons( QMessageBox::Cancel );
306 msgBox.setDefaultButton( QMessageBox::Cancel );
307 overwriteFileButton->hide();
308 overwriteLayerButton->hide();
309 appendToLayerButton->hide();
316 msgBox.setText( tr(
"The layer already exists. Do you want to overwrite the whole file or overwrite the layer?" ) );
317 overwriteFileButton->setVisible(
true );
318 overwriteLayerButton->setVisible(
true );
322 msgBox.setText( tr(
"The file already exists. Do you want to overwrite it?" ) );
323 overwriteFileButton->setVisible(
true );
328 msgBox.setText( tr(
"The layer already exists. Do you want to overwrite the whole file, overwrite the layer or append features to the layer?" ) );
329 appendToLayerButton->setVisible(
true );
330 overwriteFileButton->setVisible(
true );
331 overwriteLayerButton->setVisible(
true );
335 msgBox.setText( tr(
"The layer already exists. Do you want to overwrite the whole file or append features to the layer?" ) );
336 appendToLayerButton->setVisible(
true );
337 overwriteFileButton->setVisible(
true );
340 int ret = msgBox.exec();
341 if ( ret == QMessageBox::Cancel )
343 if ( msgBox.clickedButton() == overwriteFileButton )
345 else if ( msgBox.clickedButton() == overwriteLayerButton )
347 else if ( msgBox.clickedButton() == appendToLayerButton )
359 if ( QMessageBox::question(
this,
360 tr(
"Save Vector Layer As" ),
361 tr(
"The file already exists. Do you want to overwrite it?" ) ) == QMessageBox::NoButton )
374 if ( QMessageBox::question(
this,
375 tr(
"Save Vector Layer As" ),
376 tr(
"The existing layer has additional fields. Do you want to add the missing fields to the layer?" ) ) == QMessageBox::Yes )
385 QStringList layerList;
386 layerList.reserve( sublayers.size() );
389 layerList.append( sublayer.name() );
391 if ( layerList.length() > 1 )
393 layerList.sort( Qt::CaseInsensitive );
395 msgBox.setIcon( QMessageBox::Warning );
396 msgBox.setWindowTitle( tr(
"Overwrite File" ) );
397 msgBox.setText( tr(
"This file contains %1 layers that will be lost!\n" ).arg( QLocale().toString( layerList.length() ) ) );
398 msgBox.setDetailedText( tr(
"The following layers will be permanently lost:\n\n%1" ).arg( layerList.join(
"\n" ) ) );
399 msgBox.setStandardButtons( QMessageBox::Ok | QMessageBox::Cancel );
400 if ( msgBox.exec() == QMessageBox::Cancel )
406 settings.
setValue( QStringLiteral(
"UI/lastVectorFileFilterDir" ), QFileInfo(
filename() ).absolutePath() );
407 settings.
setValue( QStringLiteral(
"UI/lastVectorFormat" ),
format() );
412 void QgsVectorLayerSaveAsDialog::mFormatComboBox_currentIndexChanged(
int idx )
416 mFilename->setEnabled(
true );
421 if ( !mFilename->filePath().isEmpty() )
423 QRegularExpression rx(
"\\.(.*?)[\\s]" );
426 if ( !ext.isEmpty() )
428 QFileInfo fi( mFilename->filePath() );
429 mFilename->setFilePath( QStringLiteral(
"%1/%2.%3" ).arg( fi.path() ).arg( fi.baseName() ).arg( ext ) );
433 bool selectAllFields =
true;
438 bool isFormatForFieldsAsDisplayedValues =
false;
440 const QString sFormat(
format() );
441 if ( sFormat == QLatin1String(
"DXF" ) || sFormat == QLatin1String(
"DGN" ) )
443 mAttributesSelection->setVisible(
false );
444 selectAllFields =
false;
450 mAttributesSelection->setVisible(
true );
451 isFormatForFieldsAsDisplayedValues = ( sFormat == QLatin1String(
"CSV" ) ||
452 sFormat == QLatin1String(
"XLS" ) ||
453 sFormat == QLatin1String(
"XLSX" ) ||
454 sFormat == QLatin1String(
"ODS" ) );
461 mSymbologyExportLabel->setVisible(
true );
462 mSymbologyExportComboBox->setVisible(
true );
463 mScaleLabel->setVisible(
true );
464 mScaleWidget->setVisible(
true );
468 mSymbologyExportLabel->hide();
469 mSymbologyExportComboBox->hide();
471 mScaleWidget->hide();
474 leLayername->setEnabled( sFormat == QLatin1String(
"KML" ) ||
475 sFormat == QLatin1String(
"GPKG" ) ||
476 sFormat == QLatin1String(
"XLSX" ) ||
477 sFormat == QLatin1String(
"ODS" ) ||
478 sFormat == QLatin1String(
"FileGDB" ) ||
479 sFormat == QLatin1String(
"SQLite" ) ||
480 sFormat == QLatin1String(
"SpatiaLite" ) );
482 if ( sFormat == QLatin1String(
"XLSX" ) )
483 leLayername->setMaxLength( 31 );
484 else if ( leLayername->isEnabled() )
485 leLayername->setMaxLength( 32767 );
487 if ( !leLayername->isEnabled() )
488 leLayername->setText( QString() );
489 else if ( leLayername->text().isEmpty() &&
490 !mFilename->filePath().isEmpty() )
492 QString layerName = QFileInfo( mFilename->filePath() ).baseName();
493 leLayername->setText( layerName );
498 mAttributeTable->setRowCount( mLayer->
fields().
count() );
500 QStringList horizontalHeaders = QStringList() << tr(
"Name" ) << tr(
"Export name" ) << tr(
"Type" ) << tr(
"Replace with displayed values" );
501 mAttributeTable->setColumnCount( horizontalHeaders.size() );
502 mAttributeTable->setHorizontalHeaderLabels( horizontalHeaders );
504 bool foundFieldThatCanBeExportedAsDisplayedValue =
false;
505 for (
int i = 0; i < mLayer->
fields().size(); ++i )
508 if ( setup.
type() != QLatin1String(
"TextEdit" ) &&
511 foundFieldThatCanBeExportedAsDisplayedValue =
true;
515 mAttributeTable->setColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ),
516 ! foundFieldThatCanBeExportedAsDisplayedValue );
518 bool checkReplaceRawFieldValues = selectAllFields && isFormatForFieldsAsDisplayedValues;
519 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
521 for (
int i = 0; i < mLayer->
fields().size(); ++i )
524 Qt::ItemFlags flags = mLayer->
providerType() != QLatin1String(
"oracle" ) || !fld.
typeName().contains( QLatin1String(
"SDO_GEOMETRY" ) ) ? Qt::ItemIsEnabled : Qt::NoItemFlags;
525 QTableWidgetItem *item =
nullptr;
526 item =
new QTableWidgetItem( fld.
name() );
527 item->setFlags( flags | Qt::ItemIsUserCheckable );
528 item->setCheckState( ( selectAllFields ) ? Qt::Checked : Qt::Unchecked );
529 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::Name ), item );
531 item =
new QTableWidgetItem( fld.
name() );
532 item->setFlags( flags | Qt::ItemIsEditable );
534 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::ExportName ), item );
536 item =
new QTableWidgetItem( fld.
typeName() );
537 item->setFlags( flags );
538 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::Type ), item );
540 if ( foundFieldThatCanBeExportedAsDisplayedValue )
544 const QString widgetId( setup.
type() );
545 if ( flags == Qt::ItemIsEnabled &&
546 widgetId != QLatin1String(
"TextEdit" ) &&
549 item =
new QTableWidgetItem( tr(
"Use %1" ).arg( factory->
name() ) );
550 item->setFlags( ( selectAllFields ) ? ( Qt::ItemIsEnabled | Qt::ItemIsUserCheckable ) : Qt::ItemIsUserCheckable );
551 const bool checkItem = ( selectAllFields && isFormatForFieldsAsDisplayedValues &&
552 ( widgetId == QLatin1String(
"ValueMap" ) ||
553 widgetId == QLatin1String(
"ValueRelation" ) ||
554 widgetId == QLatin1String(
"CheckBox" ) ||
555 widgetId == QLatin1String(
"RelationReference" ) ) );
556 checkReplaceRawFieldValues &= checkItem;
557 item->setCheckState( checkItem ?
558 Qt::Checked : Qt::Unchecked );
559 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ), item );
563 item =
new QTableWidgetItem();
564 item->setFlags( Qt::NoItemFlags );
565 mAttributeTable->setItem( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ), item );
571 whileBlocking( mReplaceRawFieldValues )->setChecked( checkReplaceRawFieldValues );
572 mReplaceRawFieldValues->setEnabled( selectAllFields );
573 mReplaceRawFieldValues->setVisible( foundFieldThatCanBeExportedAsDisplayedValue );
575 mAttributeTable->resizeColumnsToContents();
580 while ( mDatasourceOptionsGroupBox->layout()->count() )
582 QLayoutItem *item = mDatasourceOptionsGroupBox->layout()->takeAt( 0 );
583 delete item->widget();
587 while ( mLayerOptionsGroupBox->layout()->count() )
589 QLayoutItem *item = mLayerOptionsGroupBox->layout()->takeAt( 0 );
590 delete item->widget();
594 typedef QPair<QLabel *, QWidget *> LabelControlPair;
600 mDatasourceOptionsGroupBox->setVisible(
true );
601 QList<QPair<QLabel *, QWidget *> > controls = createControls( driverMetaData.
driverOptions );
603 QFormLayout *datasourceLayout =
dynamic_cast<QFormLayout *
>( mDatasourceOptionsGroupBox->layout() );
605 const auto constControls = controls;
606 for ( LabelControlPair control : constControls )
608 datasourceLayout->addRow( control.first, control.second );
613 mDatasourceOptionsGroupBox->setVisible(
false );
618 mLayerOptionsGroupBox->setVisible(
true );
619 QList<QPair<QLabel *, QWidget *> > controls = createControls( driverMetaData.
layerOptions );
621 QFormLayout *layerOptionsLayout =
dynamic_cast<QFormLayout *
>( mLayerOptionsGroupBox->layout() );
623 const auto constControls = controls;
624 for ( LabelControlPair control : constControls )
626 layerOptionsLayout->addRow( control.first, control.second );
631 mLayerOptionsGroupBox->setVisible(
false );
636 mEncodingComboBox->setEnabled(
true );
643 mEncodingComboBox->setCurrentIndex( idx );
644 mEncodingComboBox->setDisabled(
true );
648 mEncodingComboBox->setEnabled(
true );
655 mEncodingComboBox->setEnabled(
true );
658 GDALDriverH hDriver = GDALGetDriverByName(
format().toUtf8().constData() );
661 mAddToCanvas->setEnabled( GDALGetMetadataItem( hDriver, GDAL_DCAP_OPEN,
nullptr ) !=
nullptr );
665 void QgsVectorLayerSaveAsDialog::mUseAliasesForExportedName_stateChanged(
int state )
667 const QSignalBlocker signalBlocker( mAttributeTable );
674 bool modifiedEntries =
false;
675 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
677 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->text()
678 != mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->data( Qt::UserRole ).toString() )
680 modifiedEntries =
true;
685 if ( modifiedEntries )
687 if ( QMessageBox::question(
this,
688 tr(
"Modified names" ),
689 tr(
"Some names were modified and will be overridden. Do you want to continue?" ) )
692 whileBlocking( mUseAliasesForExportedName )->setCheckState( Qt::PartiallyChecked );
697 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
699 mUseAliasesForExportedName->setTristate(
false );
700 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->setText( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->text() );
707 bool modifiedEntries =
false;
708 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
710 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->text()
711 != mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->text() )
712 modifiedEntries =
true;
715 if ( modifiedEntries )
717 if ( QMessageBox::question(
this,
718 tr(
"Modified names" ),
719 tr(
"Some names were modified and will be overridden. Do you want to continue?" ) )
722 whileBlocking( mUseAliasesForExportedName )->setCheckState( Qt::PartiallyChecked );
727 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
729 mUseAliasesForExportedName->setTristate(
false );
730 const QString alias = mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->data( Qt::UserRole ).toString();
731 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->setText( alias );
735 case Qt::PartiallyChecked:
741 void QgsVectorLayerSaveAsDialog::mReplaceRawFieldValues_stateChanged(
int )
743 if ( mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
746 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
747 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
749 if ( mReplaceRawFieldValues->checkState() != Qt::PartiallyChecked )
751 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
753 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->checkState() == Qt::Checked &&
754 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
755 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsEnabled )
757 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( mReplaceRawFieldValues->checkState() );
761 mReplaceRawFieldValues->setTristate(
false );
764 void QgsVectorLayerSaveAsDialog::mAttributeTable_itemChanged( QTableWidgetItem *item )
766 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
767 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
769 int row = item->row();
770 int column = item->column();
772 switch (
static_cast<ColumnIndex
>( column ) )
774 case ColumnIndex::Name:
776 if ( mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) ||
777 ! mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) ||
778 !( mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsUserCheckable ) )
781 if ( mAttributeTable->item( row, column )->checkState() == Qt::Unchecked )
783 mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( Qt::Unchecked );
784 mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable );
785 bool checkBoxEnabled =
false;
786 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
788 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
789 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsEnabled )
791 checkBoxEnabled =
true;
795 mReplaceRawFieldValues->setEnabled( checkBoxEnabled );
796 if ( !checkBoxEnabled )
797 mReplaceRawFieldValues->setCheckState( Qt::Unchecked );
799 else if ( mAttributeTable->item( row, column )->checkState() == Qt::Checked )
801 mAttributeTable->item( row,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsEnabled );
802 mReplaceRawFieldValues->setEnabled(
true );
806 case ColumnIndex::ExportName:
809 if ( item->text().isEmpty() )
811 QMessageBox::warning(
this,
812 tr(
"Empty export name" ),
813 tr(
"Empty export name are not allowed." ) );
819 while ( names.count( item->text() ) > 1 )
820 item->setText( QString(
"%1_2" ).arg( item->text() ) );
822 mUseAliasesForExportedName->setCheckState( Qt::PartiallyChecked );
825 case ColumnIndex::Type:
828 case ColumnIndex::ExportAsDisplayedValue:
830 if ( mAttributeTable->item( row, column )->flags() & Qt::ItemIsUserCheckable )
832 bool allChecked =
true;
833 bool allUnchecked =
true;
834 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
836 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
837 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsEnabled )
839 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->checkState() == Qt::Unchecked )
842 allUnchecked =
false;
845 mReplaceRawFieldValues->setCheckState( ( !allChecked && !allUnchecked ) ? Qt::PartiallyChecked : ( allChecked ) ? Qt::Checked : Qt::Unchecked );
855 mExtentGroupBox->setOutputCrs( mSelectedCrs );
860 return mFilename->filePath();
865 return leLayername->text();
870 return mEncodingComboBox->currentText();
875 return mFormatComboBox->currentData().toString();
880 return mSelectedCrs.
srsid();
896 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
900 switch ( it.value()->type )
905 QSpinBox *sb = mDatasourceOptionsGroupBox->findChild<QSpinBox *>( it.key() );
907 options << QStringLiteral(
"%1=%2" ).arg( it.key() ).arg( sb->value() );
914 QComboBox *cb = mDatasourceOptionsGroupBox->findChild<QComboBox *>( it.key() );
915 if ( opt && cb && cb->itemData( cb->currentIndex() ) != opt->
defaultValue )
916 options << QStringLiteral(
"%1=%2" ).arg( it.key(), cb->currentText() );
923 QLineEdit *le = mDatasourceOptionsGroupBox->findChild<QLineEdit *>( it.key() );
925 options << QStringLiteral(
"%1=%2" ).arg( it.key(), le->text() );
933 options << QStringLiteral(
"%1=%2" ).arg( it.key(), opt->
mValue );
940 QString plainText = mOgrDatasourceOptions->toPlainText().trimmed();
941 if ( !plainText.isEmpty() )
942 options += plainText.split(
'\n' );
955 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
959 switch ( it.value()->type )
964 QSpinBox *sb = mLayerOptionsGroupBox->findChild<QSpinBox *>( it.key() );
966 options << QStringLiteral(
"%1=%2" ).arg( it.key() ).arg( sb->value() );
973 QComboBox *cb = mLayerOptionsGroupBox->findChild<QComboBox *>( it.key() );
974 if ( opt && cb && cb->itemData( cb->currentIndex() ) != opt->
defaultValue )
975 options << QStringLiteral(
"%1=%2" ).arg( it.key(), cb->currentText() );
982 QLineEdit *le = mLayerOptionsGroupBox->findChild<QLineEdit *>( it.key() );
984 options << QStringLiteral(
"%1=%2" ).arg( it.key(), le->text() );
992 options << QStringLiteral(
"%1=%2" ).arg( it.key(), opt->
mValue );
999 QString plainText = mOgrLayerOptions->toPlainText().trimmed();
1000 if ( !plainText.isEmpty() )
1001 options += plainText.split(
'\n' );
1010 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1012 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->checkState() == Qt::Checked )
1014 attributes.append( i );
1025 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1027 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->checkState() == Qt::Checked &&
1028 ! mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
1029 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->checkState() == Qt::Checked )
1031 attributes.append( i );
1040 QStringList exportNames;
1041 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1042 exportNames.append( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportName ) )->text() );
1049 return mAddToCanvas->isChecked() && mAddToCanvas->isEnabled();
1054 mAddToCanvas->setChecked( enabled );
1059 return mSymbologyExportComboBox->currentData().toInt();
1064 return mScaleWidget->scale();
1069 mMapCanvas = canvas;
1070 mScaleWidget->setMapCanvas( canvas );
1071 mScaleWidget->setShowCurrentScaleButton(
true );
1077 return mExtentGroupBox->isChecked();
1082 return mExtentGroupBox->outputExtent();
1092 return mSelectedOnly->isChecked();
1097 return mCheckPersistMetadata->isChecked();
1102 int currentIndexData = mGeometryTypeComboBox->currentData().toInt();
1103 if ( currentIndexData == -1 )
1114 int currentIndexData = mGeometryTypeComboBox->currentData().toInt();
1115 return currentIndexData == -1;
1120 return mForceMultiCheckBox->isChecked();
1125 mForceMultiCheckBox->setChecked( checked );
1130 return mIncludeZCheckBox->isChecked();
1135 return mActionOnExistingFile;
1140 mIncludeZCheckBox->setChecked( checked );
1143 void QgsVectorLayerSaveAsDialog::mSymbologyExportComboBox_currentIndexChanged(
const QString &text )
1145 bool scaleEnabled =
true;
1146 if ( text == tr(
"No symbology" ) )
1148 scaleEnabled =
false;
1150 mScaleWidget->setEnabled( scaleEnabled );
1151 mScaleLabel->setEnabled( scaleEnabled );
1154 void QgsVectorLayerSaveAsDialog::mGeometryTypeComboBox_currentIndexChanged(
int index )
1156 int currentIndexData = mGeometryTypeComboBox->itemData( index ).toInt();
1160 mForceMultiCheckBox->setEnabled(
true );
1161 mIncludeZCheckBox->setEnabled(
true );
1165 mForceMultiCheckBox->setEnabled(
false );
1166 mForceMultiCheckBox->setChecked(
false );
1167 mIncludeZCheckBox->setEnabled(
false );
1168 mIncludeZCheckBox->setChecked(
false );
1172 void QgsVectorLayerSaveAsDialog::mSelectAllAttributes_clicked()
1174 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
1175 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
1177 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1179 if ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->flags() & Qt::ItemIsEnabled )
1181 if ( ! mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
1182 ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsUserCheckable ) )
1184 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsEnabled );
1186 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->setCheckState( Qt::Checked );
1189 if ( ! mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
1191 mReplaceRawFieldValues->setEnabled(
true );
1195 void QgsVectorLayerSaveAsDialog::mDeselectAllAttributes_clicked()
1197 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
1198 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
1200 for (
int i = 0; i < mAttributeTable->rowCount(); i++ )
1202 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::Name ) )->setCheckState( Qt::Unchecked );
1203 if ( ! mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
1204 ( mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsUserCheckable ) )
1206 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable );
1207 mAttributeTable->item( i,
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( Qt::Unchecked );
1210 if ( ! mAttributeTable->isColumnHidden(
static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
1212 mReplaceRawFieldValues->setCheckState( Qt::Unchecked );
1213 mReplaceRawFieldValues->setEnabled(
false );
1217 void QgsVectorLayerSaveAsDialog::showHelp()
1219 QgsHelp::openHelp( QStringLiteral(
"managing_data_source/create_layers.html#creating-new-layers-from-an-existing-layer" ) );
This class represents a coordinate reference system (CRS).
QgsDatumEnsemble datumEnsemble() const SIP_THROW(QgsNotSupportedException)
Attempts to retrieve datum ensemble details from the CRS.
long srsid() const
Returns the internal CRS ID, if available.
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).
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(QgsWkbTypes::Type 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.
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.
QString filename() const
Returns the target filename.
QgsAttributeList selectedAttributes() const
Returns a list of attributes which are selected for saving.
QgsRectangle filterExtent() const
Determines the extent to be exported.
Q_DECL_DEPRECATED long crs() const
Returns the internal CRS ID.
QString format() const
The 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
The encoding of 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.
void setOnlySelected(bool onlySelected)
Sets whether only selected features will be saved.
@ DestinationCrs
Show destination CRS (reprojection) option.
@ AddToCanvas
Show add to map option.
@ Extent
Show extent group.
@ Symbology
Show symbology options.
@ SelectedOnly
Show selected features only option.
@ Fields
Show field customization group.
@ Metadata
Show metadata options.
@ GeometryType
Show geometry group.
bool automaticGeometryType() const
Returns true if geometry type is set to automatic.
QString layername() const
Returns the target layer name.
QgsWkbTypes::Type geometryType() const
Returns the selected flat geometry type for the export.
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.
QgsCoordinateReferenceSystem crsObject() 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.
QgsVectorFileWriter::ActionOnExistingFile creationActionOnExistingFile() const
Returns creation action.
int symbologyExport() const
Returns type of symbology export.
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.
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(Type type) SIP_HOLDGIL
Returns a translated display string type for a WKB type, e.g., the geometry name used in WKT geometry...
Type
The WKB type describes the number of dimensions a geometry has.
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.