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