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