Skip to content

Commit

Permalink
use file filters from MDAL
Browse files Browse the repository at this point in the history
  • Loading branch information
PeterPetrik committed Dec 17, 2018
1 parent e716602 commit 64b81bd
Show file tree
Hide file tree
Showing 9 changed files with 278 additions and 2 deletions.
26 changes: 26 additions & 0 deletions python/core/auto_generated/qgsproviderregistry.sip.in
Expand Up @@ -181,6 +181,32 @@ buildSupportedRasterFileFilter to a string, which is then returned.
This replaces :py:func:`QgsRasterLayer.buildSupportedRasterFileFilter()`
%End

virtual QString fileMeshFilters() const;
%Docstring
Returns mesh file filter string

Returns a string suitable for a QFileDialog of mesh file formats
supported by all data providers.

This walks through all data providers appending calls to their
fileMeshFilters to a string, which is then returned.

.. versionadded:: 3.6
%End

virtual QString fileMeshDatasetFilters() const;
%Docstring
Returns mesh's dataset file filter string

Returns a string suitable for a QFileDialog of mesh datasets file formats
supported by all data providers.

This walks through all data providers appending calls to their
fileMeshFilters to a string, which is then returned.

.. versionadded:: 3.6
%End

virtual QString databaseDrivers() const;
%Docstring
Returns a string containing the available database drivers
Expand Down
3 changes: 2 additions & 1 deletion src/app/mesh/qgsmeshlayerproperties.cpp
Expand Up @@ -31,6 +31,7 @@
#include "qgsprojectionselectiondialog.h"
#include "qgsrenderermeshpropertieswidget.h"
#include "qgssettings.h"
#include "qgsproviderregistry.h"

#include <QFileDialog>
#include <QMessageBox>
Expand Down Expand Up @@ -137,7 +138,7 @@ void QgsMeshLayerProperties::addDataset()
QString openFileString = QFileDialog::getOpenFileName( nullptr,
tr( "Load mesh datasets" ),
openFileDir,
QStringLiteral( "All files(*.*);;Results Files XMDF(*.xmdf);;Results Files DAT(*.dat)" ) );
QgsProviderRegistry::instance()->fileMeshDatasetFilters() );

if ( openFileString.isEmpty() )
{
Expand Down
28 changes: 28 additions & 0 deletions src/core/qgsproviderregistry.cpp
Expand Up @@ -38,6 +38,7 @@ typedef QString providerkey_t();
typedef QString description_t();
typedef bool isprovider_t();
typedef QString fileVectorFilters_t();
typedef void fileMeshFilters_t( QString &fileMeshFiltersString, QString &fileMeshDatasetFiltersString );
typedef void buildsupportedrasterfilefilter_t( QString &fileFiltersString );
typedef QString databaseDrivers_t();
typedef QString directoryDrivers_t();
Expand Down Expand Up @@ -233,6 +234,23 @@ void QgsProviderRegistry::init()
QgsDebugMsg( QStringLiteral( "Checking %1: ...loaded OK (%2 file filters)" ).arg( myLib.fileName() ).arg( fileRasterFilters.split( ";;" ).count() ) );
}

// now get mesh file filters, if any
fileMeshFilters_t *pFileMeshFilters = reinterpret_cast< fileMeshFilters_t * >( cast_to_fptr( myLib.resolve( "fileMeshFilters" ) ) );
if ( pFileMeshFilters )
{
QString fileMeshFilters;
QString fileMeshDatasetFilters;

pFileMeshFilters( fileMeshFilters, fileMeshDatasetFilters );

if ( !fileMeshFilters.isEmpty() )
mMeshFileFilters += fileMeshFilters;
if ( !fileMeshDatasetFilters.isEmpty() )
mMeshDatasetFileFilters += fileMeshDatasetFilters;

QgsDebugMsg( QStringLiteral( "Checking %1: ...loaded OK (%2 file mesh filters, %3 file dataset filters)" ).arg( myLib.fileName() ).arg( mMeshFileFilters.split( ";;" ).count() ).arg( mMeshDatasetFileFilters.split( ";;" ).count() ) );
}

// call initProvider() if such function is available - allows provider to register its services to QGIS
initProviderFunction_t *initFunc = reinterpret_cast< initProviderFunction_t * >( cast_to_fptr( myLib.resolve( "initProvider" ) ) );
if ( initFunc )
Expand Down Expand Up @@ -574,6 +592,16 @@ QString QgsProviderRegistry::fileRasterFilters() const
return mRasterFileFilters;
}

QString QgsProviderRegistry::fileMeshFilters() const
{
return mMeshFileFilters;
}

QString QgsProviderRegistry::fileMeshDatasetFilters() const
{
return mMeshDatasetFileFilters;
}

QString QgsProviderRegistry::databaseDrivers() const
{
return mDatabaseDrivers;
Expand Down
36 changes: 36 additions & 0 deletions src/core/qgsproviderregistry.h
Expand Up @@ -180,6 +180,32 @@ class CORE_EXPORT QgsProviderRegistry
*/
virtual QString fileRasterFilters() const;

/**
* Returns mesh file filter string
Returns a string suitable for a QFileDialog of mesh file formats
supported by all data providers.
This walks through all data providers appending calls to their
fileMeshFilters to a string, which is then returned.
\since QGIS 3.6
*/
virtual QString fileMeshFilters() const;

/**
* Returns mesh's dataset file filter string
Returns a string suitable for a QFileDialog of mesh datasets file formats
supported by all data providers.
This walks through all data providers appending calls to their
fileMeshFilters to a string, which is then returned.
\since QGIS 3.6
*/
virtual QString fileMeshDatasetFilters() const;

//! Returns a string containing the available database drivers
virtual QString databaseDrivers() const;
//! Returns a string containing the available directory drivers
Expand Down Expand Up @@ -257,6 +283,16 @@ class CORE_EXPORT QgsProviderRegistry
*/
QString mRasterFileFilters;

/**
* File filter string for raster files
*/
QString mMeshFileFilters;

/**
* File filter string for raster files
*/
QString mMeshDatasetFileFilters;

/**
* Available database drivers string for vector databases
*
Expand Down
87 changes: 87 additions & 0 deletions src/providers/mdal/qgsmdalprovider.cpp
Expand Up @@ -19,6 +19,7 @@

#include "qgsmdalprovider.h"
#include "qgstriangularmesh.h"
#include "qgslogger.h"

#ifdef HAVE_GUI
#include "qgssourceselectprovider.h"
Expand Down Expand Up @@ -170,6 +171,76 @@ QgsRectangle QgsMdalProvider::extent() const
return ret;
}

void QgsMdalProvider::fileMeshFilters( QString &fileMeshFiltersString, QString &fileMeshDatasetFiltersString )
{
DriverH mdalDriver;

// Grind through all the drivers and their respective metadata.
// We'll add a file filter for those drivers that have a file
// extension defined for them; the others, well, even though
// theoreticaly we can open those files because there exists a
// driver for them, the user will have to use the "All Files" to
// open datasets with no explicitly defined file name extension.

fileMeshFiltersString.clear();
fileMeshDatasetFiltersString.clear();

int driverCount = MDAL_driverCount();

QgsDebugMsg( QStringLiteral( "MDAL driver count: %1" ).arg( driverCount ) );

for ( int i = 0; i < driverCount; ++i )
{
mdalDriver = MDAL_driverFromIndex( i );
if ( !mdalDriver )
{
QgsLogger::warning( "unable to get driver " + QString::number( i ) );
continue;
}

QString longName = MDAL_DR_longName( mdalDriver );
QString driverFilters = MDAL_DR_filters( mdalDriver );
driverFilters = driverFilters.replace( QStringLiteral( ";;" ), QStringLiteral( " " ) );

bool isMeshDriver = MDAL_DR_meshLoadCapability( mdalDriver );

if ( longName.isEmpty() )
{
QgsLogger::warning( "invalid driver long name " + QString::number( i ) );
continue;
}

if ( !driverFilters.isEmpty() )
{
QString driverFilter = longName + " (" + driverFilters + ");;";
if ( isMeshDriver )
fileMeshFiltersString += driverFilter;
else
fileMeshDatasetFiltersString += driverFilter;
}
}

// sort file filters alphabetically
QStringList filters = fileMeshFiltersString.split( QStringLiteral( ";;" ), QString::SkipEmptyParts );
filters.sort();
fileMeshFiltersString = filters.join( QStringLiteral( ";;" ) ) + ";;";

filters = fileMeshDatasetFiltersString.split( QStringLiteral( ";;" ), QString::SkipEmptyParts );
filters.sort();
fileMeshDatasetFiltersString = filters.join( QStringLiteral( ";;" ) ) + ";;";

// can't forget the default case - first
fileMeshFiltersString.prepend( QObject::tr( "All files" ) + " (*);;" );
fileMeshDatasetFiltersString.prepend( QObject::tr( "All files" ) + " (*);;" );

// cleanup
if ( fileMeshFiltersString.endsWith( QLatin1String( ";;" ) ) ) fileMeshFiltersString.chop( 2 );
if ( fileMeshDatasetFiltersString.endsWith( QLatin1String( ";;" ) ) ) fileMeshDatasetFiltersString.chop( 2 );

QgsDebugMsg( "Mesh filter list built: " + fileMeshFiltersString );
QgsDebugMsg( "Mesh dataset filter list built: " + fileMeshDatasetFiltersString );
}

/*----------------------------------------------------------------------------------------------*/

bool QgsMdalProvider::addDataset( const QString &uri )
Expand Down Expand Up @@ -394,4 +465,20 @@ QGISEXTERN QList<QgsSourceSelectProvider *> *sourceSelectProviders()
return providers;
}

/**
Builds the list of mesh file filter strings
We query MDAL for a list of supported mesh formats; we then build
a list of file filter strings from that list to be used for meshes and
also one for datasets. We return a strings
that contains this list that is suitable for use in a
QFileDialog::getOpenFileNames() call.
\since QGIS 3.6
*/
QGISEXTERN void fileMeshFilters( QString &fileMeshFiltersString, QString &fileMeshDatasetFiltersString )
{
QgsMdalProvider::fileMeshFilters( fileMeshFiltersString, fileMeshDatasetFiltersString );
}

#endif
7 changes: 7 additions & 0 deletions src/providers/mdal/qgsmdalprovider.h
Expand Up @@ -69,6 +69,13 @@ class QgsMdalProvider : public QgsMeshDataProvider
QgsMeshDataBlock areFacesActive( QgsMeshDatasetIndex index, int faceIndex, int count ) const override;
QgsRectangle extent() const override;

/**
* Returns filters for meshes and datasets to be used in Open File Dialogs
* \param fileMeshFiltersString file mesh filters
* \param fileMeshDatasetFiltersString file mesh datasets filters
*/
static void fileMeshFilters( QString &fileMeshFiltersString, QString &fileMeshDatasetFiltersString );

private:
QVector<QgsMeshVertex> vertices( ) const;
QVector<QgsMeshFace> faces( ) const;
Expand Down
2 changes: 1 addition & 1 deletion src/providers/mdal/qgsmdalsourceselect.cpp
Expand Up @@ -28,7 +28,7 @@ QgsMdalSourceSelect::QgsMdalSourceSelect( QWidget *parent, Qt::WindowFlags fl, Q
setupButtons( buttonBox );

mFileWidget->setDialogTitle( tr( "Open MDAL Supported Mesh Dataset(s)" ) );
mFileWidget->setFilter( tr( "All Files (*);;GRIB File (*.grb *.grb2 *.bin *.grib *.grib1 *.grib2);;NetCDF File (*.nc);;2DM Mesh File (*.2dm);;3Di Results (results_3di.nc)" ) );
mFileWidget->setFilter( QgsProviderRegistry::instance()->fileMeshFilters() );
mFileWidget->setStorageMode( QgsFileWidget::GetMultipleFiles );
connect( mFileWidget, &QgsFileWidget::fileChanged, this, [ = ]( const QString & path )
{
Expand Down
4 changes: 4 additions & 0 deletions tests/src/providers/CMakeLists.txt
Expand Up @@ -15,12 +15,14 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/src/providers/wms
${CMAKE_SOURCE_DIR}/src/providers/postgres
${CMAKE_SOURCE_DIR}/src/providers/arcgisrest
${CMAKE_SOURCE_DIR}/src/providers/mdal
${CMAKE_SOURCE_DIR}/src/test
${CMAKE_BINARY_DIR}/src/core
)
INCLUDE_DIRECTORIES(SYSTEM
${QT_INCLUDE_DIR}
${GDAL_INCLUDE_DIR}
${MDAL_INCLUDE_DIR}
${QCA_INCLUDE_DIR}
${QTKEYCHAIN_INCLUDE_DIR}
${POSTGRES_INCLUDE_DIR}
Expand Down Expand Up @@ -85,6 +87,8 @@ TARGET_LINK_LIBRARIES(qgis_postgresprovidertest postgresprovider_a)
ADD_QGIS_TEST(postgresconntest testqgspostgresconn.cpp)
TARGET_LINK_LIBRARIES(qgis_postgresconntest postgresprovider_a)

ADD_QGIS_TEST(mdalprovidertest testqgsmdalprovider.cpp)

#############################################################
# WCS public servers test:
# No need to test on all platforms
Expand Down
87 changes: 87 additions & 0 deletions tests/src/providers/testqgsmdalprovider.cpp
@@ -0,0 +1,87 @@
/***************************************************************************
testqgsmdalprovider.cpp
--------------------------------------
Date : Decemeber 2018
Copyright : (C) 2018 by Peter Petrik
Email : zilolv@gmail.com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include <limits>

#include "qgstest.h"
#include <QObject>
#include <QString>
#include <QStringList>
#include <QApplication>
#include <QFileInfo>
#include <QDir>

//qgis includes...
#include <qgis.h>
#include <qgsapplication.h>
#include <qgsproviderregistry.h>

/**
* \ingroup UnitTests
* This is a unit test for the gdal provider
*/
class TestQgsMdalProvider : public QObject
{
Q_OBJECT

private slots:
void initTestCase();// will be called before the first testfunction is executed.
void cleanupTestCase();// will be called after the last testfunction was executed.
void init() {}// will be called before each testfunction is executed.
void cleanup() {}// will be called after every testfunction.

void filters();

private:
QString mTestDataDir;
QString mReport;
};

//runs before all tests
void TestQgsMdalProvider::initTestCase()
{
// init QGIS's paths - true means that all path will be inited from prefix
QgsApplication::init();
QgsApplication::initQgis();

mTestDataDir = QStringLiteral( TEST_DATA_DIR ) + '/'; //defined in CmakeLists.txt
mReport = QStringLiteral( "<h1>MDAL Provider Tests</h1>\n" );
}

//runs after all tests
void TestQgsMdalProvider::cleanupTestCase()
{
QgsApplication::exitQgis();
QString myReportFile = QDir::tempPath() + "/qgistest.html";
QFile myFile( myReportFile );
if ( myFile.open( QIODevice::WriteOnly | QIODevice::Append ) )
{
QTextStream myQTextStream( &myFile );
myQTextStream << mReport;
myFile.close();
}
}

void TestQgsMdalProvider::filters()
{
QString meshFilters = QgsProviderRegistry::instance()->fileMeshFilters();
QVERIFY(meshFilters.contains("*.2dm"));

QString datasetFilters = QgsProviderRegistry::instance()->fileMeshDatasetFilters();
QVERIFY(datasetFilters.contains("*.dat"));
}

QGSTEST_MAIN( TestQgsMdalProvider )
#include "testqgsmdalprovider.moc"

0 comments on commit 64b81bd

Please sign in to comment.