Skip to content

Commit

Permalink
[GUI] VectorLayerSaveAsDialog: allow to select an existing FileGeodat…
Browse files Browse the repository at this point in the history
…abase (fixes #54566)

This fix isn't totally satisfactory, because AFAICS there's no way in Qt
FileDialog to both be able select an existing directory (.gdb) without
entering into it, or select the parent of a new directory to be created.
We'd need something between the GetFile or GetDirectory storage modes,
although it is not clear how that could be implemented, without 2
separate buttons in the QtFileDialog (like "Select directory" and "Enter
directory")
The hack/fix here is to add to the (*.gdb *.GDB) filter an extra "gdb"
file that matches the "gdb" file found in existing File Geodatabase.
And remove it from the filename once it is selected.
  • Loading branch information
rouault authored and nyalldawson committed Oct 3, 2023
1 parent 4735bd9 commit 0c651ff
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 4 deletions.
16 changes: 12 additions & 4 deletions src/gui/ogr/qgsvectorlayersaveasdialog.cpp
Expand Up @@ -433,15 +433,23 @@ void QgsVectorLayerSaveAsDialog::mFormatComboBox_currentIndexChanged( int idx )
Q_UNUSED( idx )

mFilename->setEnabled( true );
mFilename->setFilter( QgsVectorFileWriter::filterForDriver( format() ) );
QString filter = QgsVectorFileWriter::filterForDriver( format() );
// A bit of hack to solve https://github.com/qgis/QGIS/issues/54566
// to be able to select an existing File Geodatabase, we add in the filter
// the "gdb" file that is found in all File Geodatabase .gdb directory
// to allow the user to select it. We need to detect this particular case
// in QgsFileWidget::openFileDialog() to remove this gdb file from the
// selected filename
if ( format() == QLatin1String( "OpenFileGDB" ) || format() == QLatin1String( "FileGDB" ) )
filter = QStringLiteral( "%1 (*.gdb *.GDB gdb)" ).arg( tr( "ESRI File Geodatabase" ) );
mFilename->setFilter( filter );

// if output filename already defined we need to replace old suffix
// to avoid double extensions like .gpkg.shp
if ( !mFilename->filePath().isEmpty() )
{
QRegularExpression rx( "\\.(.*?)[\\s]" );
QString ext;
ext = rx.match( QgsVectorFileWriter::filterForDriver( format() ) ).captured( 1 );
const thread_local QRegularExpression rx( "\\.(.*?)[\\s]" );
const QString ext = rx.match( filter ).captured( 1 );
if ( !ext.isEmpty() )
{
QFileInfo fi( mFilename->filePath() );
Expand Down
12 changes: 12 additions & 0 deletions src/gui/qgsfilewidget.cpp
Expand Up @@ -337,6 +337,18 @@ void QgsFileWidget::openFileDialog()
// make sure filename ends with filter. This isn't automatically done by
// getSaveFileName on some platforms (e.g. gnome)
fileName = QgsFileUtils::addExtensionFromFilter( fileName, mSelectedFilter );

// A bit of hack to solve https://github.com/qgis/QGIS/issues/54566
// to be able to select an existing File Geodatabase, we add in the filter
// the "gdb" file that is found in all File Geodatabase .gdb directory
// to allow the user to select it. We now need to remove this gdb file
// (which became gdb.gdb due to above logic) from the selected filename
if ( mFilter.contains( QLatin1String( "(*.gdb *.GDB gdb)" ) ) &&
( fileName.endsWith( QLatin1String( "/gdb.gdb" ) ) ||
fileName.endsWith( QLatin1String( "\\gdb.gdb" ) ) ) )
{
fileName.chop( static_cast<int>( strlen( "/gdb.gdb" ) ) );
}
}
break;
}
Expand Down

0 comments on commit 0c651ff

Please sign in to comment.