QGIS API Documentation 3.28.14-Firenze (exported)
Loading...
Searching...
No Matches
qgsvectorlayersaveasdialog.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsvectorlayersaveasdialog.h
3 Dialog to select destination, type and crs for ogr layers
4 -------------------
5 begin : Mon Mar 22 2010
6 copyright : (C) 2010 by Juergen E. Fischer
7 email : jef at norbit dot de
8 ***************************************************************************/
9
10/***************************************************************************
11 * *
12 * This program is free software; you can redistribute it and/or modify *
13 * it under the terms of the GNU General Public License as published by *
14 * the Free Software Foundation; either version 2 of the License, or *
15 * (at your option) any later version. *
16 * *
17 ***************************************************************************/
18#include "qgslogger.h"
25#include "qgssettings.h"
26#include "qgsmapcanvas.h"
27#include "qgsgui.h"
28#include "qgsapplication.h"
29#include "qgsmaplayerutils.h"
30#include <QMessageBox>
31#include <QFileDialog>
32#include <QTextCodec>
33#include <QSpinBox>
34#include <QRegularExpression>
35#include <limits>
36#include "gdal.h"
37#include "qgsdatums.h"
38#include "qgsiconutils.h"
39#include "qgsproviderregistry.h"
41
42QgsVectorLayerSaveAsDialog::QgsVectorLayerSaveAsDialog( long srsid, QWidget *parent, Qt::WindowFlags fl )
43 : QDialog( parent, fl )
44 , mSelectedCrs( QgsCoordinateReferenceSystem::fromSrsId( srsid ) )
45 , mActionOnExistingFile( QgsVectorFileWriter::CreateOrOverwriteFile )
46{
47 setup();
48}
49
50QgsVectorLayerSaveAsDialog::QgsVectorLayerSaveAsDialog( QgsVectorLayer *layer, Options options, QWidget *parent, Qt::WindowFlags fl )
51 : QDialog( parent, fl )
52 , mLayer( layer )
53 , mActionOnExistingFile( QgsVectorFileWriter::CreateOrOverwriteFile )
54 , mOptions( options )
55{
56 if ( layer )
57 {
58 mSelectedCrs = layer->crs();
59 mLayerExtent = layer->extent();
60 }
61 setup();
62
63 if ( layer )
64 {
65 mDefaultOutputLayerNameFromInputLayerName = QgsMapLayerUtils::launderLayerName( layer->name() );
66 leLayername->setDefaultValue( mDefaultOutputLayerNameFromInputLayerName );
67 leLayername->setClearMode( QgsFilterLineEdit::ClearToDefault );
68 if ( leLayername->isEnabled() )
69 leLayername->setText( mDefaultOutputLayerNameFromInputLayerName );
70 }
71
72 if ( !( mOptions & Symbology ) )
73 {
74 mSymbologyExportLabel->hide();
75 mSymbologyExportComboBox->hide();
76 mScaleLabel->hide();
77 mScaleWidget->hide();
78 }
79
80 if ( !( mOptions & DestinationCrs ) )
81 {
82 mCrsLabel->hide();
83 mCrsSelector->hide();
84 }
85 if ( !( mOptions & Fields ) )
86 mAttributesSelection->hide();
87
88 if ( !( mOptions & SelectedOnly ) )
89 mSelectedOnly->hide();
90
91 if ( !( mOptions & AddToCanvas ) )
92 mAddToCanvas->hide();
93
94 if ( !( mOptions & GeometryType ) )
95 mGeometryGroupBox->hide();
96
97 if ( !( mOptions & Extent ) )
98 mExtentGroupBox->hide();
99
100 if ( !( mOptions & Metadata ) )
101 {
102 mCheckPersistMetadata->setChecked( false );
103 mCheckPersistMetadata->hide();
104 }
105
106 mSelectedOnly->setEnabled( layer && layer->selectedFeatureCount() != 0 );
107 mButtonBox->button( QDialogButtonBox::Ok )->setDisabled( true );
108}
109
110void QgsVectorLayerSaveAsDialog::setup()
111{
112 setupUi( this );
114
115 connect( mFormatComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsVectorLayerSaveAsDialog::mFormatComboBox_currentIndexChanged );
116 connect( mCrsSelector, &QgsProjectionSelectionWidget::crsChanged, this, &QgsVectorLayerSaveAsDialog::mCrsSelector_crsChanged );
117 connect( mSymbologyExportComboBox, &QComboBox::currentTextChanged, this, &QgsVectorLayerSaveAsDialog::mSymbologyExportComboBox_currentIndexChanged );
118 connect( mGeometryTypeComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsVectorLayerSaveAsDialog::mGeometryTypeComboBox_currentIndexChanged );
119 connect( mSelectAllAttributes, &QPushButton::clicked, this, &QgsVectorLayerSaveAsDialog::mSelectAllAttributes_clicked );
120 connect( mDeselectAllAttributes, &QPushButton::clicked, this, &QgsVectorLayerSaveAsDialog::mDeselectAllAttributes_clicked );
121 connect( mUseAliasesForExportedName, &QCheckBox::stateChanged, this, &QgsVectorLayerSaveAsDialog::mUseAliasesForExportedName_stateChanged );
122 connect( mReplaceRawFieldValues, &QCheckBox::stateChanged, this, &QgsVectorLayerSaveAsDialog::mReplaceRawFieldValues_stateChanged );
123 connect( mAttributeTable, &QTableWidget::itemChanged, this, &QgsVectorLayerSaveAsDialog::mAttributeTable_itemChanged );
124
125#ifdef Q_OS_WIN
126 mHelpButtonBox->setVisible( false );
127 mButtonBox->addButton( QDialogButtonBox::Help );
128 connect( mButtonBox, &QDialogButtonBox::helpRequested, this, &QgsVectorLayerSaveAsDialog::showHelp );
129#else
130 connect( mHelpButtonBox, &QDialogButtonBox::helpRequested, this, &QgsVectorLayerSaveAsDialog::showHelp );
131#endif
132 connect( mButtonBox, &QDialogButtonBox::accepted, this, &QgsVectorLayerSaveAsDialog::accept );
133 connect( mButtonBox, &QDialogButtonBox::rejected, this, &QgsVectorLayerSaveAsDialog::reject );
134
135 const QList< QgsVectorFileWriter::DriverDetails > drivers = QgsVectorFileWriter::ogrDriverList();
136 mFormatComboBox->blockSignals( true );
137 for ( const QgsVectorFileWriter::DriverDetails &driver : drivers )
138 {
139 mFormatComboBox->addItem( driver.longName, driver.driverName );
140 }
141
142 QgsSettings settings;
143 QString format = settings.value( QStringLiteral( "UI/lastVectorFormat" ), "GPKG" ).toString();
144 mFormatComboBox->setCurrentIndex( mFormatComboBox->findData( format ) );
145 mFormatComboBox->blockSignals( false );
146
147 const auto addGeomItem = [this]( QgsWkbTypes::Type type )
148 {
149 mGeometryTypeComboBox->addItem( QgsIconUtils::iconForWkbType( type ), QgsWkbTypes::translatedDisplayString( type ), type );
150 };
151
152 //add geometry types to combobox
153 mGeometryTypeComboBox->addItem( tr( "Automatic" ), -1 );
154 addGeomItem( QgsWkbTypes::Point );
155 addGeomItem( QgsWkbTypes::LineString );
156 addGeomItem( QgsWkbTypes::Polygon );
158 addGeomItem( QgsWkbTypes::NoGeometry );
159 mGeometryTypeComboBox->setCurrentIndex( mGeometryTypeComboBox->findData( -1 ) );
160
161 mEncodingComboBox->addItems( QgsVectorDataProvider::availableEncodings() );
162
163 QString enc = settings.value( QStringLiteral( "UI/encoding" ), "System" ).toString();
164 int idx = mEncodingComboBox->findText( enc );
165 if ( idx < 0 )
166 {
167 mEncodingComboBox->insertItem( 0, enc );
168 idx = 0;
169 }
170
171 mCrsSelector->setCrs( mSelectedCrs );
172 mCrsSelector->setLayerCrs( mSelectedCrs );
173 mCrsSelector->setMessage( tr( "Select the coordinate reference system for the vector file. "
174 "The data points will be transformed from the layer coordinate reference system." ) );
175
176 mEncodingComboBox->setCurrentIndex( idx );
177 mFormatComboBox_currentIndexChanged( mFormatComboBox->currentIndex() );
178
179 //symbology export combo box
180 mSymbologyExportComboBox->addItem( tr( "No Symbology" ), QgsVectorFileWriter::NoSymbology );
181 mSymbologyExportComboBox->addItem( tr( "Feature Symbology" ), QgsVectorFileWriter::FeatureSymbology );
182 mSymbologyExportComboBox->addItem( tr( "Symbol Layer Symbology" ), QgsVectorFileWriter::SymbolLayerSymbology );
183 mSymbologyExportComboBox_currentIndexChanged( mSymbologyExportComboBox->currentText() );
184
185 // extent group box
186 mExtentGroupBox->setOutputCrs( mSelectedCrs );
187 mExtentGroupBox->setOriginalExtent( mLayerExtent, mSelectedCrs );
188 mExtentGroupBox->setOutputExtentFromOriginal();
189 mExtentGroupBox->setCheckable( true );
190 mExtentGroupBox->setChecked( false );
191 mExtentGroupBox->setCollapsed( true );
192
193 mFilename->setStorageMode( QgsFileWidget::SaveFile );
194 mFilename->setDialogTitle( tr( "Save Layer As" ) );
195 mFilename->setDefaultRoot( settings.value( QStringLiteral( "UI/lastVectorFileFilterDir" ), QDir::homePath() ).toString() );
196 mFilename->setConfirmOverwrite( false );
197 connect( mFilename, &QgsFileWidget::fileChanged, this, [ = ]( const QString & filePath )
198 {
199 QgsSettings settings;
200 QFileInfo tmplFileInfo( filePath );
201 settings.setValue( QStringLiteral( "UI/lastVectorFileFilterDir" ), tmplFileInfo.absolutePath() );
202
203 const QFileInfo fileInfo( filePath );
204 const QString suggestedLayerName = QgsMapLayerUtils::launderLayerName( fileInfo.completeBaseName() );
205 if ( mDefaultOutputLayerNameFromInputLayerName.isEmpty() )
206 leLayername->setDefaultValue( suggestedLayerName );
207
208 // if no layer name set, then automatically match the output layer name to the file name
209 if ( leLayername->text().isEmpty() && !filePath.isEmpty() && leLayername->isEnabled() )
210 {
211 leLayername->setText( suggestedLayerName );
212 }
213 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( !filePath.isEmpty() );
214 } );
215
216 try
217 {
218 const QgsDatumEnsemble ensemble = mSelectedCrs.datumEnsemble();
219 if ( ensemble.isValid() )
220 {
221 mCrsSelector->setSourceEnsemble( ensemble.name() );
222 }
223 }
224 catch ( QgsNotSupportedException & )
225 {
226 }
227
228 mCrsSelector->setShowAccuracyWarnings( true );
229}
230
231QList<QPair<QLabel *, QWidget *> > QgsVectorLayerSaveAsDialog::createControls( const QMap<QString, QgsVectorFileWriter::Option *> &options )
232{
233 QList<QPair<QLabel *, QWidget *> > controls;
234 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
235
236 for ( it = options.constBegin(); it != options.constEnd(); ++it )
237 {
238 QgsVectorFileWriter::Option *option = it.value();
239 QWidget *control = nullptr;
240 switch ( option->type )
241 {
243 {
244 QgsVectorFileWriter::IntOption *opt = dynamic_cast<QgsVectorFileWriter::IntOption *>( option );
245 if ( opt )
246 {
247 QSpinBox *sb = new QSpinBox();
248 sb->setObjectName( it.key() );
249 sb->setMaximum( std::numeric_limits<int>::max() ); // the default is 99
250 sb->setValue( opt->defaultValue );
251 control = sb;
252 }
253 break;
254 }
255
257 {
258 QgsVectorFileWriter::SetOption *opt = dynamic_cast<QgsVectorFileWriter::SetOption *>( option );
259 if ( opt )
260 {
261 QComboBox *cb = new QComboBox();
262 cb->setObjectName( it.key() );
263 for ( const QString &val : std::as_const( opt->values ) )
264 {
265 cb->addItem( val, val );
266 }
267 if ( opt->allowNone )
268 cb->addItem( tr( "<Default>" ), QVariant( QVariant::String ) );
269 int idx = cb->findText( opt->defaultValue );
270 if ( idx == -1 )
271 idx = cb->findData( QVariant( QVariant::String ) );
272 cb->setCurrentIndex( idx );
273 control = cb;
274 }
275 break;
276 }
277
279 {
281 if ( opt )
282 {
283 QLineEdit *le = new QLineEdit( opt->defaultValue );
284 le->setObjectName( it.key() );
285 control = le;
286 }
287 break;
288 }
289
291 control = nullptr;
292 break;
293 }
294
295 if ( control )
296 {
297 QLabel *label = new QLabel( it.key() );
298
299 // Pack the tooltip in some html element, so it gets linebreaks.
300 label->setToolTip( QStringLiteral( "<p>%1</p>" ).arg( option->docString.toHtmlEscaped() ) );
301 control->setToolTip( QStringLiteral( "<p>%1</p>" ).arg( option->docString.toHtmlEscaped() ) );
302
303 controls << QPair<QLabel *, QWidget *>( label, control );
304 }
305 }
306
307 return controls;
308}
309
310void QgsVectorLayerSaveAsDialog::accept()
311{
312 if ( QFile::exists( filename() ) )
313 {
314 QgsVectorFileWriter::EditionCapabilities caps =
317 layername() );
318 QMessageBox msgBox;
319 msgBox.setIcon( QMessageBox::Question );
320 msgBox.setWindowTitle( tr( "Save Vector Layer As" ) );
321 QPushButton *overwriteFileButton = msgBox.addButton( tr( "Overwrite File" ), QMessageBox::ActionRole );
322 QPushButton *overwriteLayerButton = msgBox.addButton( tr( "Overwrite Layer" ), QMessageBox::ActionRole );
323 QPushButton *appendToLayerButton = msgBox.addButton( tr( "Append to Layer" ), QMessageBox::ActionRole );
324 msgBox.setStandardButtons( QMessageBox::Cancel );
325 msgBox.setDefaultButton( QMessageBox::Cancel );
326 overwriteFileButton->hide();
327 overwriteLayerButton->hide();
328 appendToLayerButton->hide();
329 if ( layerExists )
330 {
334 {
335 msgBox.setText( tr( "The layer already exists. Do you want to overwrite the whole file or overwrite the layer?" ) );
336 overwriteFileButton->setVisible( true );
337 overwriteLayerButton->setVisible( true );
338 }
340 {
341 msgBox.setText( tr( "The file already exists. Do you want to overwrite it?" ) );
342 overwriteFileButton->setVisible( true );
343 }
344 else if ( ( caps & QgsVectorFileWriter::CanDeleteLayer ) &&
346 {
347 msgBox.setText( tr( "The layer already exists. Do you want to overwrite the whole file, overwrite the layer or append features to the layer?" ) );
348 appendToLayerButton->setVisible( true );
349 overwriteFileButton->setVisible( true );
350 overwriteLayerButton->setVisible( true );
351 }
352 else
353 {
354 msgBox.setText( tr( "The layer already exists. Do you want to overwrite the whole file or append features to the layer?" ) );
355 appendToLayerButton->setVisible( true );
356 overwriteFileButton->setVisible( true );
357 }
358
359 int ret = msgBox.exec();
360 if ( ret == QMessageBox::Cancel )
361 return;
362 if ( msgBox.clickedButton() == overwriteFileButton )
363 mActionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteFile;
364 else if ( msgBox.clickedButton() == overwriteLayerButton )
365 mActionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteLayer;
366 else if ( msgBox.clickedButton() == appendToLayerButton )
367 mActionOnExistingFile = QgsVectorFileWriter::AppendToLayerNoNewFields;
368 }
369 else // !layerExists
370 {
372 {
373 mActionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteLayer;
374 }
375 else
376 {
377 // should not reach here, layer does not exist and cannot add new layer
378 if ( QMessageBox::question( this,
379 tr( "Save Vector Layer As" ),
380 tr( "The file already exists. Do you want to overwrite it?" ) ) == QMessageBox::NoButton )
381 {
382 return;
383 }
384 mActionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteFile;
385 }
386 }
387 }
388
389 if ( mActionOnExistingFile == QgsVectorFileWriter::AppendToLayerNoNewFields )
390 {
392 {
393 if ( QMessageBox::question( this,
394 tr( "Save Vector Layer As" ),
395 tr( "The existing layer has additional fields. Do you want to add the missing fields to the layer?" ) ) == QMessageBox::Yes )
396 {
397 mActionOnExistingFile = QgsVectorFileWriter::AppendToLayerAddFields;
398 }
399 }
400 }
401 else if ( mActionOnExistingFile == QgsVectorFileWriter::CreateOrOverwriteFile && QFile::exists( filename() ) )
402 {
403 const QList<QgsProviderSublayerDetails> sublayers = QgsProviderRegistry::instance()->querySublayers( filename() );
404 QStringList layerList;
405 layerList.reserve( sublayers.size() );
406 for ( const QgsProviderSublayerDetails &sublayer : sublayers )
407 {
408 layerList.append( sublayer.name() );
409 }
410 if ( layerList.length() > 1 )
411 {
412 layerList.sort( Qt::CaseInsensitive );
413 QMessageBox msgBox;
414 msgBox.setIcon( QMessageBox::Warning );
415 msgBox.setWindowTitle( tr( "Overwrite File" ) );
416 msgBox.setText( tr( "This file contains %1 layers that will be lost!\n" ).arg( QLocale().toString( layerList.length() ) ) );
417 msgBox.setDetailedText( tr( "The following layers will be permanently lost:\n\n%1" ).arg( layerList.join( "\n" ) ) );
418 msgBox.setStandardButtons( QMessageBox::Ok | QMessageBox::Cancel );
419 if ( msgBox.exec() == QMessageBox::Cancel )
420 return;
421 }
422 }
423
424 QgsSettings settings;
425 settings.setValue( QStringLiteral( "UI/lastVectorFileFilterDir" ), QFileInfo( filename() ).absolutePath() );
426 settings.setValue( QStringLiteral( "UI/lastVectorFormat" ), format() );
427 settings.setValue( QStringLiteral( "UI/encoding" ), encoding() );
428 QDialog::accept();
429}
430
431void QgsVectorLayerSaveAsDialog::mFormatComboBox_currentIndexChanged( int idx )
432{
433 Q_UNUSED( idx )
434
435 mFilename->setEnabled( true );
436 QString filter = QgsVectorFileWriter::filterForDriver( format() );
437 // A bit of hack to solve https://github.com/qgis/QGIS/issues/54566
438 // to be able to select an existing File Geodatabase, we add in the filter
439 // the "gdb" file that is found in all File Geodatabase .gdb directory
440 // to allow the user to select it. We need to detect this particular case
441 // in QgsFileWidget::openFileDialog() to remove this gdb file from the
442 // selected filename
443 if ( format() == QLatin1String( "OpenFileGDB" ) || format() == QLatin1String( "FileGDB" ) )
444 filter = QStringLiteral( "%1 (*.gdb *.GDB gdb)" ).arg( tr( "ESRI File Geodatabase" ) );
445 mFilename->setFilter( filter );
446
447 // if output filename already defined we need to replace old suffix
448 // to avoid double extensions like .gpkg.shp
449 if ( !mFilename->filePath().isEmpty() )
450 {
451 const thread_local QRegularExpression rx( "\\.(.*?)[\\s]" );
452 const QString ext = rx.match( filter ).captured( 1 );
453 if ( !ext.isEmpty() )
454 {
455 QFileInfo fi( mFilename->filePath() );
456 mFilename->setFilePath( QStringLiteral( "%1/%2.%3" ).arg( fi.path() ).arg( fi.baseName() ).arg( ext ) );
457 }
458 }
459
460 bool selectAllFields = true;
461
462 // Is it a format for which fields that have attached widgets of types
463 // ValueMap, ValueRelation, etc. should be by default exported with their displayed
464 // values
465 bool isFormatForFieldsAsDisplayedValues = false;
466
467 const QString sFormat( format() );
468 if ( sFormat == QLatin1String( "DXF" ) || sFormat == QLatin1String( "DGN" ) )
469 {
470 mAttributesSelection->setVisible( false );
471 selectAllFields = false;
472 }
473 else
474 {
475 if ( mOptions & Fields )
476 {
477 mAttributesSelection->setVisible( true );
478 isFormatForFieldsAsDisplayedValues = ( sFormat == QLatin1String( "CSV" ) ||
479 sFormat == QLatin1String( "XLS" ) ||
480 sFormat == QLatin1String( "XLSX" ) ||
481 sFormat == QLatin1String( "ODS" ) );
482 }
483 }
484
485 // Show symbology options only for some formats
486 if ( QgsVectorFileWriter::supportsFeatureStyles( sFormat ) && ( mOptions & Symbology ) )
487 {
488 mSymbologyExportLabel->setVisible( true );
489 mSymbologyExportComboBox->setVisible( true );
490 mScaleLabel->setVisible( true );
491 mScaleWidget->setVisible( true );
492 }
493 else
494 {
495 mSymbologyExportLabel->hide();
496 mSymbologyExportComboBox->hide();
497 mScaleLabel->hide();
498 mScaleWidget->hide();
499 }
500
501 leLayername->setEnabled( sFormat == QLatin1String( "KML" ) ||
502 sFormat == QLatin1String( "GPKG" ) ||
503 sFormat == QLatin1String( "XLSX" ) ||
504 sFormat == QLatin1String( "ODS" ) ||
505 sFormat == QLatin1String( "FileGDB" ) ||
506 sFormat == QLatin1String( "OpenFileGDB" ) ||
507 sFormat == QLatin1String( "SQLite" ) ||
508 sFormat == QLatin1String( "SpatiaLite" ) );
509
510 if ( sFormat == QLatin1String( "XLSX" ) )
511 leLayername->setMaxLength( 31 );
512 else if ( leLayername->isEnabled() )
513 leLayername->setMaxLength( 32767 ); // default length
514
515 if ( !leLayername->isEnabled() )
516 leLayername->setText( QString() );
517 else if ( leLayername->text().isEmpty() )
518 {
519 QString layerName = mDefaultOutputLayerNameFromInputLayerName;
520 if ( layerName.isEmpty() && !mFilename->filePath().isEmpty() )
521 {
522 layerName = QFileInfo( mFilename->filePath() ).baseName();
523 leLayername->setDefaultValue( layerName );
524 }
525 if ( layerName.isEmpty() )
526 layerName = tr( "new_layer" );
527 leLayername->setText( layerName );
528 }
529
530 if ( mLayer )
531 {
532 mAttributeTable->setRowCount( mLayer->fields().count() );
533
534 QStringList horizontalHeaders = QStringList() << tr( "Name" ) << tr( "Export name" ) << tr( "Type" ) << tr( "Replace with displayed values" );
535 mAttributeTable->setColumnCount( horizontalHeaders.size() );
536 mAttributeTable->setHorizontalHeaderLabels( horizontalHeaders );
537
538 bool foundFieldThatCanBeExportedAsDisplayedValue = false;
539 for ( int i = 0; i < mLayer->fields().size(); ++i )
540 {
541 const QgsEditorWidgetSetup setup = QgsGui::editorWidgetRegistry()->findBest( mLayer, mLayer->fields()[i].name() );
542 if ( setup.type() != QLatin1String( "TextEdit" ) &&
543 QgsGui::editorWidgetRegistry()->factory( setup.type() ) )
544 {
545 foundFieldThatCanBeExportedAsDisplayedValue = true;
546 break;
547 }
548 }
549 mAttributeTable->setColumnHidden( static_cast<int>( ColumnIndex::ExportAsDisplayedValue ),
550 ! foundFieldThatCanBeExportedAsDisplayedValue );
551
552 bool checkReplaceRawFieldValues = selectAllFields && isFormatForFieldsAsDisplayedValues;
553 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
554 {
555 for ( int i = 0; i < mLayer->fields().size(); ++i )
556 {
557 QgsField fld = mLayer->fields().at( i );
558 Qt::ItemFlags flags = mLayer->providerType() != QLatin1String( "oracle" ) || !fld.typeName().contains( QLatin1String( "SDO_GEOMETRY" ) ) ? Qt::ItemIsEnabled : Qt::NoItemFlags;
559 QTableWidgetItem *item = nullptr;
560 item = new QTableWidgetItem( fld.name() );
561 item->setFlags( flags | Qt::ItemIsUserCheckable );
562 item->setCheckState( ( selectAllFields ) ? Qt::Checked : Qt::Unchecked );
563 mAttributeTable->setItem( i, static_cast<int>( ColumnIndex::Name ), item );
564
565 item = new QTableWidgetItem( fld.name() );
566 item->setFlags( flags | Qt::ItemIsEditable );
567 item->setData( Qt::UserRole, fld.displayName() );
568 mAttributeTable->setItem( i, static_cast<int>( ColumnIndex::ExportName ), item );
569
570 item = new QTableWidgetItem( fld.typeName() );
571 item->setFlags( flags );
572 mAttributeTable->setItem( i, static_cast<int>( ColumnIndex::Type ), item );
573
574 if ( foundFieldThatCanBeExportedAsDisplayedValue )
575 {
576 const QgsEditorWidgetSetup setup = QgsGui::editorWidgetRegistry()->findBest( mLayer, mLayer->fields()[i].name() );
577 QgsEditorWidgetFactory *factory = nullptr;
578 const QString widgetId( setup.type() );
579 if ( flags == Qt::ItemIsEnabled &&
580 widgetId != QLatin1String( "TextEdit" ) &&
581 ( factory = QgsGui::editorWidgetRegistry()->factory( widgetId ) ) )
582 {
583 item = new QTableWidgetItem( tr( "Use %1" ).arg( factory->name() ) );
584 item->setFlags( ( selectAllFields ) ? ( Qt::ItemIsEnabled | Qt::ItemIsUserCheckable ) : Qt::ItemIsUserCheckable );
585 const bool checkItem = ( selectAllFields && isFormatForFieldsAsDisplayedValues &&
586 ( widgetId == QLatin1String( "ValueMap" ) ||
587 widgetId == QLatin1String( "ValueRelation" ) ||
588 widgetId == QLatin1String( "CheckBox" ) ||
589 widgetId == QLatin1String( "RelationReference" ) ) );
590 checkReplaceRawFieldValues &= checkItem;
591 item->setCheckState( checkItem ?
592 Qt::Checked : Qt::Unchecked );
593 mAttributeTable->setItem( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ), item );
594 }
595 else
596 {
597 item = new QTableWidgetItem();
598 item->setFlags( Qt::NoItemFlags );
599 mAttributeTable->setItem( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ), item );
600 }
601 }
602 }
603 }
604
605 whileBlocking( mReplaceRawFieldValues )->setChecked( checkReplaceRawFieldValues );
606 mReplaceRawFieldValues->setEnabled( selectAllFields );
607 mReplaceRawFieldValues->setVisible( foundFieldThatCanBeExportedAsDisplayedValue );
608
609 mAttributeTable->resizeColumnsToContents();
610 }
611
612 QgsVectorFileWriter::MetaData driverMetaData;
613
614 while ( mDatasourceOptionsGroupBox->layout()->count() )
615 {
616 QLayoutItem *item = mDatasourceOptionsGroupBox->layout()->takeAt( 0 );
617 delete item->widget();
618 delete item;
619 }
620
621 while ( mLayerOptionsGroupBox->layout()->count() )
622 {
623 QLayoutItem *item = mLayerOptionsGroupBox->layout()->takeAt( 0 );
624 delete item->widget();
625 delete item;
626 }
627
628 typedef QPair<QLabel *, QWidget *> LabelControlPair;
629
630 if ( QgsVectorFileWriter::driverMetadata( format(), driverMetaData ) )
631 {
632 if ( !driverMetaData.driverOptions.empty() )
633 {
634 mDatasourceOptionsGroupBox->setVisible( true );
635 QList<QPair<QLabel *, QWidget *> > controls = createControls( driverMetaData.driverOptions );
636
637 QFormLayout *datasourceLayout = dynamic_cast<QFormLayout *>( mDatasourceOptionsGroupBox->layout() );
638
639 const auto constControls = controls;
640 for ( LabelControlPair control : constControls )
641 {
642 datasourceLayout->addRow( control.first, control.second );
643 }
644 }
645 else
646 {
647 mDatasourceOptionsGroupBox->setVisible( false );
648 }
649
650 if ( !driverMetaData.layerOptions.empty() )
651 {
652 mLayerOptionsGroupBox->setVisible( true );
653 QList<QPair<QLabel *, QWidget *> > controls = createControls( driverMetaData.layerOptions );
654
655 QFormLayout *layerOptionsLayout = dynamic_cast<QFormLayout *>( mLayerOptionsGroupBox->layout() );
656
657 const auto constControls = controls;
658 for ( LabelControlPair control : constControls )
659 {
660 layerOptionsLayout->addRow( control.first, control.second );
661 }
662 }
663 else
664 {
665 mLayerOptionsGroupBox->setVisible( false );
666 }
667
668 if ( driverMetaData.compulsoryEncoding.isEmpty() )
669 {
670 mEncodingComboBox->setEnabled( true );
671 }
672 else
673 {
674 int idx = mEncodingComboBox->findText( driverMetaData.compulsoryEncoding );
675 if ( idx >= 0 )
676 {
677 mEncodingComboBox->setCurrentIndex( idx );
678 mEncodingComboBox->setDisabled( true );
679 }
680 else
681 {
682 mEncodingComboBox->setEnabled( true );
683 }
684 }
685
686 }
687 else
688 {
689 mEncodingComboBox->setEnabled( true );
690 }
691
692 GDALDriverH hDriver = GDALGetDriverByName( format().toUtf8().constData() );
693 if ( hDriver )
694 {
695 mAddToCanvas->setEnabled( GDALGetMetadataItem( hDriver, GDAL_DCAP_OPEN, nullptr ) != nullptr );
696 }
697}
698
699void QgsVectorLayerSaveAsDialog::mUseAliasesForExportedName_stateChanged( int state )
700{
701 const QSignalBlocker signalBlocker( mAttributeTable );
702
703 switch ( state )
704 {
705 case Qt::Unchecked:
706 {
707 // Check for modified entries
708 bool modifiedEntries = false;
709 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
710 {
711 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportName ) )->text()
712 != mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportName ) )->data( Qt::UserRole ).toString() )
713 {
714 modifiedEntries = true;
715 break;
716 }
717 }
718
719 if ( modifiedEntries )
720 {
721 if ( QMessageBox::question( this,
722 tr( "Modified names" ),
723 tr( "Some names were modified and will be overridden. Do you want to continue?" ) )
724 == QMessageBox::No )
725 {
726 whileBlocking( mUseAliasesForExportedName )->setCheckState( Qt::PartiallyChecked );
727 return;
728 }
729 }
730
731 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
732 {
733 mUseAliasesForExportedName->setTristate( false );
734 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportName ) )->setText( mAttributeTable->item( i, static_cast<int>( ColumnIndex::Name ) )->text() );
735 }
736 }
737 break;
738 case Qt::Checked:
739 {
740 // Check for modified entries
741 bool modifiedEntries = false;
742 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
743 {
744 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportName ) )->text()
745 != mAttributeTable->item( i, static_cast<int>( ColumnIndex::Name ) )->text() )
746 modifiedEntries = true;
747 }
748
749 if ( modifiedEntries )
750 {
751 if ( QMessageBox::question( this,
752 tr( "Modified names" ),
753 tr( "Some names were modified and will be overridden. Do you want to continue?" ) )
754 == QMessageBox::No )
755 {
756 whileBlocking( mUseAliasesForExportedName )->setCheckState( Qt::PartiallyChecked );
757 return;
758 }
759 }
760
761 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
762 {
763 mUseAliasesForExportedName->setTristate( false );
764 const QString alias = mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportName ) )->data( Qt::UserRole ).toString();
765 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportName ) )->setText( alias );
766 }
767 }
768 break;
769 case Qt::PartiallyChecked:
770 // Do nothing
771 break;
772 }
773}
774
775void QgsVectorLayerSaveAsDialog::mReplaceRawFieldValues_stateChanged( int )
776{
777 if ( mAttributeTable->isColumnHidden( static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
778 return;
779
780 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
781 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
782
783 if ( mReplaceRawFieldValues->checkState() != Qt::PartiallyChecked )
784 {
785 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
786 {
787 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::Name ) )->checkState() == Qt::Checked &&
788 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
789 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsEnabled )
790 {
791 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( mReplaceRawFieldValues->checkState() );
792 }
793 }
794 }
795 mReplaceRawFieldValues->setTristate( false );
796}
797
798void QgsVectorLayerSaveAsDialog::mAttributeTable_itemChanged( QTableWidgetItem *item )
799{
800 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
801 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
802
803 int row = item->row();
804 int column = item->column();
805
806 switch ( static_cast<ColumnIndex>( column ) )
807 {
808 case ColumnIndex::Name:
809 {
810 if ( mAttributeTable->isColumnHidden( static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) ||
811 ! mAttributeTable->item( row, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) ||
812 !( mAttributeTable->item( row, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsUserCheckable ) )
813 return;
814
815 if ( mAttributeTable->item( row, column )->checkState() == Qt::Unchecked )
816 {
817 mAttributeTable->item( row, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( Qt::Unchecked );
818 mAttributeTable->item( row, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable );
819 bool checkBoxEnabled = false;
820 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
821 {
822 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
823 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsEnabled )
824 {
825 checkBoxEnabled = true;
826 break;
827 }
828 }
829 mReplaceRawFieldValues->setEnabled( checkBoxEnabled );
830 if ( !checkBoxEnabled )
831 mReplaceRawFieldValues->setCheckState( Qt::Unchecked );
832 }
833 else if ( mAttributeTable->item( row, column )->checkState() == Qt::Checked )
834 {
835 mAttributeTable->item( row, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsEnabled );
836 mReplaceRawFieldValues->setEnabled( true );
837 }
838 }
839 break;
840 case ColumnIndex::ExportName:
841 {
842 // Check empty export name
843 if ( item->text().isEmpty() )
844 {
845 QMessageBox::warning( this,
846 tr( "Empty export name" ),
847 tr( "Empty export name are not allowed." ) );
848 return;
849 }
850
851 // Rename eventually duplicated names
852 QStringList names = attributesExportNames();
853 while ( names.count( item->text() ) > 1 )
854 item->setText( QString( "%1_2" ).arg( item->text() ) );
855
856 mUseAliasesForExportedName->setCheckState( Qt::PartiallyChecked );
857 }
858 break;
859 case ColumnIndex::Type:
860 // Nothing to do
861 break;
862 case ColumnIndex::ExportAsDisplayedValue:
863 {
864 if ( mAttributeTable->item( row, column )->flags() & Qt::ItemIsUserCheckable )
865 {
866 bool allChecked = true;
867 bool allUnchecked = true;
868 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
869 {
870 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
871 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsEnabled )
872 {
873 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->checkState() == Qt::Unchecked )
874 allChecked = false;
875 else
876 allUnchecked = false;
877 }
878 }
879 mReplaceRawFieldValues->setCheckState( ( !allChecked && !allUnchecked ) ? Qt::PartiallyChecked : ( allChecked ) ? Qt::Checked : Qt::Unchecked );
880 }
881 }
882 break;
883 }
884}
885
886void QgsVectorLayerSaveAsDialog::mCrsSelector_crsChanged( const QgsCoordinateReferenceSystem &crs )
887{
888 mSelectedCrs = crs;
889 mExtentGroupBox->setOutputCrs( mSelectedCrs );
890}
891
893{
894 return mFilename->filePath();
895}
896
898{
899 return leLayername->text();
900}
901
903{
904 return mEncodingComboBox->currentText();
905}
906
908{
909 return mFormatComboBox->currentData().toString();
910}
911
913{
914 return mSelectedCrs.srsid();
915}
916
921
923{
924 QStringList options;
925
926 QgsVectorFileWriter::MetaData driverMetaData;
927
928 if ( QgsVectorFileWriter::driverMetadata( format(), driverMetaData ) )
929 {
930 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
931
932 for ( it = driverMetaData.driverOptions.constBegin(); it != driverMetaData.driverOptions.constEnd(); ++it )
933 {
934 switch ( it.value()->type )
935 {
937 {
939 QSpinBox *sb = mDatasourceOptionsGroupBox->findChild<QSpinBox *>( it.key() );
940 if ( opt && sb && sb->value() != opt->defaultValue )
941 options << QStringLiteral( "%1=%2" ).arg( it.key() ).arg( sb->value() );
942 break;
943 }
944
946 {
948 QComboBox *cb = mDatasourceOptionsGroupBox->findChild<QComboBox *>( it.key() );
949 if ( opt && cb && cb->itemData( cb->currentIndex() ) != opt->defaultValue )
950 options << QStringLiteral( "%1=%2" ).arg( it.key(), cb->currentText() );
951 break;
952 }
953
955 {
957 QLineEdit *le = mDatasourceOptionsGroupBox->findChild<QLineEdit *>( it.key() );
958 if ( opt && le && le->text() != opt->defaultValue )
959 options << QStringLiteral( "%1=%2" ).arg( it.key(), le->text() );
960 break;
961 }
962
964 {
966 dynamic_cast<QgsVectorFileWriter::HiddenOption *>( it.value() );
967 if ( !opt->mValue.isEmpty() )
968 options << QStringLiteral( "%1=%2" ).arg( it.key(), opt->mValue );
969 break;
970 }
971 }
972 }
973 }
974
975 QString plainText = mOgrDatasourceOptions->toPlainText().trimmed();
976 if ( !plainText.isEmpty() )
977 options += plainText.split( '\n' );
978
979 return options;
980}
981
983{
984 QStringList options;
985
986 QgsVectorFileWriter::MetaData driverMetaData;
987
988 if ( QgsVectorFileWriter::driverMetadata( format(), driverMetaData ) )
989 {
990 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
991
992 for ( it = driverMetaData.layerOptions.constBegin(); it != driverMetaData.layerOptions.constEnd(); ++it )
993 {
994 switch ( it.value()->type )
995 {
997 {
999 QSpinBox *sb = mLayerOptionsGroupBox->findChild<QSpinBox *>( it.key() );
1000 if ( opt && sb && sb->value() != opt->defaultValue )
1001 options << QStringLiteral( "%1=%2" ).arg( it.key() ).arg( sb->value() );
1002 break;
1003 }
1004
1006 {
1008 QComboBox *cb = mLayerOptionsGroupBox->findChild<QComboBox *>( it.key() );
1009 if ( opt && cb && cb->itemData( cb->currentIndex() ) != opt->defaultValue )
1010 options << QStringLiteral( "%1=%2" ).arg( it.key(), cb->currentText() );
1011 break;
1012 }
1013
1015 {
1017 QLineEdit *le = mLayerOptionsGroupBox->findChild<QLineEdit *>( it.key() );
1018 if ( opt && le && le->text() != opt->defaultValue )
1019 options << QStringLiteral( "%1=%2" ).arg( it.key(), le->text() );
1020 break;
1021 }
1022
1024 {
1026 dynamic_cast<QgsVectorFileWriter::HiddenOption *>( it.value() );
1027 if ( !opt->mValue.isEmpty() )
1028 options << QStringLiteral( "%1=%2" ).arg( it.key(), opt->mValue );
1029 break;
1030 }
1031 }
1032 }
1033 }
1034
1035 QString plainText = mOgrLayerOptions->toPlainText().trimmed();
1036 if ( !plainText.isEmpty() )
1037 options += plainText.split( '\n' );
1038
1039 return options;
1040}
1041
1043{
1044 QgsAttributeList attributes;
1045
1046 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
1047 {
1048 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::Name ) )->checkState() == Qt::Checked )
1049 {
1050 attributes.append( i );
1051 }
1052 }
1053
1054 return attributes;
1055}
1056
1058{
1059 QgsAttributeList attributes;
1060
1061 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
1062 {
1063 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::Name ) )->checkState() == Qt::Checked &&
1064 ! mAttributeTable->isColumnHidden( static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
1065 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->checkState() == Qt::Checked )
1066 {
1067 attributes.append( i );
1068 }
1069 }
1070
1071 return attributes;
1072}
1073
1075{
1076 QStringList exportNames;
1077 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
1078 exportNames.append( mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportName ) )->text() );
1079
1080 return exportNames;
1081}
1082
1084{
1085 return mAddToCanvas->isChecked() && mAddToCanvas->isEnabled();
1086}
1087
1089{
1090 mAddToCanvas->setChecked( enabled );
1091}
1092
1094{
1095 return mSymbologyExportComboBox->currentData().toInt();
1096}
1097
1099{
1100 return mScaleWidget->scale();
1101}
1102
1104{
1105 mMapCanvas = canvas;
1106 mScaleWidget->setMapCanvas( canvas );
1107 mScaleWidget->setShowCurrentScaleButton( true );
1108 mExtentGroupBox->setCurrentExtent( canvas->mapSettings().visibleExtent(), canvas->mapSettings().destinationCrs() );
1109}
1110
1112{
1113 return mExtentGroupBox->isChecked();
1114}
1115
1117{
1118 return mExtentGroupBox->outputExtent();
1119}
1120
1122{
1123 mSelectedOnly->setChecked( onlySelected );
1124}
1125
1127{
1128 return mSelectedOnly->isChecked();
1129}
1130
1132{
1133 return mCheckPersistMetadata->isChecked();
1134}
1135
1137{
1138 int currentIndexData = mGeometryTypeComboBox->currentData().toInt();
1139 if ( currentIndexData == -1 )
1140 {
1141 //automatic
1142 return QgsWkbTypes::Unknown;
1143 }
1144
1145 return static_cast< QgsWkbTypes::Type >( currentIndexData );
1146}
1147
1149{
1150 int currentIndexData = mGeometryTypeComboBox->currentData().toInt();
1151 return currentIndexData == -1;
1152}
1153
1155{
1156 return mForceMultiCheckBox->isChecked();
1157}
1158
1160{
1161 mForceMultiCheckBox->setChecked( checked );
1162}
1163
1165{
1166 return mIncludeZCheckBox->isChecked();
1167}
1168
1173
1175{
1176 mIncludeZCheckBox->setChecked( checked );
1177}
1178
1179void QgsVectorLayerSaveAsDialog::mSymbologyExportComboBox_currentIndexChanged( const QString &text )
1180{
1181 bool scaleEnabled = true;
1182 if ( text == tr( "No symbology" ) )
1183 {
1184 scaleEnabled = false;
1185 }
1186 mScaleWidget->setEnabled( scaleEnabled );
1187 mScaleLabel->setEnabled( scaleEnabled );
1188}
1189
1190void QgsVectorLayerSaveAsDialog::mGeometryTypeComboBox_currentIndexChanged( int index )
1191{
1192 int currentIndexData = mGeometryTypeComboBox->itemData( index ).toInt();
1193
1194 if ( currentIndexData != -1 && currentIndexData != QgsWkbTypes::NoGeometry )
1195 {
1196 mForceMultiCheckBox->setEnabled( true );
1197 mIncludeZCheckBox->setEnabled( true );
1198 }
1199 else
1200 {
1201 mForceMultiCheckBox->setEnabled( false );
1202 mForceMultiCheckBox->setChecked( false );
1203 mIncludeZCheckBox->setEnabled( false );
1204 mIncludeZCheckBox->setChecked( false );
1205 }
1206}
1207
1208void QgsVectorLayerSaveAsDialog::mSelectAllAttributes_clicked()
1209{
1210 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
1211 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
1212
1213 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
1214 {
1215 if ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::Name ) )->flags() & Qt::ItemIsEnabled )
1216 {
1217 if ( ! mAttributeTable->isColumnHidden( static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
1218 ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsUserCheckable ) )
1219 {
1220 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsEnabled );
1221 }
1222 mAttributeTable->item( i, static_cast<int>( ColumnIndex::Name ) )->setCheckState( Qt::Checked );
1223 }
1224 }
1225 if ( ! mAttributeTable->isColumnHidden( static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
1226 {
1227 mReplaceRawFieldValues->setEnabled( true );
1228 }
1229}
1230
1231void QgsVectorLayerSaveAsDialog::mDeselectAllAttributes_clicked()
1232{
1233 const QSignalBlocker signalBlockerAttributeTable( mAttributeTable );
1234 const QSignalBlocker signalBlockerReplaceRawFieldValues( mReplaceRawFieldValues );
1235
1236 for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
1237 {
1238 mAttributeTable->item( i, static_cast<int>( ColumnIndex::Name ) )->setCheckState( Qt::Unchecked );
1239 if ( ! mAttributeTable->isColumnHidden( static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) &&
1240 ( mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->flags() & Qt::ItemIsUserCheckable ) )
1241 {
1242 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setFlags( Qt::ItemIsUserCheckable );
1243 mAttributeTable->item( i, static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) )->setCheckState( Qt::Unchecked );
1244 }
1245 }
1246 if ( ! mAttributeTable->isColumnHidden( static_cast<int>( ColumnIndex::ExportAsDisplayedValue ) ) )
1247 {
1248 mReplaceRawFieldValues->setCheckState( Qt::Unchecked );
1249 mReplaceRawFieldValues->setEnabled( false );
1250 }
1251}
1252
1253void QgsVectorLayerSaveAsDialog::showHelp()
1254{
1255 QgsHelp::openHelp( QStringLiteral( "managing_data_source/create_layers.html#creating-new-layers-from-an-existing-layer" ) );
1256}
This class represents a coordinate reference system (CRS).
QgsDatumEnsemble datumEnsemble() const
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.
Definition qgsdatums.h:95
bool isValid() const
Returns true if the datum ensemble is a valid object, or false if it is a null/invalid object.
Definition qgsdatums.h:102
QString name() const
Display name of datum ensemble.
Definition qgsdatums.h:107
Every attribute editor widget needs a factory, which inherits this class.
QString name() const
Returns The human readable identifier name of this widget type.
QgsEditorWidgetSetup findBest(const QgsVectorLayer *vl, const QString &fieldName) const
Find the best editor widget and its configuration for a given field.
Holder for the widget type and its configuration for a field.
Encapsulate a field in an attribute table or data source.
Definition qgsfield.h:51
QString typeName() const
Gets the field type.
Definition qgsfield.cpp:152
QString name
Definition qgsfield.h:60
QString displayName() const
Returns the name to use when displaying this field.
Definition qgsfield.cpp:90
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).
@ SaveFile
Select a single new or pre-existing file.
void fileChanged(const QString &path)
Emitted whenever the current file or directory path is changed.
@ 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.
Definition qgsgui.cpp:83
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...
Definition qgsgui.cpp:178
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition qgshelp.cpp:38
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.
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 name
Definition qgsmaplayer.h:76
QString providerType() const
Returns the provider type (provider key) for this layer.
QgsCoordinateReferenceSystem crs
Definition qgsmaplayer.h:79
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.
void crsChanged(const QgsCoordinateReferenceSystem &)
Emitted when the selected CRS is changed.
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:
Definition qgssettings.h:62
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.
@ SelectedOnly
Show selected features only option.
@ Fields
Show field customization 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.
Type
The WKB type describes the number of dimensions a geometry has.
Definition qgswkbtypes.h:70
static QString translatedDisplayString(Type 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.
Definition qgis.h:2453
QList< int > QgsAttributeList
Definition qgsfield.h:26
const QgsCoordinateReferenceSystem & crs
Details of available driver formats.
QMap< QString, QgsVectorFileWriter::Option * > driverOptions
QMap< QString, QgsVectorFileWriter::Option * > layerOptions
QString compulsoryEncoding
Some formats require a compulsory encoding, typically UTF-8. If no compulsory encoding,...