Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
add list of available GDAL vector drivers to the QGIS options (fix #1…
…8738)

This allows to select which driver to use if more than one driver can be
used to open dataset, as in the case of FileGDB.
  • Loading branch information
alexbruy committed Aug 26, 2020
1 parent cee6a76 commit 744380b
Show file tree
Hide file tree
Showing 3 changed files with 274 additions and 146 deletions.
104 changes: 81 additions & 23 deletions src/app/qgsoptions.cpp
Expand Up @@ -99,7 +99,7 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl, const QList<QgsOpti
setupUi( this );
connect( cbxProjectDefaultNew, &QCheckBox::toggled, this, &QgsOptions::cbxProjectDefaultNew_toggled );
connect( leLayerGlobalCrs, &QgsProjectionSelectionWidget::crsChanged, this, &QgsOptions::leLayerGlobalCrs_crsChanged );
connect( lstGdalDrivers, &QTreeWidget::itemDoubleClicked, this, &QgsOptions::lstGdalDrivers_itemDoubleClicked );
connect( lstRasterDrivers, &QTreeWidget::itemDoubleClicked, this, &QgsOptions::lstRasterDrivers_itemDoubleClicked );
connect( mProjectOnLaunchCmbBx, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsOptions::mProjectOnLaunchCmbBx_currentIndexChanged );
connect( spinFontSize, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), this, &QgsOptions::spinFontSize_valueChanged );
connect( mFontFamilyRadioQt, &QRadioButton::released, this, &QgsOptions::mFontFamilyRadioQt_released );
Expand Down Expand Up @@ -1890,7 +1890,7 @@ void QgsOptions::leLayerGlobalCrs_crsChanged( const QgsCoordinateReferenceSystem
mLayerDefaultCrs = crs;
}

void QgsOptions::lstGdalDrivers_itemDoubleClicked( QTreeWidgetItem *item, int column )
void QgsOptions::lstRasterDrivers_itemDoubleClicked( QTreeWidgetItem *item, int column )
{
Q_UNUSED( column )
// edit driver if driver supports write
Expand Down Expand Up @@ -2259,6 +2259,7 @@ void QgsOptions::loadGdalDriverList()
QStringList myDrivers;
QStringList myGdalWriteDrivers;
QMap<QString, QString> myDriversFlags, myDriversExt, myDriversLongName;
QMap<QString, bool> driversType; // true for raster, false for vector

// make sure we save list when accept()
mLoadedGdalDriverList = true;
Expand All @@ -2280,33 +2281,53 @@ void QgsOptions::loadGdalDriverList()
continue;
}

// in GDAL 2.0 vector and mixed drivers are returned by GDALGetDriver, so filter out non-raster drivers
// TODO add same UI for vector drivers
// in GDAL 2.0 both vector and raster drivers are returned by GDALGetDriver
if ( QString( GDALGetMetadataItem( myGdalDriver, GDAL_DCAP_RASTER, nullptr ) ) != QLatin1String( "YES" ) )
continue;
{
driversType[myGdalDriverDescription] = false;
}
else
{
driversType[myGdalDriverDescription] = true;
}

myGdalDriverDescription = GDALGetDescription( myGdalDriver );
myDrivers << myGdalDriverDescription;

QgsDebugMsg( QStringLiteral( "driver #%1 - %2" ).arg( i ).arg( myGdalDriverDescription ) );

// get driver R/W flags, taken from GDALGeneralCmdLineProcessor()
const char *pszRWFlag, *pszVirtualIO;
if ( QgsGdalUtils::supportsRasterCreate( myGdalDriver ) )
// get driver R/W flags, adopted from GDALGeneralCmdLineProcessor()
QString driverFlags = "";
if ( driversType[myGdalDriverDescription] )
{
myGdalWriteDrivers << myGdalDriverDescription;
pszRWFlag = "rw+";
if ( QgsGdalUtils::supportsRasterCreate( myGdalDriver ) )
{
myGdalWriteDrivers << myGdalDriverDescription;
driverFlags = "rw+";
}
else if ( GDALGetMetadataItem( myGdalDriver, GDAL_DCAP_CREATECOPY,
nullptr ) )
driverFlags = "rw";
else
driverFlags = "ro";
}
else if ( GDALGetMetadataItem( myGdalDriver, GDAL_DCAP_CREATECOPY,
nullptr ) )
pszRWFlag = "rw";
else
pszRWFlag = "ro";
{
if ( GDALGetMetadataItem( myGdalDriver, GDAL_DCAP_OPEN, nullptr ) )
driverFlags = "r";

if ( GDALGetMetadataItem( myGdalDriver, GDAL_DCAP_CREATE, nullptr ) )
driverFlags += "w+";
else if ( GDALGetMetadataItem( myGdalDriver, GDAL_DCAP_CREATECOPY, nullptr ) )
driverFlags += "w";
else
driverFlags += "o";
}

if ( GDALGetMetadataItem( myGdalDriver, GDAL_DCAP_VIRTUALIO, nullptr ) )
pszVirtualIO = "v";
else
pszVirtualIO = "";
myDriversFlags[myGdalDriverDescription] = QStringLiteral( "%1%2" ).arg( pszRWFlag, pszVirtualIO );
driverFlags += "v";

myDriversFlags[myGdalDriverDescription] = driverFlags;

// get driver extensions and long name
// the gdal provider can override/add extensions but there is no interface to query this
Expand Down Expand Up @@ -2344,13 +2365,24 @@ void QgsOptions::loadGdalDriverList()
QString myFlags = myDriversFlags[myName];
mypItem->setText( 2, myFlags );
mypItem->setText( 3, myDriversLongName[myName] );
lstGdalDrivers->addTopLevelItem( mypItem );
if ( driversType[myName] )
{
lstRasterDrivers->addTopLevelItem( mypItem );
}
else
{
lstVectorDrivers->addTopLevelItem( mypItem );
}
}

// adjust column width
for ( int i = 0; i < 4; i++ )
{
lstGdalDrivers->resizeColumnToContents( i );
lstGdalDrivers->setColumnWidth( i, lstGdalDrivers->columnWidth( i ) + 5 );
lstRasterDrivers->resizeColumnToContents( i );
lstRasterDrivers->setColumnWidth( i, lstRasterDrivers->columnWidth( i ) + 5 );

lstVectorDrivers->resizeColumnToContents( i );
lstVectorDrivers->setColumnWidth( i, lstVectorDrivers->columnWidth( i ) + 5 );
}

// populate cmbEditCreateOptions with gdal write drivers - sorted, GTiff first
Expand All @@ -2374,9 +2406,10 @@ void QgsOptions::saveGdalDriverList()
const auto oldSkippedGdalDrivers = QgsApplication::skippedGdalDrivers();
auto deferredSkippedGdalDrivers = QgsApplication::deferredSkippedGdalDrivers();
QStringList skippedGdalDrivers;
for ( int i = 0; i < lstGdalDrivers->topLevelItemCount(); i++ )
// raster drivers
for ( int i = 0; i < lstRasterDrivers->topLevelItemCount(); i++ )
{
QTreeWidgetItem *mypItem = lstGdalDrivers->topLevelItem( i );
QTreeWidgetItem *mypItem = lstRasterDrivers->topLevelItem( i );
const auto &driverName( mypItem->text( 0 ) );
if ( mypItem->checkState( 0 ) == Qt::Unchecked )
{
Expand All @@ -2396,6 +2429,31 @@ void QgsOptions::saveGdalDriverList()
}
}
}

// vector drivers
for ( int i = 0; i < lstVectorDrivers->topLevelItemCount(); i++ )
{
QTreeWidgetItem *mypItem = lstVectorDrivers->topLevelItem( i );
const auto &driverName( mypItem->text( 0 ) );
if ( mypItem->checkState( 0 ) == Qt::Unchecked )
{
skippedGdalDrivers << driverName;
if ( !deferredSkippedGdalDrivers.contains( driverName ) &&
!oldSkippedGdalDrivers.contains( driverName ) )
{
deferredSkippedGdalDrivers << driverName;
driverUnregisterNeeded = true;
}
}
else
{
if ( deferredSkippedGdalDrivers.contains( driverName ) )
{
deferredSkippedGdalDrivers.removeAll( driverName );
}
}
}

if ( driverUnregisterNeeded )
{
QMessageBox::information( this, tr( "Drivers Disabled" ),
Expand Down
2 changes: 1 addition & 1 deletion src/app/qgsoptions.h
Expand Up @@ -86,7 +86,7 @@ class APP_EXPORT QgsOptions : public QgsOptionsDialogBase, private Ui::QgsOption
void resetTemplateFolder();
//! Slot called when user chooses to change the default 'on the fly' projection.
void leLayerGlobalCrs_crsChanged( const QgsCoordinateReferenceSystem &crs );
void lstGdalDrivers_itemDoubleClicked( QTreeWidgetItem *item, int column );
void lstRasterDrivers_itemDoubleClicked( QTreeWidgetItem *item, int column );
void editCreateOptions();
void editPyramidsOptions();
void editGdalDriver( const QString &driverName );
Expand Down

0 comments on commit 744380b

Please sign in to comment.