Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New shapefile layer dialog: avoid accidental overwrite of a file whose extension is not specified #45207

Merged
merged 2 commits into from
Sep 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions python/gui/auto_generated/qgsnewvectorlayerdialog.sip.in
Original file line number Diff line number Diff line change
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
69 changes: 39 additions & 30 deletions src/gui/qgsnewvectorlayerdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "qgsogrprovider.h"
#include "qgsgui.h"
#include "qgsiconutils.h"
#include "qgsfileutils.h"

#include <QPushButton>
#include <QComboBox>
Expand Down Expand Up @@ -109,21 +110,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 @@ -293,6 +282,39 @@ 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" ) );
fileName = QgsFileUtils::ensureFileNameHasExtension( fileName, { QStringLiteral( "shp" ) } );
}
else
{
fileName = fileName.replace( fileName.lastIndexOf( QLatin1String( ".shp" ), -1, Qt::CaseInsensitive ), 4, QLatin1String( ".dbf" ) );
fileName = QgsFileUtils::ensureFileNameHasExtension( fileName, { QStringLiteral( "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 @@ -305,30 +327,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 QgsWkbTypes::Type geometrytype = geomDialog.selectedType();
const QString fileformat = geomDialog.selectedFileFormat();
const QgsWkbTypes::Type geometrytype = geomDialog.selectedType();
QString fileName = geomDialog.filename();

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
Original file line number Diff line number Diff line change
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