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