Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
New shapefile layer dialog: avoid accidental overwrite of a file whos…
…e extension is not specified

and avoid closing the dialog when the user doesn't confirm overwriting

Fixes #44299
  • Loading branch information
rouault authored and nyalldawson committed Sep 24, 2021
1 parent 2ed7b3e commit b5c99af
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 31 deletions.
4 changes: 4 additions & 0 deletions python/gui/auto_generated/qgsnewvectorlayerdialog.sip.in
Expand Up @@ -107,6 +107,10 @@ Sets the ``crs`` value for the new layer in the dialog.
.. versionadded:: 3.0
%End

public slots:
virtual void accept();


};

/************************************************************************
Expand Down
72 changes: 41 additions & 31 deletions src/gui/qgsnewvectorlayerdialog.cpp
Expand Up @@ -100,21 +100,9 @@ QgsNewVectorLayerDialog::QgsNewVectorLayerDialog( QWidget *parent, Qt::WindowFla
mAttributeView->addTopLevelItem( new QTreeWidgetItem( QStringList() << QStringLiteral( "id" ) << QStringLiteral( "Integer" ) << QStringLiteral( "10" ) << QString() ) );
connect( mNameEdit, &QLineEdit::textChanged, this, &QgsNewVectorLayerDialog::nameChanged );
connect( mAttributeView, &QTreeWidget::itemSelectionChanged, this, &QgsNewVectorLayerDialog::selectionChanged );
connect( mGeometryTypeBox, static_cast<void( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, [ = ]( int index )
connect( mGeometryTypeBox, static_cast<void( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, [ = ]( int )
{
QString fileName = mFileName->filePath();
if ( !fileName.isEmpty() )
{
if ( index == 0 )
{
fileName = fileName.replace( fileName.lastIndexOf( QLatin1String( ".shp" ), -1, Qt::CaseInsensitive ), 4, QLatin1String( ".dbf" ) );
}
else
{
fileName = fileName.replace( fileName.lastIndexOf( QLatin1String( ".dbf" ), -1, Qt::CaseInsensitive ), 4, QLatin1String( ".shp" ) );
}
mFileName->setFilePath( fileName );
}
updateExtension();
checkOk();
} );

Expand Down Expand Up @@ -284,6 +272,41 @@ QString QgsNewVectorLayerDialog::runAndCreateLayer( QWidget *parent, QString *pE
return res;
}

void QgsNewVectorLayerDialog::updateExtension()
{
QString fileName = filename();
const QString fileformat = selectedFileFormat();
const QgsWkbTypes::Type geometrytype = selectedType();
if ( fileformat == QLatin1String( "ESRI Shapefile" ) )
{
if ( geometrytype != QgsWkbTypes::NoGeometry )
{
fileName = fileName.replace( fileName.lastIndexOf( QLatin1String( ".dbf" ), -1, Qt::CaseInsensitive ), 4, QLatin1String( ".shp" ) );
if ( !fileName.endsWith( QLatin1String( ".shp" ), Qt::CaseInsensitive ) )
fileName += QLatin1String( ".shp" );
}
else
{
fileName = fileName.replace( fileName.lastIndexOf( QLatin1String( ".shp" ), -1, Qt::CaseInsensitive ), 4, QLatin1String( ".dbf" ) );
if ( !fileName.endsWith( QLatin1String( ".dbf" ), Qt::CaseInsensitive ) )
fileName += QLatin1String( ".dbf" );
}
}
setFilename( fileName );

}

void QgsNewVectorLayerDialog::accept()
{
updateExtension();

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 )
return;

QDialog::accept();
}

QString QgsNewVectorLayerDialog::execAndCreateLayer( QString &errorMessage, QWidget *parent, const QString &initialPath, QString *encoding, const QgsCoordinateReferenceSystem &crs )
{
errorMessage.clear();
Expand All @@ -296,30 +319,17 @@ QString QgsNewVectorLayerDialog::execAndCreateLayer( QString &errorMessage, QWid
return QString();
}

if ( QFile::exists( geomDialog.filename() ) && QMessageBox::warning( parent, 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 )
return QString();
const QString fileformat = geomDialog.selectedFileFormat();
const QgsWkbTypes::Type geometrytype = geomDialog.selectedType();
QString fileName = geomDialog.filename();

QgsWkbTypes::Type geometrytype = geomDialog.selectedType();
QString fileformat = geomDialog.selectedFileFormat();
QString enc = geomDialog.selectedFileEncoding();
const QString enc = geomDialog.selectedFileEncoding();
QgsDebugMsg( QStringLiteral( "New file format will be: %1" ).arg( fileformat ) );

QList< QPair<QString, QString> > attributes;
geomDialog.attributes( attributes );

QgsSettings settings;
QString fileName = geomDialog.filename();
if ( fileformat == QLatin1String( "ESRI Shapefile" ) && ( geometrytype != QgsWkbTypes::NoGeometry && !fileName.endsWith( QLatin1String( ".shp" ), Qt::CaseInsensitive ) ) )
fileName += QLatin1String( ".shp" );
else if ( fileformat == QLatin1String( "ESRI Shapefile" ) && ( geometrytype == QgsWkbTypes::NoGeometry && !fileName.endsWith( QLatin1String( ".dbf" ), Qt::CaseInsensitive ) ) )
{
if ( fileName.endsWith( QLatin1String( ".shp" ), Qt::CaseInsensitive ) )
fileName = fileName.replace( fileName.lastIndexOf( QLatin1String( ".shp" ), -1, Qt::CaseInsensitive ), 4, QLatin1String( ".dbf" ) );
else
fileName += QLatin1String( ".dbf" );
}

settings.setValue( QStringLiteral( "UI/lastVectorFileFilterDir" ), QFileInfo( fileName ).absolutePath() );
settings.setValue( QStringLiteral( "UI/encoding" ), enc );

Expand Down
5 changes: 5 additions & 0 deletions src/gui/qgsnewvectorlayerdialog.h
Expand Up @@ -112,6 +112,9 @@ class GUI_EXPORT QgsNewVectorLayerDialog: public QDialog, private Ui::QgsNewVect
*/
void setCrs( const QgsCoordinateReferenceSystem &crs );

public slots:
void accept() override;

private slots:
void mAddAttributeButton_clicked();
void mRemoveAttributeButton_clicked();
Expand All @@ -126,6 +129,8 @@ class GUI_EXPORT QgsNewVectorLayerDialog: public QDialog, private Ui::QgsNewVect

private:
QPushButton *mOkButton = nullptr;

void updateExtension();
};

#endif //qgsnewvectorlayerdialog_H

0 comments on commit b5c99af

Please sign in to comment.