19#include "moc_qgsnewvectorlayerdialog.cpp" 
   32#include "qgsogrproviderutils.h" 
   42  : QDialog( parent, fl )
 
   47  connect( mAddAttributeButton, &QToolButton::clicked, 
this, &QgsNewVectorLayerDialog::mAddAttributeButton_clicked );
 
   48  connect( mRemoveAttributeButton, &QToolButton::clicked, 
this, &QgsNewVectorLayerDialog::mRemoveAttributeButton_clicked );
 
   49  connect( mFileFormatComboBox, 
static_cast<void ( QComboBox::* )( 
int )
>( &QComboBox::currentIndexChanged ), 
this, &QgsNewVectorLayerDialog::mFileFormatComboBox_currentIndexChanged );
 
   50  connect( mTypeBox, 
static_cast<void ( QComboBox::* )( 
int )
>( &QComboBox::currentIndexChanged ), 
this, &QgsNewVectorLayerDialog::mTypeBox_currentIndexChanged );
 
   51  connect( buttonBox, &QDialogButtonBox::helpRequested, 
this, &QgsNewVectorLayerDialog::showHelp );
 
   52  connect( mButtonUp, &QToolButton::clicked, 
this, &QgsNewVectorLayerDialog::moveFieldsUp );
 
   53  connect( mButtonDown, &QToolButton::clicked, 
this, &QgsNewVectorLayerDialog::moveFieldsDown );
 
   62#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION( 3, 9, 0 ) 
   66  mWidth->setValidator( 
new QIntValidator( 1, 255, 
this ) );
 
   67  mPrecision->setValidator( 
new QIntValidator( 0, 15, 
this ) );
 
   77  for ( 
const auto type : geomTypes )
 
   79  mGeometryTypeBox->setCurrentIndex( -1 );
 
   81  mOkButton = buttonBox->button( QDialogButtonBox::Ok );
 
   82  mOkButton->setEnabled( 
false );
 
   84  mFileFormatComboBox->addItem( tr( 
"ESRI Shapefile" ), 
"ESRI Shapefile" );
 
   88  mFileFormatComboBox->addItem( tr( 
"Comma Separated Value" ), 
"Comma Separated Value" );
 
   89  mFileFormatComboBox->addItem( tr( 
"GML" ), 
"GML" );
 
   90  mFileFormatComboBox->addItem( tr( 
"Mapinfo File" ), 
"Mapinfo File" );
 
   92  if ( mFileFormatComboBox->count() == 1 )
 
   94    mFileFormatComboBox->setVisible( 
false );
 
   95    mFileFormatLabel->setVisible( 
false );
 
   98  mCrsSelector->setShowAccuracyWarnings( 
true );
 
  100  mFileFormatComboBox->setCurrentIndex( 0 );
 
  105  const QString enc = 
QgsSettings().
value( QStringLiteral( 
"/UI/encoding" ), 
"System" ).toString();
 
  109  int encindex = mFileEncoding->findText( enc );
 
  112    mFileEncoding->insertItem( 0, enc );
 
  115  mFileEncoding->setCurrentIndex( encindex );
 
  117  mAttributeView->addTopLevelItem( 
new QTreeWidgetItem( QStringList() << QStringLiteral( 
"id" ) << QStringLiteral( 
"Integer" ) << QStringLiteral( 
"10" ) << QString() ) );
 
  118  connect( mNameEdit, &QLineEdit::textChanged, 
this, &QgsNewVectorLayerDialog::nameChanged );
 
  119  connect( mAttributeView, &QTreeWidget::itemSelectionChanged, 
this, &QgsNewVectorLayerDialog::selectionChanged );
 
  120  connect( mGeometryTypeBox, 
static_cast<void ( QComboBox::* )( 
int )
>( &QComboBox::currentIndexChanged ), 
this, [
this]( 
int ) {
 
  125  mAddAttributeButton->setEnabled( 
false );
 
  126  mRemoveAttributeButton->setEnabled( 
false );
 
  127  mButtonUp->setEnabled( 
false );
 
  128  mButtonDown->setEnabled( 
false );
 
  132  mFileName->setConfirmOverwrite( 
false );
 
  133  mFileName->setDialogTitle( tr( 
"Save Layer As" ) );
 
  135  mFileName->setDefaultRoot( settings.
value( QStringLiteral( 
"UI/lastVectorFileFilterDir" ), QDir::homePath() ).toString() );
 
  138    const QFileInfo tmplFileInfo( mFileName->filePath() );
 
  139    settings.
setValue( QStringLiteral( 
"UI/lastVectorFileFilterDir" ), tmplFileInfo.absolutePath() );
 
 
  144void QgsNewVectorLayerDialog::mFileFormatComboBox_currentIndexChanged( 
int index )
 
  147  if ( mFileFormatComboBox->currentText() == tr( 
"ESRI Shapefile" ) )
 
  148    mNameEdit->setMaxLength( 10 );
 
  150    mNameEdit->setMaxLength( 32767 );
 
  153void QgsNewVectorLayerDialog::mTypeBox_currentIndexChanged( 
int index )
 
  159      if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 255 )
 
  160        mWidth->setText( QStringLiteral( 
"80" ) );
 
  161      mPrecision->setEnabled( 
false );
 
  162      mWidth->setEnabled( 
true );
 
  163      mWidth->setValidator( 
new QIntValidator( 1, 255, 
this ) );
 
  167      if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 10 )
 
  168        mWidth->setText( QStringLiteral( 
"10" ) );
 
  169      mPrecision->setEnabled( 
false );
 
  170      mWidth->setEnabled( 
true );
 
  171      mWidth->setValidator( 
new QIntValidator( 1, 10, 
this ) );
 
  175      if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 20 )
 
  176        mWidth->setText( QStringLiteral( 
"20" ) );
 
  177      if ( mPrecision->text().toInt() < 1 || mPrecision->text().toInt() > 15 )
 
  178        mPrecision->setText( QStringLiteral( 
"6" ) );
 
  180      mPrecision->setEnabled( 
true );
 
  181      mWidth->setEnabled( 
true );
 
  182      mWidth->setValidator( 
new QIntValidator( 1, 20, 
this ) );
 
  186      mPrecision->setEnabled( 
false );
 
  187      mWidth->setEnabled( 
false );
 
  197  wkbType = 
static_cast<Qgis::WkbType>( mGeometryTypeBox->currentData( Qt::UserRole ).toInt() );
 
  199  if ( mGeometryWithZRadioButton->isChecked() )
 
  202  if ( mGeometryWithMRadioButton->isChecked() )
 
 
  210  return mCrsSelector->crs();
 
 
  215  mCrsSelector->setCrs( 
crs );
 
 
  218void QgsNewVectorLayerDialog::mAddAttributeButton_clicked()
 
  220  const QString myName = mNameEdit->text();
 
  221  const QString myWidth = mWidth->text();
 
  222  const QString myPrecision = mPrecision->isEnabled() ? mPrecision->text() : QString();
 
  224  const QString myType = mTypeBox->currentData( Qt::UserRole ).toString();
 
  225  mAttributeView->addTopLevelItem( 
new QTreeWidgetItem( QStringList() << myName << myType << myWidth << myPrecision ) );
 
  231  if ( !mNameEdit->hasFocus() )
 
  233    mNameEdit->setFocus();
 
  237void QgsNewVectorLayerDialog::mRemoveAttributeButton_clicked()
 
  239  delete mAttributeView->currentItem();
 
  245  QTreeWidgetItemIterator it( mAttributeView );
 
  248    QTreeWidgetItem *item = *it;
 
  249    const QString type = QStringLiteral( 
"%1;%2;%3" ).arg( item->text( 1 ), item->text( 2 ), item->text( 3 ) );
 
  250    at.push_back( qMakePair( item->text( 0 ), type ) );
 
  251    QgsDebugMsgLevel( QStringLiteral( 
"appending %1//%2" ).arg( item->text( 0 ), type ), 2 );
 
 
  259  QString myType = mFileFormatComboBox->currentData( Qt::UserRole ).toString();
 
 
  265  return mFileEncoding->currentText();
 
 
  268void QgsNewVectorLayerDialog::nameChanged( 
const QString &name )
 
  270  mAddAttributeButton->setDisabled( name.isEmpty() || !mAttributeView->findItems( name, Qt::MatchExactly ).isEmpty() );
 
  273void QgsNewVectorLayerDialog::selectionChanged()
 
  275  mRemoveAttributeButton->setDisabled( mAttributeView->selectedItems().isEmpty() );
 
  276  mButtonUp->setDisabled( mAttributeView->selectedItems().isEmpty() );
 
  277  mButtonDown->setDisabled( mAttributeView->selectedItems().isEmpty() );
 
  280void QgsNewVectorLayerDialog::moveFieldsUp()
 
  282  int currentRow = mAttributeView->currentIndex().row();
 
  283  if ( currentRow == 0 )
 
  286  mAttributeView->insertTopLevelItem( currentRow - 1, mAttributeView->takeTopLevelItem( currentRow ) );
 
  287  mAttributeView->setCurrentIndex( mAttributeView->model()->index( currentRow - 1, 0 ) );
 
  290void QgsNewVectorLayerDialog::moveFieldsDown()
 
  292  int currentRow = mAttributeView->currentIndex().row();
 
  293  if ( currentRow == mAttributeView->topLevelItemCount() - 1 )
 
  296  mAttributeView->insertTopLevelItem( currentRow + 1, mAttributeView->takeTopLevelItem( currentRow ) );
 
  297  mAttributeView->setCurrentIndex( mAttributeView->model()->index( currentRow + 1, 0 ) );
 
  302  return mFileName->filePath();
 
 
  310void QgsNewVectorLayerDialog::checkOk()
 
  312  const bool ok = ( !mFileName->filePath().isEmpty() && mAttributeView->topLevelItemCount() > 0 && mGeometryTypeBox->currentIndex() != -1 );
 
  313  mOkButton->setEnabled( ok );
 
  321  if ( res.isEmpty() && error.isEmpty() )
 
 
  326void QgsNewVectorLayerDialog::updateExtension()
 
  331  if ( fileformat == QLatin1String( 
"ESRI Shapefile" ) )
 
  335      fileName = fileName.replace( fileName.lastIndexOf( QLatin1String( 
".dbf" ), -1, Qt::CaseInsensitive ), 4, QLatin1String( 
".shp" ) );
 
  340      fileName = fileName.replace( fileName.lastIndexOf( QLatin1String( 
".shp" ), -1, Qt::CaseInsensitive ), 4, QLatin1String( 
".dbf" ) );
 
  349  if ( !mNameEdit->text().trimmed().isEmpty() )
 
  351    const QString currentFieldName = mNameEdit->text();
 
  352    bool currentFound = 
false;
 
  353    QTreeWidgetItemIterator it( mAttributeView );
 
  356      QTreeWidgetItem *item = *it;
 
  357      if ( item->text( 0 ) == currentFieldName )
 
  367      if ( QMessageBox::question( 
this, windowTitle(), tr( 
"The field “%1” has not been added to the fields list. Are you sure you want to proceed and discard this field?" ).arg( currentFieldName ), QMessageBox::Ok | QMessageBox::Cancel ) != QMessageBox::Ok )
 
  376  if ( QFile::exists( 
filename() ) && QMessageBox::warning( 
this, tr( 
"New ShapeFile Layer" ), tr( 
"The layer already exists. Are you sure you want to overwrite the existing file?" ), QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel ) != QMessageBox::Yes )
 
 
  384  errorMessage.clear();
 
  387  if ( !initialPath.isEmpty() )
 
  389  if ( geomDialog.exec() == QDialog::Rejected )
 
  396  QString fileName = geomDialog.
filename();
 
  399  QgsDebugMsgLevel( QStringLiteral( 
"New file format will be: %1" ).arg( fileformat ), 2 );
 
  405  settings.
setValue( QStringLiteral( 
"UI/lastVectorFileFilterDir" ), QFileInfo( fileName ).absolutePath() );
 
  406  settings.
setValue( QStringLiteral( 
"UI/encoding" ), enc );
 
  412    const bool success = QgsOgrProviderUtils::createEmptyDataSource( fileName, fileformat, enc, geometrytype, 
attributes, srs, errorMessage );
 
  420    errorMessage = QObject::tr( 
"Geometry type not recognised" );
 
 
  431void QgsNewVectorLayerDialog::showHelp()
 
  433  QgsHelp::openHelp( QStringLiteral( 
"managing_data_source/create_layers.html#creating-a-new-shapefile-layer" ) );
 
WkbType
The WKB type describes the number of dimensions a geometry has.
 
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
 
Represents a coordinate reference system (CRS).
 
static QIcon iconForFieldType(QMetaType::Type type, QMetaType::Type subType=QMetaType::Type::UnknownType, const QString &typeString=QString())
Returns an icon corresponding to a field type.
 
static QString ensureFileNameHasExtension(const QString &fileName, const QStringList &extensions)
Ensures that a fileName ends with an extension from the provided list of extensions.
 
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...
 
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
 
static QIcon iconForWkbType(Qgis::WkbType type)
Returns the icon for a vector layer whose geometry type is provided.
 
A dialog for configuring the properties of a new vector layer.
 
static Q_DECL_DEPRECATED QString runAndCreateLayer(QWidget *parent=nullptr, QString *enc=nullptr, const QgsCoordinateReferenceSystem &crs=QgsCoordinateReferenceSystem(), const QString &initialPath=QString())
Runs the dialog and creates a layer matching the dialog parameters.
 
void attributes(QList< QPair< QString, QString > > &at) const
Appends the chosen attribute names and types to at.
 
QgsCoordinateReferenceSystem crs() const
Returns the selected CRS for the new layer.
 
void setCrs(const QgsCoordinateReferenceSystem &crs)
Sets the crs value for the new layer in the dialog.
 
QString filename() const
Returns the name for the new layer.
 
QString selectedFileFormat() const
Returns the file format for storage.
 
QString selectedFileEncoding() const
Returns the file format for storage.
 
QgsNewVectorLayerDialog(QWidget *parent=nullptr, Qt::WindowFlags fl=QgsGuiUtils::ModalDialogFlags)
New dialog constructor.
 
static QString execAndCreateLayer(QString &errorMessage, QWidget *parent=nullptr, const QString &initialPath=QString(), QString *encoding=nullptr, const QgsCoordinateReferenceSystem &crs=QgsCoordinateReferenceSystem())
Runs the dialog and creates a layer matching the dialog parameters.
 
Qgis::WkbType selectedType() const
Returns the selected geometry type.
 
void setFilename(const QString &filename)
Sets the initial file name to show in the dialog.
 
Stores settings for use within QGIS.
 
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
 
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
 
static QString typeToDisplayString(QMetaType::Type type, QMetaType::Type subType=QMetaType::Type::UnknownType)
Returns a user-friendly translated string representing a QVariant type.
 
static QStringList availableEncodings()
Returns a list of available encodings.
 
static QString filterForDriver(const QString &driverName)
Creates a filter for an OGR driver key.
 
static Q_INVOKABLE QString translatedDisplayString(Qgis::WkbType type)
Returns a translated display string type for a WKB type, e.g., the geometry name used in WKT geometry...
 
static Qgis::WkbType addM(Qgis::WkbType type)
Adds the m dimension to a WKB type and returns the new type.
 
static Qgis::WkbType addZ(Qgis::WkbType type)
Adds the z dimension to a WKB type and returns the new type.
 
#define QgsDebugMsgLevel(str, level)
 
#define QgsDebugError(str)
 
const QgsCoordinateReferenceSystem & crs