31#include "qgsogrproviderutils.h"
39 : QDialog( parent, fl )
44 connect( mAddAttributeButton, &QToolButton::clicked,
this, &QgsNewVectorLayerDialog::mAddAttributeButton_clicked );
45 connect( mRemoveAttributeButton, &QToolButton::clicked,
this, &QgsNewVectorLayerDialog::mRemoveAttributeButton_clicked );
46 connect( mFileFormatComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsNewVectorLayerDialog::mFileFormatComboBox_currentIndexChanged );
47 connect( mTypeBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsNewVectorLayerDialog::mTypeBox_currentIndexChanged );
48 connect( buttonBox, &QDialogButtonBox::helpRequested,
this, &QgsNewVectorLayerDialog::showHelp );
49 connect( mButtonUp, &QToolButton::clicked,
this, &QgsNewVectorLayerDialog::moveFieldsUp );
50 connect( mButtonDown, &QToolButton::clicked,
this, &QgsNewVectorLayerDialog::moveFieldsDown );
60 mWidth->setValidator(
new QIntValidator( 1, 255,
this ) );
61 mPrecision->setValidator(
new QIntValidator( 0, 15,
this ) );
72 for (
const auto type : geomTypes )
74 mGeometryTypeBox->setCurrentIndex( -1 );
76 mOkButton = buttonBox->button( QDialogButtonBox::Ok );
77 mOkButton->setEnabled(
false );
79 mFileFormatComboBox->addItem( tr(
"ESRI Shapefile" ),
"ESRI Shapefile" );
83 mFileFormatComboBox->addItem( tr(
"Comma Separated Value" ),
"Comma Separated Value" );
84 mFileFormatComboBox->addItem( tr(
"GML" ),
"GML" );
85 mFileFormatComboBox->addItem( tr(
"Mapinfo File" ),
"Mapinfo File" );
87 if ( mFileFormatComboBox->count() == 1 )
89 mFileFormatComboBox->setVisible(
false );
90 mFileFormatLabel->setVisible(
false );
93 mCrsSelector->setShowAccuracyWarnings(
true );
95 mFileFormatComboBox->setCurrentIndex( 0 );
100 const QString enc =
QgsSettings().
value( QStringLiteral(
"/UI/encoding" ),
"System" ).toString();
104 int encindex = mFileEncoding->findText( enc );
107 mFileEncoding->insertItem( 0, enc );
110 mFileEncoding->setCurrentIndex( encindex );
112 mAttributeView->addTopLevelItem(
new QTreeWidgetItem( QStringList() << QStringLiteral(
"id" ) << QStringLiteral(
"Integer" ) << QStringLiteral(
"10" ) << QString() ) );
113 connect( mNameEdit, &QLineEdit::textChanged,
this, &QgsNewVectorLayerDialog::nameChanged );
114 connect( mAttributeView, &QTreeWidget::itemSelectionChanged,
this, &QgsNewVectorLayerDialog::selectionChanged );
115 connect( mGeometryTypeBox,
static_cast<void( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, [ = ](
int )
121 mAddAttributeButton->setEnabled(
false );
122 mRemoveAttributeButton->setEnabled(
false );
123 mButtonUp->setEnabled(
false );
124 mButtonDown->setEnabled(
false );
128 mFileName->setConfirmOverwrite(
false );
129 mFileName->setDialogTitle( tr(
"Save Layer As" ) );
131 mFileName->setDefaultRoot( settings.
value( QStringLiteral(
"UI/lastVectorFileFilterDir" ), QDir::homePath() ).toString() );
135 const QFileInfo tmplFileInfo( mFileName->filePath() );
136 settings.
setValue( QStringLiteral(
"UI/lastVectorFileFilterDir" ), tmplFileInfo.absolutePath() );
141void QgsNewVectorLayerDialog::mFileFormatComboBox_currentIndexChanged(
int index )
144 if ( mFileFormatComboBox->currentText() == tr(
"ESRI Shapefile" ) )
145 mNameEdit->setMaxLength( 10 );
147 mNameEdit->setMaxLength( 32767 );
150void QgsNewVectorLayerDialog::mTypeBox_currentIndexChanged(
int index )
156 if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 255 )
157 mWidth->setText( QStringLiteral(
"80" ) );
158 mPrecision->setEnabled(
false );
159 mWidth->setValidator(
new QIntValidator( 1, 255,
this ) );
163 if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 10 )
164 mWidth->setText( QStringLiteral(
"10" ) );
165 mPrecision->setEnabled(
false );
166 mWidth->setValidator(
new QIntValidator( 1, 10,
this ) );
170 if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 20 )
171 mWidth->setText( QStringLiteral(
"20" ) );
172 if ( mPrecision->text().toInt() < 1 || mPrecision->text().toInt() > 15 )
173 mPrecision->setText( QStringLiteral(
"6" ) );
175 mPrecision->setEnabled(
true );
176 mWidth->setValidator(
new QIntValidator( 1, 20,
this ) );
189 ( mGeometryTypeBox->currentData( Qt::UserRole ).toInt() );
191 if ( mGeometryWithZRadioButton->isChecked() )
194 if ( mGeometryWithMRadioButton->isChecked() )
202 return mCrsSelector->crs();
207 mCrsSelector->setCrs(
crs );
210void QgsNewVectorLayerDialog::mAddAttributeButton_clicked()
212 const QString myName = mNameEdit->text();
213 const QString myWidth = mWidth->text();
214 const QString myPrecision = mPrecision->isEnabled() ? mPrecision->text() : QString();
216 const QString myType = mTypeBox->currentData( Qt::UserRole ).toString();
217 mAttributeView->addTopLevelItem(
new QTreeWidgetItem( QStringList() << myName << myType << myWidth << myPrecision ) );
223 if ( !mNameEdit->hasFocus() )
225 mNameEdit->setFocus();
229void QgsNewVectorLayerDialog::mRemoveAttributeButton_clicked()
231 delete mAttributeView->currentItem();
237 QTreeWidgetItemIterator it( mAttributeView );
240 QTreeWidgetItem *item = *it;
241 const QString type = QStringLiteral(
"%1;%2;%3" ).arg( item->text( 1 ), item->text( 2 ), item->text( 3 ) );
242 at.push_back( qMakePair( item->text( 0 ), type ) );
243 QgsDebugMsgLevel( QStringLiteral(
"appending %1//%2" ).arg( item->text( 0 ), type ), 2 );
251 QString myType = mFileFormatComboBox->currentData( Qt::UserRole ).toString();
257 return mFileEncoding->currentText();
260void QgsNewVectorLayerDialog::nameChanged(
const QString &name )
262 mAddAttributeButton->setDisabled( name.isEmpty() || !mAttributeView->findItems( name, Qt::MatchExactly ).isEmpty() );
265void QgsNewVectorLayerDialog::selectionChanged()
267 mRemoveAttributeButton->setDisabled( mAttributeView->selectedItems().isEmpty() );
268 mButtonUp->setDisabled( mAttributeView->selectedItems().isEmpty() );
269 mButtonDown->setDisabled( mAttributeView->selectedItems().isEmpty() );
272void QgsNewVectorLayerDialog::moveFieldsUp()
274 int currentRow = mAttributeView->currentIndex().row();
275 if ( currentRow == 0 )
278 mAttributeView->insertTopLevelItem( currentRow - 1, mAttributeView->takeTopLevelItem( currentRow ) );
279 mAttributeView->setCurrentIndex( mAttributeView->model()->index( currentRow - 1, 0 ) );
282void QgsNewVectorLayerDialog::moveFieldsDown()
284 int currentRow = mAttributeView->currentIndex().row();
285 if ( currentRow == mAttributeView->topLevelItemCount() - 1 )
288 mAttributeView->insertTopLevelItem( currentRow + 1, mAttributeView->takeTopLevelItem( currentRow ) );
289 mAttributeView->setCurrentIndex( mAttributeView->model()->index( currentRow + 1, 0 ) );
294 return mFileName->filePath();
302void QgsNewVectorLayerDialog::checkOk()
304 const bool ok = ( !mFileName->filePath().isEmpty() && mAttributeView->topLevelItemCount() > 0 && mGeometryTypeBox->currentIndex() != -1 );
305 mOkButton->setEnabled( ok );
313 if ( res.isEmpty() && error.isEmpty() )
318void QgsNewVectorLayerDialog::updateExtension()
323 if ( fileformat == QLatin1String(
"ESRI Shapefile" ) )
327 fileName = fileName.replace( fileName.lastIndexOf( QLatin1String(
".dbf" ), -1, Qt::CaseInsensitive ), 4, QLatin1String(
".shp" ) );
332 fileName = fileName.replace( fileName.lastIndexOf( QLatin1String(
".shp" ), -1, Qt::CaseInsensitive ), 4, QLatin1String(
".dbf" ) );
342 if ( !mNameEdit->text().trimmed().isEmpty() )
344 const QString currentFieldName = mNameEdit->text();
345 bool currentFound =
false;
346 QTreeWidgetItemIterator it( mAttributeView );
349 QTreeWidgetItem *item = *it;
350 if ( item->text( 0 ) == currentFieldName )
360 if ( QMessageBox::question(
this, windowTitle(),
361 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 ),
362 QMessageBox::Ok | QMessageBox::Cancel ) != QMessageBox::Ok )
371 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?" ),
372 QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel ) != QMessageBox::Yes )
380 errorMessage.clear();
383 if ( !initialPath.isEmpty() )
385 if ( geomDialog.exec() == QDialog::Rejected )
392 QString fileName = geomDialog.
filename();
395 QgsDebugMsgLevel( QStringLiteral(
"New file format will be: %1" ).arg( fileformat ), 2 );
401 settings.
setValue( QStringLiteral(
"UI/lastVectorFileFilterDir" ), QFileInfo( fileName ).absolutePath() );
402 settings.
setValue( QStringLiteral(
"UI/encoding" ), enc );
408 const bool success = QgsOgrProviderUtils::createEmptyDataSource( fileName, fileformat, enc, geometrytype,
attributes, srs, errorMessage );
416 errorMessage = QObject::tr(
"Geometry type not recognised" );
427void QgsNewVectorLayerDialog::showHelp()
429 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