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