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, [=](
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.
This class 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.
This class is a composition of two QSettings instances:
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 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