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 ) );
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 ) {
120 mAddAttributeButton->setEnabled(
false );
121 mRemoveAttributeButton->setEnabled(
false );
122 mButtonUp->setEnabled(
false );
123 mButtonDown->setEnabled(
false );
127 mFileName->setConfirmOverwrite(
false );
128 mFileName->setDialogTitle( tr(
"Save Layer As" ) );
130 mFileName->setDefaultRoot( settings.
value( QStringLiteral(
"UI/lastVectorFileFilterDir" ), QDir::homePath() ).toString() );
133 const QFileInfo tmplFileInfo( mFileName->filePath() );
134 settings.
setValue( QStringLiteral(
"UI/lastVectorFileFilterDir" ), tmplFileInfo.absolutePath() );
139void QgsNewVectorLayerDialog::mFileFormatComboBox_currentIndexChanged(
int index )
142 if ( mFileFormatComboBox->currentText() == tr(
"ESRI Shapefile" ) )
143 mNameEdit->setMaxLength( 10 );
145 mNameEdit->setMaxLength( 32767 );
148void QgsNewVectorLayerDialog::mTypeBox_currentIndexChanged(
int index )
154 if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 255 )
155 mWidth->setText( QStringLiteral(
"80" ) );
156 mPrecision->setEnabled(
false );
157 mWidth->setValidator(
new QIntValidator( 1, 255,
this ) );
161 if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 10 )
162 mWidth->setText( QStringLiteral(
"10" ) );
163 mPrecision->setEnabled(
false );
164 mWidth->setValidator(
new QIntValidator( 1, 10,
this ) );
168 if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 20 )
169 mWidth->setText( QStringLiteral(
"20" ) );
170 if ( mPrecision->text().toInt() < 1 || mPrecision->text().toInt() > 15 )
171 mPrecision->setText( QStringLiteral(
"6" ) );
173 mPrecision->setEnabled(
true );
174 mWidth->setValidator(
new QIntValidator( 1, 20,
this ) );
186 wkbType =
static_cast<Qgis::WkbType>( mGeometryTypeBox->currentData( Qt::UserRole ).toInt() );
188 if ( mGeometryWithZRadioButton->isChecked() )
191 if ( mGeometryWithMRadioButton->isChecked() )
199 return mCrsSelector->crs();
204 mCrsSelector->setCrs(
crs );
207void QgsNewVectorLayerDialog::mAddAttributeButton_clicked()
209 const QString myName = mNameEdit->text();
210 const QString myWidth = mWidth->text();
211 const QString myPrecision = mPrecision->isEnabled() ? mPrecision->text() : QString();
213 const QString myType = mTypeBox->currentData( Qt::UserRole ).toString();
214 mAttributeView->addTopLevelItem(
new QTreeWidgetItem( QStringList() << myName << myType << myWidth << myPrecision ) );
220 if ( !mNameEdit->hasFocus() )
222 mNameEdit->setFocus();
226void QgsNewVectorLayerDialog::mRemoveAttributeButton_clicked()
228 delete mAttributeView->currentItem();
234 QTreeWidgetItemIterator it( mAttributeView );
237 QTreeWidgetItem *item = *it;
238 const QString type = QStringLiteral(
"%1;%2;%3" ).arg( item->text( 1 ), item->text( 2 ), item->text( 3 ) );
239 at.push_back( qMakePair( item->text( 0 ), type ) );
240 QgsDebugMsgLevel( QStringLiteral(
"appending %1//%2" ).arg( item->text( 0 ), type ), 2 );
248 QString myType = mFileFormatComboBox->currentData( Qt::UserRole ).toString();
254 return mFileEncoding->currentText();
257void QgsNewVectorLayerDialog::nameChanged(
const QString &name )
259 mAddAttributeButton->setDisabled( name.isEmpty() || !mAttributeView->findItems( name, Qt::MatchExactly ).isEmpty() );
262void QgsNewVectorLayerDialog::selectionChanged()
264 mRemoveAttributeButton->setDisabled( mAttributeView->selectedItems().isEmpty() );
265 mButtonUp->setDisabled( mAttributeView->selectedItems().isEmpty() );
266 mButtonDown->setDisabled( mAttributeView->selectedItems().isEmpty() );
269void QgsNewVectorLayerDialog::moveFieldsUp()
271 int currentRow = mAttributeView->currentIndex().row();
272 if ( currentRow == 0 )
275 mAttributeView->insertTopLevelItem( currentRow - 1, mAttributeView->takeTopLevelItem( currentRow ) );
276 mAttributeView->setCurrentIndex( mAttributeView->model()->index( currentRow - 1, 0 ) );
279void QgsNewVectorLayerDialog::moveFieldsDown()
281 int currentRow = mAttributeView->currentIndex().row();
282 if ( currentRow == mAttributeView->topLevelItemCount() - 1 )
285 mAttributeView->insertTopLevelItem( currentRow + 1, mAttributeView->takeTopLevelItem( currentRow ) );
286 mAttributeView->setCurrentIndex( mAttributeView->model()->index( currentRow + 1, 0 ) );
291 return mFileName->filePath();
299void QgsNewVectorLayerDialog::checkOk()
301 const bool ok = ( !mFileName->filePath().isEmpty() && mAttributeView->topLevelItemCount() > 0 && mGeometryTypeBox->currentIndex() != -1 );
302 mOkButton->setEnabled( ok );
310 if ( res.isEmpty() && error.isEmpty() )
315void QgsNewVectorLayerDialog::updateExtension()
320 if ( fileformat == QLatin1String(
"ESRI Shapefile" ) )
324 fileName = fileName.replace( fileName.lastIndexOf( QLatin1String(
".dbf" ), -1, Qt::CaseInsensitive ), 4, QLatin1String(
".shp" ) );
329 fileName = fileName.replace( fileName.lastIndexOf( QLatin1String(
".shp" ), -1, Qt::CaseInsensitive ), 4, QLatin1String(
".dbf" ) );
338 if ( !mNameEdit->text().trimmed().isEmpty() )
340 const QString currentFieldName = mNameEdit->text();
341 bool currentFound =
false;
342 QTreeWidgetItemIterator it( mAttributeView );
345 QTreeWidgetItem *item = *it;
346 if ( item->text( 0 ) == currentFieldName )
356 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 )
365 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 )
373 errorMessage.clear();
376 if ( !initialPath.isEmpty() )
378 if ( geomDialog.exec() == QDialog::Rejected )
385 QString fileName = geomDialog.
filename();
388 QgsDebugMsgLevel( QStringLiteral(
"New file format will be: %1" ).arg( fileformat ), 2 );
394 settings.
setValue( QStringLiteral(
"UI/lastVectorFileFilterDir" ), QFileInfo( fileName ).absolutePath() );
395 settings.
setValue( QStringLiteral(
"UI/encoding" ), enc );
401 const bool success = QgsOgrProviderUtils::createEmptyDataSource( fileName, fileformat, enc, geometrytype,
attributes, srs, errorMessage );
409 errorMessage = QObject::tr(
"Geometry type not recognised" );
420void QgsNewVectorLayerDialog::showHelp()
422 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