30#include "qgsogrproviderutils.h"
41#include "moc_qgsnewvectorlayerdialog.cpp"
44 : QDialog( parent, fl )
49 connect( mAddAttributeButton, &QToolButton::clicked,
this, &QgsNewVectorLayerDialog::mAddAttributeButton_clicked );
50 connect( mRemoveAttributeButton, &QToolButton::clicked,
this, &QgsNewVectorLayerDialog::mRemoveAttributeButton_clicked );
51 connect( mFileFormatComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsNewVectorLayerDialog::mFileFormatComboBox_currentIndexChanged );
52 connect( mTypeBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsNewVectorLayerDialog::mTypeBox_currentIndexChanged );
53 connect( buttonBox, &QDialogButtonBox::helpRequested,
this, &QgsNewVectorLayerDialog::showHelp );
54 connect( mButtonUp, &QToolButton::clicked,
this, &QgsNewVectorLayerDialog::moveFieldsUp );
55 connect( mButtonDown, &QToolButton::clicked,
this, &QgsNewVectorLayerDialog::moveFieldsDown );
64#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION( 3, 9, 0 )
68 mWidth->setValidator(
new QIntValidator( 1, 255,
this ) );
69 mPrecision->setValidator(
new QIntValidator( 0, 15,
this ) );
79 for (
const auto type : geomTypes )
81 mGeometryTypeBox->setCurrentIndex( -1 );
83 mOkButton = buttonBox->button( QDialogButtonBox::Ok );
84 mOkButton->setEnabled(
false );
86 mFileFormatComboBox->addItem( tr(
"ESRI Shapefile" ),
"ESRI Shapefile" );
90 mFileFormatComboBox->addItem( tr(
"Comma Separated Value" ),
"Comma Separated Value" );
91 mFileFormatComboBox->addItem( tr(
"GML" ),
"GML" );
92 mFileFormatComboBox->addItem( tr(
"Mapinfo File" ),
"Mapinfo File" );
94 if ( mFileFormatComboBox->count() == 1 )
96 mFileFormatComboBox->setVisible(
false );
97 mFileFormatLabel->setVisible(
false );
100 mCrsSelector->setShowAccuracyWarnings(
true );
102 mFileFormatComboBox->setCurrentIndex( 0 );
107 const QString enc =
QgsSettings().
value( QStringLiteral(
"/UI/encoding" ),
"System" ).toString();
111 int encindex = mFileEncoding->findText( enc );
114 mFileEncoding->insertItem( 0, enc );
117 mFileEncoding->setCurrentIndex( encindex );
119 mAttributeView->addTopLevelItem(
new QTreeWidgetItem( QStringList() << QStringLiteral(
"id" ) << QStringLiteral(
"Integer" ) << QStringLiteral(
"10" ) << QString() ) );
120 connect( mNameEdit, &QLineEdit::textChanged,
this, &QgsNewVectorLayerDialog::nameChanged );
121 connect( mAttributeView, &QTreeWidget::itemSelectionChanged,
this, &QgsNewVectorLayerDialog::selectionChanged );
122 connect( mGeometryTypeBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, [
this](
int ) {
127 mAddAttributeButton->setEnabled(
false );
128 mRemoveAttributeButton->setEnabled(
false );
129 mButtonUp->setEnabled(
false );
130 mButtonDown->setEnabled(
false );
134 mFileName->setConfirmOverwrite(
false );
135 mFileName->setDialogTitle( tr(
"Save Layer As" ) );
137 mFileName->setDefaultRoot( settings.
value( QStringLiteral(
"UI/lastVectorFileFilterDir" ), QDir::homePath() ).toString() );
140 const QFileInfo tmplFileInfo( mFileName->filePath() );
141 settings.
setValue( QStringLiteral(
"UI/lastVectorFileFilterDir" ), tmplFileInfo.absolutePath() );
146void QgsNewVectorLayerDialog::mFileFormatComboBox_currentIndexChanged(
int index )
149 if ( mFileFormatComboBox->currentText() == tr(
"ESRI Shapefile" ) )
150 mNameEdit->setMaxLength( 10 );
152 mNameEdit->setMaxLength( 32767 );
155void QgsNewVectorLayerDialog::mTypeBox_currentIndexChanged(
int index )
161 if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 255 )
162 mWidth->setText( QStringLiteral(
"80" ) );
163 mPrecision->setEnabled(
false );
164 mWidth->setEnabled(
true );
165 mWidth->setValidator(
new QIntValidator( 1, 255,
this ) );
169 if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 10 )
170 mWidth->setText( QStringLiteral(
"10" ) );
171 mPrecision->setEnabled(
false );
172 mWidth->setEnabled(
true );
173 mWidth->setValidator(
new QIntValidator( 1, 10,
this ) );
177 if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 20 )
178 mWidth->setText( QStringLiteral(
"20" ) );
179 if ( mPrecision->text().toInt() < 1 || mPrecision->text().toInt() > 15 )
180 mPrecision->setText( QStringLiteral(
"6" ) );
182 mPrecision->setEnabled(
true );
183 mWidth->setEnabled(
true );
184 mWidth->setValidator(
new QIntValidator( 1, 20,
this ) );
188 mPrecision->setEnabled(
false );
189 mWidth->setEnabled(
false );
199 wkbType =
static_cast<Qgis::WkbType>( mGeometryTypeBox->currentData( Qt::UserRole ).toInt() );
201 if ( mGeometryWithZRadioButton->isChecked() )
204 if ( mGeometryWithMRadioButton->isChecked() )
212 return mCrsSelector->crs();
217 mCrsSelector->setCrs(
crs );
220void QgsNewVectorLayerDialog::mAddAttributeButton_clicked()
222 const QString myName = mNameEdit->text();
223 const QString myWidth = mWidth->text();
224 const QString myPrecision = mPrecision->isEnabled() ? mPrecision->text() : QString();
226 const QString myType = mTypeBox->currentData( Qt::UserRole ).toString();
227 mAttributeView->addTopLevelItem(
new QTreeWidgetItem( QStringList() << myName << myType << myWidth << myPrecision ) );
233 if ( !mNameEdit->hasFocus() )
235 mNameEdit->setFocus();
239void QgsNewVectorLayerDialog::mRemoveAttributeButton_clicked()
241 delete mAttributeView->currentItem();
247 QTreeWidgetItemIterator it( mAttributeView );
250 QTreeWidgetItem *item = *it;
251 const QString type = QStringLiteral(
"%1;%2;%3" ).arg( item->text( 1 ), item->text( 2 ), item->text( 3 ) );
252 at.push_back( qMakePair( item->text( 0 ), type ) );
253 QgsDebugMsgLevel( QStringLiteral(
"appending %1//%2" ).arg( item->text( 0 ), type ), 2 );
261 QString myType = mFileFormatComboBox->currentData( Qt::UserRole ).toString();
267 return mFileEncoding->currentText();
270void QgsNewVectorLayerDialog::nameChanged(
const QString &name )
272 mAddAttributeButton->setDisabled( name.isEmpty() || !mAttributeView->findItems( name, Qt::MatchExactly ).isEmpty() );
275void QgsNewVectorLayerDialog::selectionChanged()
277 mRemoveAttributeButton->setDisabled( mAttributeView->selectedItems().isEmpty() );
278 mButtonUp->setDisabled( mAttributeView->selectedItems().isEmpty() );
279 mButtonDown->setDisabled( mAttributeView->selectedItems().isEmpty() );
282void QgsNewVectorLayerDialog::moveFieldsUp()
284 int currentRow = mAttributeView->currentIndex().row();
285 if ( currentRow == 0 )
288 mAttributeView->insertTopLevelItem( currentRow - 1, mAttributeView->takeTopLevelItem( currentRow ) );
289 mAttributeView->setCurrentIndex( mAttributeView->model()->index( currentRow - 1, 0 ) );
292void QgsNewVectorLayerDialog::moveFieldsDown()
294 int currentRow = mAttributeView->currentIndex().row();
295 if ( currentRow == mAttributeView->topLevelItemCount() - 1 )
298 mAttributeView->insertTopLevelItem( currentRow + 1, mAttributeView->takeTopLevelItem( currentRow ) );
299 mAttributeView->setCurrentIndex( mAttributeView->model()->index( currentRow + 1, 0 ) );
304 return mFileName->filePath();
312void QgsNewVectorLayerDialog::checkOk()
314 const bool ok = ( !mFileName->filePath().isEmpty() && mAttributeView->topLevelItemCount() > 0 && mGeometryTypeBox->currentIndex() != -1 );
315 mOkButton->setEnabled( ok );
323 if ( res.isEmpty() && error.isEmpty() )
328void QgsNewVectorLayerDialog::updateExtension()
333 if ( fileformat == QLatin1String(
"ESRI Shapefile" ) )
337 fileName = fileName.replace( fileName.lastIndexOf( QLatin1String(
".dbf" ), -1, Qt::CaseInsensitive ), 4, QLatin1String(
".shp" ) );
342 fileName = fileName.replace( fileName.lastIndexOf( QLatin1String(
".shp" ), -1, Qt::CaseInsensitive ), 4, QLatin1String(
".dbf" ) );
351 if ( !mNameEdit->text().trimmed().isEmpty() )
353 const QString currentFieldName = mNameEdit->text();
354 bool currentFound =
false;
355 QTreeWidgetItemIterator it( mAttributeView );
358 QTreeWidgetItem *item = *it;
359 if ( item->text( 0 ) == currentFieldName )
369 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 )
378 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 )
386 errorMessage.clear();
389 if ( !initialPath.isEmpty() )
391 if ( geomDialog.exec() == QDialog::Rejected )
398 QString fileName = geomDialog.
filename();
401 QgsDebugMsgLevel( QStringLiteral(
"New file format will be: %1" ).arg( fileformat ), 2 );
407 settings.
setValue( QStringLiteral(
"UI/lastVectorFileFilterDir" ), QFileInfo( fileName ).absolutePath() );
408 settings.
setValue( QStringLiteral(
"UI/encoding" ), enc );
414 const bool success = QgsOgrProviderUtils::createEmptyDataSource( fileName, fileformat, enc, geometrytype,
attributes, srs, errorMessage );
422 errorMessage = QObject::tr(
"Geometry type not recognised" );
433void QgsNewVectorLayerDialog::showHelp()
435 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.
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)