19#include "moc_qgsnewvectorlayerdialog.cpp"
32#include "qgsogrproviderutils.h"
40 : QDialog( parent, fl )
45 connect( mAddAttributeButton, &QToolButton::clicked,
this, &QgsNewVectorLayerDialog::mAddAttributeButton_clicked );
46 connect( mRemoveAttributeButton, &QToolButton::clicked,
this, &QgsNewVectorLayerDialog::mRemoveAttributeButton_clicked );
47 connect( mFileFormatComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsNewVectorLayerDialog::mFileFormatComboBox_currentIndexChanged );
48 connect( mTypeBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsNewVectorLayerDialog::mTypeBox_currentIndexChanged );
49 connect( buttonBox, &QDialogButtonBox::helpRequested,
this, &QgsNewVectorLayerDialog::showHelp );
50 connect( mButtonUp, &QToolButton::clicked,
this, &QgsNewVectorLayerDialog::moveFieldsUp );
51 connect( mButtonDown, &QToolButton::clicked,
this, &QgsNewVectorLayerDialog::moveFieldsDown );
61 mWidth->setValidator(
new QIntValidator( 1, 255,
this ) );
62 mPrecision->setValidator(
new QIntValidator( 0, 15,
this ) );
73 for (
const auto type : geomTypes )
75 mGeometryTypeBox->setCurrentIndex( -1 );
77 mOkButton = buttonBox->button( QDialogButtonBox::Ok );
78 mOkButton->setEnabled(
false );
80 mFileFormatComboBox->addItem( tr(
"ESRI Shapefile" ),
"ESRI Shapefile" );
84 mFileFormatComboBox->addItem( tr(
"Comma Separated Value" ),
"Comma Separated Value" );
85 mFileFormatComboBox->addItem( tr(
"GML" ),
"GML" );
86 mFileFormatComboBox->addItem( tr(
"Mapinfo File" ),
"Mapinfo File" );
88 if ( mFileFormatComboBox->count() == 1 )
90 mFileFormatComboBox->setVisible(
false );
91 mFileFormatLabel->setVisible(
false );
94 mCrsSelector->setShowAccuracyWarnings(
true );
96 mFileFormatComboBox->setCurrentIndex( 0 );
101 const QString enc =
QgsSettings().
value( QStringLiteral(
"/UI/encoding" ),
"System" ).toString();
105 int encindex = mFileEncoding->findText( enc );
108 mFileEncoding->insertItem( 0, enc );
111 mFileEncoding->setCurrentIndex( encindex );
113 mAttributeView->addTopLevelItem(
new QTreeWidgetItem( QStringList() << QStringLiteral(
"id" ) << QStringLiteral(
"Integer" ) << QStringLiteral(
"10" ) << QString() ) );
114 connect( mNameEdit, &QLineEdit::textChanged,
this, &QgsNewVectorLayerDialog::nameChanged );
115 connect( mAttributeView, &QTreeWidget::itemSelectionChanged,
this, &QgsNewVectorLayerDialog::selectionChanged );
116 connect( mGeometryTypeBox,
static_cast<void( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, [ = ](
int )
122 mAddAttributeButton->setEnabled(
false );
123 mRemoveAttributeButton->setEnabled(
false );
124 mButtonUp->setEnabled(
false );
125 mButtonDown->setEnabled(
false );
129 mFileName->setConfirmOverwrite(
false );
130 mFileName->setDialogTitle( tr(
"Save Layer As" ) );
132 mFileName->setDefaultRoot( settings.
value( QStringLiteral(
"UI/lastVectorFileFilterDir" ), QDir::homePath() ).toString() );
136 const QFileInfo tmplFileInfo( mFileName->filePath() );
137 settings.
setValue( QStringLiteral(
"UI/lastVectorFileFilterDir" ), tmplFileInfo.absolutePath() );
142void QgsNewVectorLayerDialog::mFileFormatComboBox_currentIndexChanged(
int index )
145 if ( mFileFormatComboBox->currentText() == tr(
"ESRI Shapefile" ) )
146 mNameEdit->setMaxLength( 10 );
148 mNameEdit->setMaxLength( 32767 );
151void QgsNewVectorLayerDialog::mTypeBox_currentIndexChanged(
int index )
157 if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 255 )
158 mWidth->setText( QStringLiteral(
"80" ) );
159 mPrecision->setEnabled(
false );
160 mWidth->setValidator(
new QIntValidator( 1, 255,
this ) );
164 if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 10 )
165 mWidth->setText( QStringLiteral(
"10" ) );
166 mPrecision->setEnabled(
false );
167 mWidth->setValidator(
new QIntValidator( 1, 10,
this ) );
171 if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 20 )
172 mWidth->setText( QStringLiteral(
"20" ) );
173 if ( mPrecision->text().toInt() < 1 || mPrecision->text().toInt() > 15 )
174 mPrecision->setText( QStringLiteral(
"6" ) );
176 mPrecision->setEnabled(
true );
177 mWidth->setValidator(
new QIntValidator( 1, 20,
this ) );
190 ( mGeometryTypeBox->currentData( Qt::UserRole ).toInt() );
192 if ( mGeometryWithZRadioButton->isChecked() )
195 if ( mGeometryWithMRadioButton->isChecked() )
203 return mCrsSelector->crs();
208 mCrsSelector->setCrs(
crs );
211void QgsNewVectorLayerDialog::mAddAttributeButton_clicked()
213 const QString myName = mNameEdit->text();
214 const QString myWidth = mWidth->text();
215 const QString myPrecision = mPrecision->isEnabled() ? mPrecision->text() : QString();
217 const QString myType = mTypeBox->currentData( Qt::UserRole ).toString();
218 mAttributeView->addTopLevelItem(
new QTreeWidgetItem( QStringList() << myName << myType << myWidth << myPrecision ) );
224 if ( !mNameEdit->hasFocus() )
226 mNameEdit->setFocus();
230void QgsNewVectorLayerDialog::mRemoveAttributeButton_clicked()
232 delete mAttributeView->currentItem();
238 QTreeWidgetItemIterator it( mAttributeView );
241 QTreeWidgetItem *item = *it;
242 const QString type = QStringLiteral(
"%1;%2;%3" ).arg( item->text( 1 ), item->text( 2 ), item->text( 3 ) );
243 at.push_back( qMakePair( item->text( 0 ), type ) );
244 QgsDebugMsgLevel( QStringLiteral(
"appending %1//%2" ).arg( item->text( 0 ), type ), 2 );
252 QString myType = mFileFormatComboBox->currentData( Qt::UserRole ).toString();
258 return mFileEncoding->currentText();
261void QgsNewVectorLayerDialog::nameChanged(
const QString &name )
263 mAddAttributeButton->setDisabled( name.isEmpty() || !mAttributeView->findItems( name, Qt::MatchExactly ).isEmpty() );
266void QgsNewVectorLayerDialog::selectionChanged()
268 mRemoveAttributeButton->setDisabled( mAttributeView->selectedItems().isEmpty() );
269 mButtonUp->setDisabled( mAttributeView->selectedItems().isEmpty() );
270 mButtonDown->setDisabled( mAttributeView->selectedItems().isEmpty() );
273void QgsNewVectorLayerDialog::moveFieldsUp()
275 int currentRow = mAttributeView->currentIndex().row();
276 if ( currentRow == 0 )
279 mAttributeView->insertTopLevelItem( currentRow - 1, mAttributeView->takeTopLevelItem( currentRow ) );
280 mAttributeView->setCurrentIndex( mAttributeView->model()->index( currentRow - 1, 0 ) );
283void QgsNewVectorLayerDialog::moveFieldsDown()
285 int currentRow = mAttributeView->currentIndex().row();
286 if ( currentRow == mAttributeView->topLevelItemCount() - 1 )
289 mAttributeView->insertTopLevelItem( currentRow + 1, mAttributeView->takeTopLevelItem( currentRow ) );
290 mAttributeView->setCurrentIndex( mAttributeView->model()->index( currentRow + 1, 0 ) );
295 return mFileName->filePath();
303void QgsNewVectorLayerDialog::checkOk()
305 const bool ok = ( !mFileName->filePath().isEmpty() && mAttributeView->topLevelItemCount() > 0 && mGeometryTypeBox->currentIndex() != -1 );
306 mOkButton->setEnabled( ok );
314 if ( res.isEmpty() && error.isEmpty() )
319void QgsNewVectorLayerDialog::updateExtension()
324 if ( fileformat == QLatin1String(
"ESRI Shapefile" ) )
328 fileName = fileName.replace( fileName.lastIndexOf( QLatin1String(
".dbf" ), -1, Qt::CaseInsensitive ), 4, QLatin1String(
".shp" ) );
333 fileName = fileName.replace( fileName.lastIndexOf( QLatin1String(
".shp" ), -1, Qt::CaseInsensitive ), 4, QLatin1String(
".dbf" ) );
343 if ( !mNameEdit->text().trimmed().isEmpty() )
345 const QString currentFieldName = mNameEdit->text();
346 bool currentFound =
false;
347 QTreeWidgetItemIterator it( mAttributeView );
350 QTreeWidgetItem *item = *it;
351 if ( item->text( 0 ) == currentFieldName )
361 if ( QMessageBox::question(
this, windowTitle(),
362 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 ),
363 QMessageBox::Ok | QMessageBox::Cancel ) != QMessageBox::Ok )
372 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?" ),
373 QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel ) != QMessageBox::Yes )
381 errorMessage.clear();
384 if ( !initialPath.isEmpty() )
386 if ( geomDialog.exec() == QDialog::Rejected )
393 QString fileName = geomDialog.
filename();
396 QgsDebugMsgLevel( QStringLiteral(
"New file format will be: %1" ).arg( fileformat ), 2 );
402 settings.
setValue( QStringLiteral(
"UI/lastVectorFileFilterDir" ), QFileInfo( fileName ).absolutePath() );
403 settings.
setValue( QStringLiteral(
"UI/encoding" ), enc );
409 const bool success = QgsOgrProviderUtils::createEmptyDataSource( fileName, fileformat, enc, geometrytype,
attributes, srs, errorMessage );
417 errorMessage = QObject::tr(
"Geometry type not recognised" );
428void QgsNewVectorLayerDialog::showHelp()
430 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