QGIS API Documentation 3.29.0-Master (da8bb1db43)
qgsnewgeopackagelayerdialog.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsnewgeopackagelayerdialog.cpp
3
4 -------------------
5 begin : April 2016
6 copyright : (C) 2016 by Even Rouault
7 email : even.rouault at spatialys.com
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
19
21
22#include "qgis.h"
23#include "qgsapplication.h"
24#include "qgsproviderregistry.h"
25#include "qgsvectorlayer.h"
26#include "qgsproject.h"
29#include "qgslogger.h"
30#include "qgssettings.h"
31#include "qgshelp.h"
32#include "qgsogrutils.h"
33#include "qgsgui.h"
35#include "qgsiconutils.h"
36#include "qgsvariantutils.h"
37
38#include <QPushButton>
39#include <QLineEdit>
40#include <QMessageBox>
41#include <QFileDialog>
42#include <QCompleter>
43
44#include <ogr_api.h>
45#include <ogr_srs_api.h>
46#include <gdal_version.h>
47#include <cpl_error.h>
48#include <cpl_string.h>
49
50#define DEFAULT_OGR_FID_COLUMN_TITLE "fid" // default value from OGR
51
53 : QDialog( parent, fl )
54{
55 setupUi( this );
56 setObjectName( QStringLiteral( "QgsNewGeoPackageLayerDialog" ) );
58
59 connect( mAddAttributeButton, &QToolButton::clicked, this, &QgsNewGeoPackageLayerDialog::mAddAttributeButton_clicked );
60 connect( mRemoveAttributeButton, &QToolButton::clicked, this, &QgsNewGeoPackageLayerDialog::mRemoveAttributeButton_clicked );
61 connect( mFieldTypeBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsNewGeoPackageLayerDialog::mFieldTypeBox_currentIndexChanged );
62 connect( mGeometryTypeBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsNewGeoPackageLayerDialog::mGeometryTypeBox_currentIndexChanged );
63 connect( mTableNameEdit, &QLineEdit::textChanged, this, &QgsNewGeoPackageLayerDialog::mTableNameEdit_textChanged );
64 connect( mTableNameEdit, &QLineEdit::textEdited, this, &QgsNewGeoPackageLayerDialog::mTableNameEdit_textEdited );
65 connect( mLayerIdentifierEdit, &QLineEdit::textEdited, this, &QgsNewGeoPackageLayerDialog::mLayerIdentifierEdit_textEdited );
66 connect( buttonBox, &QDialogButtonBox::accepted, this, &QgsNewGeoPackageLayerDialog::buttonBox_accepted );
67 connect( buttonBox, &QDialogButtonBox::rejected, this, &QgsNewGeoPackageLayerDialog::buttonBox_rejected );
68 connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsNewGeoPackageLayerDialog::showHelp );
69
70 mAddAttributeButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionNewAttribute.svg" ) ) );
71 mRemoveAttributeButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionDeleteAttribute.svg" ) ) );
72
73 const auto addGeomItem = [this]( OGRwkbGeometryType ogrGeomType )
74 {
76 mGeometryTypeBox->addItem( QgsIconUtils::iconForWkbType( qgsType ), QgsWkbTypes::translatedDisplayString( qgsType ), ogrGeomType );
77 };
78
79 addGeomItem( wkbNone );
80 addGeomItem( wkbPoint );
81 addGeomItem( wkbLineString );
82 addGeomItem( wkbPolygon );
83 addGeomItem( wkbMultiPoint );
84 addGeomItem( wkbMultiLineString );
85 addGeomItem( wkbMultiPolygon );
86
87#if 0
88 // QGIS always create CompoundCurve and there's no real interest of having just CircularString. CompoundCurve are more useful
89 addGeomItem( wkbCircularString );
90#endif
91 addGeomItem( wkbCompoundCurve );
92 addGeomItem( wkbCurvePolygon );
93 addGeomItem( wkbMultiCurve );
94 addGeomItem( wkbMultiSurface );
95 mGeometryTypeBox->setCurrentIndex( -1 );
96
97 mGeometryWithZCheckBox->setEnabled( false );
98 mGeometryWithMCheckBox->setEnabled( false );
99 mGeometryColumnEdit->setEnabled( false );
100 mGeometryColumnEdit->setText( QStringLiteral( "geometry" ) );
101 mFeatureIdColumnEdit->setPlaceholderText( QStringLiteral( DEFAULT_OGR_FID_COLUMN_TITLE ) );
102 mCheckBoxCreateSpatialIndex->setEnabled( false );
103 mCrsSelector->setEnabled( false );
104 mCrsSelector->setShowAccuracyWarnings( true );
105
106 mFieldTypeBox->addItem( QgsFields::iconForFieldType( QVariant::String ), QgsVariantUtils::typeToDisplayString( QVariant::String ), "text" );
107 mFieldTypeBox->addItem( QgsFields::iconForFieldType( QVariant::Int ), QgsVariantUtils::typeToDisplayString( QVariant::Int ), "integer" );
108 mFieldTypeBox->addItem( QgsFields::iconForFieldType( QVariant::LongLong ), QgsVariantUtils::typeToDisplayString( QVariant::LongLong ), "integer64" );
109 mFieldTypeBox->addItem( QgsFields::iconForFieldType( QVariant::Double ), QgsVariantUtils::typeToDisplayString( QVariant::Double ), "real" );
110 mFieldTypeBox->addItem( QgsFields::iconForFieldType( QVariant::Date ), QgsVariantUtils::typeToDisplayString( QVariant::Date ), "date" );
111 mFieldTypeBox->addItem( QgsFields::iconForFieldType( QVariant::DateTime ), QgsVariantUtils::typeToDisplayString( QVariant::DateTime ), "datetime" );
112 mFieldTypeBox->addItem( QgsFields::iconForFieldType( QVariant::Bool ), QgsVariantUtils::typeToDisplayString( QVariant::Bool ), "bool" );
113 mFieldTypeBox->addItem( QgsFields::iconForFieldType( QVariant::ByteArray ), QgsVariantUtils::typeToDisplayString( QVariant::ByteArray ), "binary" );
114 mFieldTypeBox->addItem( QgsFields::iconForFieldType( QVariant::Map ), tr( "JSON" ), "json" );
115
116 mOkButton = buttonBox->button( QDialogButtonBox::Ok );
117 mOkButton->setEnabled( false );
118
119 connect( mFieldNameEdit, &QLineEdit::textChanged, this, &QgsNewGeoPackageLayerDialog::fieldNameChanged );
120 connect( mAttributeView, &QTreeWidget::itemSelectionChanged, this, &QgsNewGeoPackageLayerDialog::selectionChanged );
121 connect( mTableNameEdit, &QLineEdit::textChanged, this, &QgsNewGeoPackageLayerDialog::checkOk );
122 connect( mGeometryTypeBox, static_cast<void( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsNewGeoPackageLayerDialog::checkOk );
123
124 mAddAttributeButton->setEnabled( false );
125 mRemoveAttributeButton->setEnabled( false );
126
127 mCheckBoxCreateSpatialIndex->setChecked( true );
128
129 const QgsSettings settings;
130 mDatabase->setStorageMode( QgsFileWidget::SaveFile );
131 mDatabase->setFilter( tr( "GeoPackage" ) + " (*.gpkg)" );
132 mDatabase->setDialogTitle( tr( "Select Existing or Create a New GeoPackage Database File…" ) );
133 mDatabase->setDefaultRoot( settings.value( QStringLiteral( "UI/lastVectorFileFilterDir" ), QDir::homePath() ).toString() );
134 mDatabase->setConfirmOverwrite( false );
135 connect( mDatabase, &QgsFileWidget::fileChanged, this, [ = ]( const QString & filePath )
136 {
137 QgsSettings settings;
138 const QFileInfo tmplFileInfo( filePath );
139 settings.setValue( QStringLiteral( "UI/lastVectorFileFilterDir" ), tmplFileInfo.absolutePath() );
140 if ( !filePath.isEmpty() && !mTableNameEdited )
141 {
142 const QFileInfo fileInfo( filePath );
143 mTableNameEdit->setText( fileInfo.baseName() );
144 }
145 checkOk();
146 } );
147
148 QgsProviderConnectionModel *ogrProviderModel = new QgsProviderConnectionModel( QStringLiteral( "ogr" ), this );
149
150 QCompleter *completer = new QCompleter( this );
151 completer->setModel( ogrProviderModel );
152 completer->setCompletionRole( QgsProviderConnectionModel::RoleUri );
153 completer->setCompletionMode( QCompleter::PopupCompletion );
154 completer->setFilterMode( Qt::MatchContains );
155 mDatabase->lineEdit()->setCompleter( completer );
156}
157
159{
160 mCrsSelector->setCrs( crs );
161}
162
164{
165 mDatabase->setReadOnly( true );
166}
167
168void QgsNewGeoPackageLayerDialog::mFieldTypeBox_currentIndexChanged( int )
169{
170 const QString myType = mFieldTypeBox->currentData( Qt::UserRole ).toString();
171 mFieldLengthEdit->setEnabled( myType == QLatin1String( "text" ) );
172 if ( myType != QLatin1String( "text" ) )
173 mFieldLengthEdit->clear();
174}
175
176
177void QgsNewGeoPackageLayerDialog::mGeometryTypeBox_currentIndexChanged( int )
178{
179 const OGRwkbGeometryType geomType = static_cast<OGRwkbGeometryType>
180 ( mGeometryTypeBox->currentData( Qt::UserRole ).toInt() );
181 const bool isSpatial = geomType != wkbNone;
182 mGeometryWithZCheckBox->setEnabled( isSpatial );
183 mGeometryWithMCheckBox->setEnabled( isSpatial );
184 mGeometryColumnEdit->setEnabled( isSpatial );
185 mCheckBoxCreateSpatialIndex->setEnabled( isSpatial );
186 mCrsSelector->setEnabled( isSpatial );
187}
188
189void QgsNewGeoPackageLayerDialog::mTableNameEdit_textChanged( const QString &text )
190{
191 mTableNameEdited = !text.isEmpty();
192 if ( !text.isEmpty() && !mLayerIdentifierEdited )
193 {
194 mLayerIdentifierEdit->setText( text );
195 }
196}
197
198void QgsNewGeoPackageLayerDialog::mTableNameEdit_textEdited( const QString &text )
199{
200 // Remember if the user explicitly defined a name
201 mTableNameEdited = !text.isEmpty();
202}
203
204void QgsNewGeoPackageLayerDialog::mLayerIdentifierEdit_textEdited( const QString &text )
205{
206 // Remember if the user explicitly defined a name
207 mLayerIdentifierEdited = !text.isEmpty();
208}
209
210void QgsNewGeoPackageLayerDialog::checkOk()
211{
212 const bool ok = !mDatabase->filePath().isEmpty() &&
213 !mTableNameEdit->text().isEmpty() &&
214 mGeometryTypeBox->currentIndex() != -1;
215
216 mOkButton->setEnabled( ok );
217}
218
219void QgsNewGeoPackageLayerDialog::mAddAttributeButton_clicked()
220{
221 if ( !mFieldNameEdit->text().isEmpty() )
222 {
223 const QString myName = mFieldNameEdit->text();
224 const QString featureId = mFeatureIdColumnEdit->text().isEmpty() ? QStringLiteral( DEFAULT_OGR_FID_COLUMN_TITLE ) : mFeatureIdColumnEdit->text();
225 if ( myName.compare( featureId, Qt::CaseInsensitive ) == 0 )
226 {
227 QMessageBox::critical( this, tr( "Add Field" ), tr( "The field cannot have the same name as the feature identifier." ) );
228 return;
229 }
230
231 //use userrole to avoid translated type string
232 const QString myType = mFieldTypeBox->currentData( Qt::UserRole ).toString();
233 const QString length = mFieldLengthEdit->text();
234 mAttributeView->addTopLevelItem( new QTreeWidgetItem( QStringList() << myName << myType << length ) );
235
236 checkOk();
237
238 mFieldNameEdit->clear();
239 }
240}
241
242void QgsNewGeoPackageLayerDialog::mRemoveAttributeButton_clicked()
243{
244 delete mAttributeView->currentItem();
245
246 checkOk();
247}
248
249void QgsNewGeoPackageLayerDialog::fieldNameChanged( const QString &name )
250{
251 mAddAttributeButton->setDisabled( name.isEmpty() || ! mAttributeView->findItems( name, Qt::MatchExactly ).isEmpty() );
252}
253
254void QgsNewGeoPackageLayerDialog::selectionChanged()
255{
256 mRemoveAttributeButton->setDisabled( mAttributeView->selectedItems().isEmpty() );
257}
258
259void QgsNewGeoPackageLayerDialog::buttonBox_accepted()
260{
261 if ( apply() )
262 accept();
263}
264
265void QgsNewGeoPackageLayerDialog::buttonBox_rejected()
266{
267 reject();
268}
269
270bool QgsNewGeoPackageLayerDialog::apply()
271{
272 if ( !mFieldNameEdit->text().trimmed().isEmpty() )
273 {
274 const QString currentFieldName = mFieldNameEdit->text();
275 bool currentFound = false;
276 QTreeWidgetItemIterator it( mAttributeView );
277 while ( *it )
278 {
279 QTreeWidgetItem *item = *it;
280 if ( item->text( 0 ) == currentFieldName )
281 {
282 currentFound = true;
283 break;
284 }
285 ++it;
286 }
287
288 if ( !currentFound )
289 {
290 if ( QMessageBox::question( this, windowTitle(),
291 tr( "The field “%1” has not been added to the fields list. Are you sure you want to proceed and discard this field?" ).arg( currentFieldName ),
292 QMessageBox::Ok | QMessageBox::Cancel ) != QMessageBox::Ok )
293 {
294 return false;
295 }
296 }
297 }
298
299 QString fileName( mDatabase->filePath() );
300 if ( !fileName.endsWith( QLatin1String( ".gpkg" ), Qt::CaseInsensitive ) )
301 fileName += QLatin1String( ".gpkg" );
302
303 bool createNewDb = false;
304
305 if ( QFile::exists( fileName ) )
306 {
307 bool overwrite = false;
308
309 switch ( mBehavior )
310 {
311 case Prompt:
312 {
313 QMessageBox msgBox;
314 msgBox.setIcon( QMessageBox::Question );
315 msgBox.setWindowTitle( tr( "New GeoPackage Layer" ) );
316 msgBox.setText( tr( "The File already exists. Do you want to overwrite the existing file with a new database or add a new layer to it?" ) );
317 QPushButton *overwriteButton = msgBox.addButton( tr( "Overwrite" ), QMessageBox::ActionRole );
318 QPushButton *addNewLayerButton = msgBox.addButton( tr( "Add New Layer" ), QMessageBox::ActionRole );
319 msgBox.setStandardButtons( QMessageBox::Cancel );
320 msgBox.setDefaultButton( addNewLayerButton );
321 bool cancel = false;
322 if ( property( "hideDialogs" ).toBool() )
323 {
324 overwrite = property( "question_existing_db_answer_overwrite" ).toBool();
325 if ( !overwrite )
326 cancel = !property( "question_existing_db_answer_add_new_layer" ).toBool();
327 }
328 else
329 {
330 const int ret = msgBox.exec();
331 if ( ret == QMessageBox::Cancel )
332 cancel = true;
333 if ( msgBox.clickedButton() == overwriteButton )
334 overwrite = true;
335 }
336 if ( cancel )
337 {
338 return false;
339 }
340 break;
341 }
342
343 case Overwrite:
344 overwrite = true;
345 break;
346
347 case AddNewLayer:
348 overwrite = false;
349 break;
350 }
351
352 if ( overwrite )
353 {
354 QFile( fileName ).remove();
355 createNewDb = true;
356 }
357 }
358 else
359 {
360 createNewDb = true;
361 }
362
363 OGRSFDriverH hGpkgDriver = OGRGetDriverByName( "GPKG" );
364 if ( !hGpkgDriver )
365 {
366 if ( !property( "hideDialogs" ).toBool() )
367 QMessageBox::critical( this, tr( "New GeoPackage Layer" ),
368 tr( "Layer creation failed. GeoPackage driver not found." ) );
369 return false;
370 }
371
373 if ( createNewDb )
374 {
375 hDS.reset( OGR_Dr_CreateDataSource( hGpkgDriver, fileName.toUtf8().constData(), nullptr ) );
376 if ( !hDS )
377 {
378 const QString msg( tr( "Creation of database failed (OGR error: %1)" ).arg( QString::fromUtf8( CPLGetLastErrorMsg() ) ) );
379 if ( !property( "hideDialogs" ).toBool() )
380 QMessageBox::critical( this, tr( "New GeoPackage Layer" ), msg );
381 return false;
382 }
383 }
384 else
385 {
386 OGRSFDriverH hDriver = nullptr;
387 hDS.reset( OGROpen( fileName.toUtf8().constData(), true, &hDriver ) );
388 if ( !hDS )
389 {
390 const QString msg( tr( "Opening of database failed (OGR error: %1)" ).arg( QString::fromUtf8( CPLGetLastErrorMsg() ) ) );
391 if ( !property( "hideDialogs" ).toBool() )
392 QMessageBox::critical( this, tr( "New GeoPackage Layer" ), msg );
393 return false;
394 }
395 if ( hDriver != hGpkgDriver )
396 {
397 const QString msg( tr( "Opening of file succeeded, but this is not a GeoPackage database." ) );
398 if ( !property( "hideDialogs" ).toBool() )
399 QMessageBox::critical( this, tr( "New GeoPackage Layer" ), msg );
400 return false;
401 }
402 }
403
404 const QString tableName( mTableNameEdit->text() );
405
406 bool overwriteTable = false;
407 if ( OGR_DS_GetLayerByName( hDS.get(), tableName.toUtf8().constData() ) )
408 {
409 if ( property( "hideDialogs" ).toBool() )
410 {
411 overwriteTable = property( "question_existing_layer_answer_overwrite" ).toBool();
412 }
413 else if ( QMessageBox::question( this, tr( "New GeoPackage Layer" ),
414 tr( "A table with the same name already exists. Do you want to overwrite it?" ),
415 QMessageBox::Yes | QMessageBox::No, QMessageBox::No ) == QMessageBox::Yes )
416 {
417 overwriteTable = true;
418 }
419
420 if ( !overwriteTable )
421 {
422 return false;
423 }
424 }
425
426 const QString layerIdentifier( mLayerIdentifierEdit->text() );
427 const QString layerDescription( mLayerDescriptionEdit->text() );
428
429 OGRwkbGeometryType wkbType = static_cast<OGRwkbGeometryType>
430 ( mGeometryTypeBox->currentData( Qt::UserRole ).toInt() );
431
432 // z-coordinate & m-value.
433 if ( mGeometryWithZCheckBox->isChecked() )
434 wkbType = OGR_GT_SetZ( wkbType );
435
436 if ( mGeometryWithMCheckBox->isChecked() )
437 wkbType = OGR_GT_SetM( wkbType );
438
439 OGRSpatialReferenceH hSRS = nullptr;
440 // consider spatial reference system of the layer
441 const QgsCoordinateReferenceSystem srs = mCrsSelector->crs();
442 if ( wkbType != wkbNone && srs.isValid() )
443 {
445 }
446
447 // Set options
448 char **options = nullptr;
449
450 if ( overwriteTable )
451 options = CSLSetNameValue( options, "OVERWRITE", "YES" );
452 if ( !layerIdentifier.isEmpty() )
453 options = CSLSetNameValue( options, "IDENTIFIER", layerIdentifier.toUtf8().constData() );
454 if ( !layerDescription.isEmpty() )
455 options = CSLSetNameValue( options, "DESCRIPTION", layerDescription.toUtf8().constData() );
456
457 const QString featureId( mFeatureIdColumnEdit->text() );
458 if ( !featureId.isEmpty() )
459 options = CSLSetNameValue( options, "FID", featureId.toUtf8().constData() );
460
461 const QString geometryColumn( mGeometryColumnEdit->text() );
462 if ( wkbType != wkbNone && !geometryColumn.isEmpty() )
463 options = CSLSetNameValue( options, "GEOMETRY_COLUMN", geometryColumn.toUtf8().constData() );
464
465 if ( wkbType != wkbNone )
466 options = CSLSetNameValue( options, "SPATIAL_INDEX", mCheckBoxCreateSpatialIndex->isChecked() ? "YES" : "NO" );
467
468 OGRLayerH hLayer = OGR_DS_CreateLayer( hDS.get(), tableName.toUtf8().constData(), hSRS, wkbType, options );
469 CSLDestroy( options );
470 if ( hSRS )
471 OSRRelease( hSRS );
472 if ( !hLayer )
473 {
474 const QString msg( tr( "Creation of layer failed (OGR error: %1)" ).arg( QString::fromUtf8( CPLGetLastErrorMsg() ) ) );
475 if ( !property( "hideDialogs" ).toBool() )
476 QMessageBox::critical( this, tr( "New GeoPackage Layer" ), msg );
477 return false;
478 }
479
480 QTreeWidgetItemIterator it( mAttributeView );
481 while ( *it )
482 {
483 const QString fieldName( ( *it )->text( 0 ) );
484 const QString fieldType( ( *it )->text( 1 ) );
485 const QString fieldWidth( ( *it )->text( 2 ) );
486
487 OGRFieldType ogrType( OFTString );
488 OGRFieldSubType ogrSubType = OFSTNone;
489 if ( fieldType == QLatin1String( "text" ) )
490 ogrType = OFTString;
491 else if ( fieldType == QLatin1String( "integer" ) )
492 ogrType = OFTInteger;
493 else if ( fieldType == QLatin1String( "integer64" ) )
494 ogrType = OFTInteger64;
495 else if ( fieldType == QLatin1String( "real" ) )
496 ogrType = OFTReal;
497 else if ( fieldType == QLatin1String( "date" ) )
498 ogrType = OFTDate;
499 else if ( fieldType == QLatin1String( "datetime" ) )
500 ogrType = OFTDateTime;
501 else if ( fieldType == QLatin1String( "bool" ) )
502 {
503 ogrType = OFTInteger;
504 ogrSubType = OFSTBoolean;
505 }
506 else if ( fieldType == QLatin1String( "binary" ) )
507 ogrType = OFTBinary;
508 else if ( fieldType == QLatin1String( "json" ) )
509 {
510 ogrType = OFTString;
511 ogrSubType = OFSTJSON;
512 }
513
514 const int ogrWidth = fieldWidth.toInt();
515
516 const gdal::ogr_field_def_unique_ptr fld( OGR_Fld_Create( fieldName.toUtf8().constData(), ogrType ) );
517 if ( ogrSubType != OFSTNone )
518 OGR_Fld_SetSubType( fld.get(), ogrSubType );
519
520 if ( ogrType != OFTBinary )
521 OGR_Fld_SetWidth( fld.get(), ogrWidth );
522
523 if ( OGR_L_CreateField( hLayer, fld.get(), true ) != OGRERR_NONE )
524 {
525 if ( !property( "hideDialogs" ).toBool() )
526 {
527 QMessageBox::critical( this, tr( "New GeoPackage Layer" ),
528 tr( "Creation of field %1 failed (OGR error: %2)" )
529 .arg( fieldName, QString::fromUtf8( CPLGetLastErrorMsg() ) ) );
530 }
531 return false;
532 }
533
534 ++it;
535 }
536
537 // In GDAL >= 2.0, the driver implements a deferred creation strategy, so
538 // issue a command that will force table creation
539 CPLErrorReset();
540 OGR_L_ResetReading( hLayer );
541 if ( CPLGetLastErrorType() != CE_None )
542 {
543 const QString msg( tr( "Creation of layer failed (OGR error: %1)" ).arg( QString::fromUtf8( CPLGetLastErrorMsg() ) ) );
544 if ( !property( "hideDialogs" ).toBool() )
545 QMessageBox::critical( this, tr( "New GeoPackage Layer" ), msg );
546 return false;
547 }
548 hDS.reset();
549
550 const QString uri( QStringLiteral( "%1|layername=%2" ).arg( fileName, tableName ) );
551 const QString userVisiblelayerName( layerIdentifier.isEmpty() ? tableName : layerIdentifier );
553 std::unique_ptr< QgsVectorLayer > layer = std::make_unique< QgsVectorLayer >( uri, userVisiblelayerName, QStringLiteral( "ogr" ), layerOptions );
554 if ( layer->isValid() )
555 {
556 if ( mAddToProject )
557 {
558 // register this layer with the central layers registry
559 QList<QgsMapLayer *> myList;
560 myList << layer.release();
561 //addMapLayers returns a list of all successfully added layers
562 //so we compare that to our original list.
563 if ( myList == QgsProject::instance()->addMapLayers( myList ) )
564 return true;
565 }
566 else
567 {
568 return true;
569 }
570 }
571 else
572 {
573 if ( !property( "hideDialogs" ).toBool() )
574 QMessageBox::critical( this, tr( "New GeoPackage Layer" ), tr( "%1 is an invalid layer and cannot be loaded." ).arg( tableName ) );
575 }
576
577 return false;
578}
579
581{
582 mBehavior = behavior;
583}
584
586{
587 mAddToProject = addToProject;
588}
589
590void QgsNewGeoPackageLayerDialog::showHelp()
591{
592 QgsHelp::openHelp( QStringLiteral( "managing_data_source/create_layers.html#creating-a-new-geopackage-layer" ) );
593}
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
This class represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
static QIcon iconForFieldType(QVariant::Type type, QVariant::Type subType=QVariant::Type::Invalid)
Returns an icon corresponding to a field type.
Definition: qgsfields.cpp:294
@ SaveFile
Select a single new or pre-existing file.
Definition: qgsfilewidget.h:71
void fileChanged(const QString &path)
Emitted whenever the current file or directory path is changed.
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.
OverwriteBehavior
Behavior to use when an existing geopackage already exists.
@ AddNewLayer
Keep existing contents and add new layer.
@ Overwrite
Overwrite whole geopackage.
void setAddToProject(bool addToProject)
Sets whether a newly created layer should automatically be added to the current project.
void setCrs(const QgsCoordinateReferenceSystem &crs)
Sets the crs value for the new layer in the dialog.
void lockDatabasePath()
Sets the database path widgets to a locked and read-only mode.
QgsNewGeoPackageLayerDialog(QWidget *parent=nullptr, Qt::WindowFlags fl=QgsGuiUtils::ModalDialogFlags)
Constructor.
void setOverwriteBehavior(OverwriteBehavior behavior)
Sets the behavior to use when a path to an existing geopackage file is used.
static OGRSpatialReferenceH crsToOGRSpatialReference(const QgsCoordinateReferenceSystem &crs)
Returns a OGRSpatialReferenceH corresponding to the specified crs object.
static QgsWkbTypes::Type ogrGeometryTypeToQgsWkbType(OGRwkbGeometryType ogrGeomType)
Converts a OGRwkbGeometryType to QgsWkbTypes::Type.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:477
QgsCoordinateTransformContext transformContext
Definition: qgsproject.h:112
A model containing registered connection names for a specific data provider.
This class is a composition of two QSettings instances:
Definition: qgssettings.h:63
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 QString typeToDisplayString(QVariant::Type type, QVariant::Type subType=QVariant::Type::Invalid)
Returns a user-friendly translated string representing a QVariant type.
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.
Definition: qgswkbtypes.h:70
std::unique_ptr< std::remove_pointer< OGRDataSourceH >::type, OGRDataSourceDeleter > ogr_datasource_unique_ptr
Scoped OGR data source.
Definition: qgsogrutils.h:137
std::unique_ptr< std::remove_pointer< OGRFieldDefnH >::type, OGRFldDeleter > ogr_field_def_unique_ptr
Scoped OGR field definition.
Definition: qgsogrutils.h:147
void * OGRSpatialReferenceH
#define DEFAULT_OGR_FID_COLUMN_TITLE
const QgsCoordinateReferenceSystem & crs
Setting options for loading vector layers.