Skip to content

Commit

Permalink
WFS provider: declare its QgsSQLComposerDialog implementation as a su…
Browse files Browse the repository at this point in the history
…bset string editor provider
  • Loading branch information
rouault authored and nyalldawson committed Nov 16, 2020
1 parent 1bd83fb commit 4317d76
Show file tree
Hide file tree
Showing 8 changed files with 311 additions and 202 deletions.
1 change: 1 addition & 0 deletions src/providers/wfs/CMakeLists.txt
Expand Up @@ -35,6 +35,7 @@ if (WITH_GUI)
qgswfssourceselect.cpp
qgswfsnewconnection.cpp
qgswfsguiutils.cpp
qgswfssubsetstringeditor.cpp
)
endif()

Expand Down
2 changes: 2 additions & 0 deletions src/providers/wfs/qgswfsprovider.h
Expand Up @@ -122,6 +122,8 @@ class QgsWFSProvider final: public QgsVectorDataProvider

bool empty() const override;

std::shared_ptr<QgsWFSSharedData> sharedData() const { return mShared; }

private slots:

void featureReceivedAnalyzeOneFeature( QVector<QgsFeatureUniqueIdPair> );
Expand Down
32 changes: 31 additions & 1 deletion src/providers/wfs/qgswfsprovidergui.cpp
Expand Up @@ -18,7 +18,8 @@
#include "qgswfssourceselect.h"
#include "qgssourceselectprovider.h"
#include "qgsproviderguimetadata.h"

#include "qgssubsetstringeditorprovider.h"
#include "qgswfssubsetstringeditor.h"

//! Provider for WFS layers source select
class QgsWfsSourceSelectProvider : public QgsSourceSelectProvider
Expand All @@ -35,6 +36,29 @@ class QgsWfsSourceSelectProvider : public QgsSourceSelectProvider
}
};

//! Provider for dedicated subset string editor for WFS layers
class QgsWfsSubsetStringEditorProvider: public QgsSubsetStringEditorProvider
{
public:

QString providerKey() const override { return QgsWFSProvider::WFS_PROVIDER_KEY; }

bool canHandleLayer( QgsVectorLayer *layer ) const override
{
QgsDataProvider *provider = layer->dataProvider();
return static_cast< bool >( dynamic_cast<QgsWFSProvider *>( provider ) );
}

QgsSubsetStringEditorInterface *createDialog( QgsVectorLayer *layer, QWidget *parent, Qt::WindowFlags fl ) override
{
QgsDataProvider *provider = layer->dataProvider();
QgsWFSProvider *wfsProvider = dynamic_cast<QgsWFSProvider *>( provider );
if ( !wfsProvider )
return nullptr;
return QgsWfsSubsetStringEditor::create( layer, wfsProvider, parent, fl );
}
};


class QgsWfsProviderGuiMetadata: public QgsProviderGuiMetadata
{
Expand All @@ -57,6 +81,12 @@ class QgsWfsProviderGuiMetadata: public QgsProviderGuiMetadata
<< new QgsWfsDataItemGuiProvider;
}

QList<QgsSubsetStringEditorProvider *> subsetStringEditorProviders() override
{
return QList<QgsSubsetStringEditorProvider *>()
<< new QgsWfsSubsetStringEditorProvider;
}

};


Expand Down
2 changes: 2 additions & 0 deletions src/providers/wfs/qgswfsshareddata.h
Expand Up @@ -46,6 +46,8 @@ class QgsWFSSharedData : public QObject, public QgsBackgroundCachedSharedData

bool hasGeometry() const override { return !mGeometryAttribute.isEmpty(); }

const QgsWfsCapabilities::Capabilities &capabilities() const { return mCaps; }

signals:

//! Raise error
Expand Down
171 changes: 4 additions & 167 deletions src/providers/wfs/qgswfssourceselect.cpp
Expand Up @@ -35,6 +35,7 @@
#include "qgsgui.h"
#include "qgsquerybuilder.h"
#include "qgswfsguiutils.h"
#include "qgswfssubsetstringeditor.h"

#include <QDomDocument>
#include <QListWidgetItem>
Expand Down Expand Up @@ -531,82 +532,6 @@ void QgsWFSSourceSelect::addButtonClicked()
}
}

QgsWFSValidatorCallback::QgsWFSValidatorCallback( QObject *parent,
const QgsWFSDataSourceURI &uri,
const QString &allSql,
const QgsWfsCapabilities::Capabilities &caps )
: QObject( parent )
, mURI( uri )
, mAllSql( allSql )
, mCaps( caps )
{
}

bool QgsWFSValidatorCallback::isValid( const QString &sqlStr, QString &errorReason, QString &warningMsg )
{
errorReason.clear();
if ( sqlStr.isEmpty() || sqlStr == mAllSql )
return true;

QgsWFSDataSourceURI uri( mURI );
uri.setSql( sqlStr );

QgsDataProvider::ProviderOptions options;
QgsWFSProvider p( uri.uri(), options, mCaps );
if ( !p.isValid() )
{
errorReason = p.processSQLErrorMsg();
return false;
}
warningMsg = p.processSQLWarningMsg();

return true;
}

QgsWFSTableSelectedCallback::QgsWFSTableSelectedCallback( QgsSQLComposerDialog *dialog,
const QgsWFSDataSourceURI &uri,
const QgsWfsCapabilities::Capabilities &caps )
: QObject( dialog )
, mDialog( dialog )
, mURI( uri )
, mCaps( caps )
{
}

void QgsWFSTableSelectedCallback::tableSelected( const QString &name )
{
QString typeName( QgsSQLStatement::stripQuotedIdentifier( name ) );
QString prefixedTypename( mCaps.addPrefixIfNeeded( typeName ) );
if ( prefixedTypename.isEmpty() )
return;
QgsWFSDataSourceURI uri( mURI );
uri.setTypeName( prefixedTypename );

QgsDataProvider::ProviderOptions providerOptions;
QgsWFSProvider p( uri.uri(), providerOptions, mCaps );
if ( !p.isValid() )
{
return;
}

QList< QgsSQLComposerDialog::PairNameType> fieldList;
QString fieldNamePrefix( QgsSQLStatement::quotedIdentifierIfNeeded( typeName ) + "." );
const auto constToList = p.fields().toList();
for ( const QgsField &field : constToList )
{
QString fieldName( fieldNamePrefix + QgsSQLStatement::quotedIdentifierIfNeeded( field.name() ) );
fieldList << QgsSQLComposerDialog::PairNameType( fieldName, field.typeName() );
}
if ( !p.geometryAttribute().isEmpty() )
{
QString fieldName( fieldNamePrefix + QgsSQLStatement::quotedIdentifierIfNeeded( p.geometryAttribute() ) );
fieldList << QgsSQLComposerDialog::PairNameType( fieldName, QStringLiteral( "geometry" ) );
}
fieldList << QgsSQLComposerDialog::PairNameType( fieldNamePrefix + "*", QString() );

mDialog->addColumnNames( fieldList, name );
}

void QgsWFSSourceSelect::buildQuery( const QModelIndex &index )
{
if ( !index.isValid() )
Expand Down Expand Up @@ -681,97 +606,9 @@ void QgsWFSSourceSelect::buildQuery( const QModelIndex &index )
sql = allSql;
}

QgsSQLComposerDialog *d = new QgsSQLComposerDialog( this );

QgsWFSValidatorCallback *validatorCbk = new QgsWFSValidatorCallback( d, uri, allSql, mCaps );
d->setSQLValidatorCallback( validatorCbk );

QgsWFSTableSelectedCallback *tableSelectedCbk = new QgsWFSTableSelectedCallback( d, uri, mCaps );
d->setTableSelectedCallback( tableSelectedCbk );

const bool bSupportJoins = mCaps.featureTypes.size() > 1 && mCaps.supportsJoins;
d->setSupportMultipleTables( bSupportJoins, QgsSQLStatement::quotedIdentifierIfNeeded( displayedTypeName ) );

QMap< QString, QString > mapTypenameToTitle;
Q_FOREACH ( const QgsWfsCapabilities::FeatureType f, mCaps.featureTypes )
mapTypenameToTitle[f.name] = f.title;

QList< QgsSQLComposerDialog::PairNameTitle > tablenames;
tablenames << QgsSQLComposerDialog::PairNameTitle(
QgsSQLStatement::quotedIdentifierIfNeeded( displayedTypeName ), mapTypenameToTitle[typeName] );
if ( bSupportJoins )
{
for ( int i = 0; i < mModel->rowCount(); i++ )
{
const QString iterTypename = mModel->index( i, MODEL_IDX_NAME ).data().toString();
if ( iterTypename != typeName )
{
QString displayedIterTypename( iterTypename );
QString unprefixedIterTypename( QgsWFSUtils::removeNamespacePrefix( iterTypename ) );
if ( !mCaps.setAmbiguousUnprefixedTypename.contains( unprefixedIterTypename ) )
displayedIterTypename = unprefixedIterTypename;

tablenames << QgsSQLComposerDialog::PairNameTitle(
QgsSQLStatement::quotedIdentifierIfNeeded( displayedIterTypename ), mapTypenameToTitle[iterTypename] );
}
}
}
d->addTableNames( tablenames );

QList< QgsSQLComposerDialog::Function> functionList;
Q_FOREACH ( const QgsWfsCapabilities::Function &f, mCaps.functionList )
{
QgsSQLComposerDialog::Function dialogF;
dialogF.name = f.name;
dialogF.returnType = f.returnType;
dialogF.minArgs = f.minArgs;
dialogF.maxArgs = f.maxArgs;
Q_FOREACH ( const QgsWfsCapabilities::Argument &arg, f.argumentList )
{
dialogF.argumentList << QgsSQLComposerDialog::Argument( arg.name, arg.type );
}
functionList << dialogF;
}
d->addFunctions( functionList );

QList< QgsSQLComposerDialog::Function> spatialPredicateList;
Q_FOREACH ( const QgsWfsCapabilities::Function &f, mCaps.spatialPredicatesList )
{
QgsSQLComposerDialog::Function dialogF;
dialogF.name = f.name;
dialogF.returnType = f.returnType;
dialogF.minArgs = f.minArgs;
dialogF.maxArgs = f.maxArgs;
Q_FOREACH ( const QgsWfsCapabilities::Argument &arg, f.argumentList )
{
dialogF.argumentList << QgsSQLComposerDialog::Argument( arg.name, arg.type );
}
spatialPredicateList << dialogF;
}
d->addSpatialPredicates( spatialPredicateList );

QList< QgsSQLComposerDialog::PairNameType> fieldList;
QString fieldNamePrefix;
if ( bSupportJoins )
{
fieldNamePrefix = QgsSQLStatement::quotedIdentifierIfNeeded( displayedTypeName ) + ".";
}
const auto constToList = p.fields().toList();
for ( const QgsField &field : constToList )
{
QString fieldName( fieldNamePrefix + QgsSQLStatement::quotedIdentifierIfNeeded( field.name() ) );
fieldList << QgsSQLComposerDialog::PairNameType( fieldName, field.typeName() );
}
if ( !p.geometryAttribute().isEmpty() )
{
QString fieldName( fieldNamePrefix + QgsSQLStatement::quotedIdentifierIfNeeded( p.geometryAttribute() ) );
fieldList << QgsSQLComposerDialog::PairNameType( fieldName, QStringLiteral( "geometry" ) );
}
fieldList << QgsSQLComposerDialog::PairNameType( fieldNamePrefix + "*", QString() );

d->addColumnNames( fieldList, QgsSQLStatement::quotedIdentifierIfNeeded( displayedTypeName ) );
auto d = QgsWfsSubsetStringEditor::create( nullptr, &p, this );

d->setSql( sql );
d->setSubsetString( sql );

mSQLIndex = index;
mSQLComposerDialog = d;
Expand Down Expand Up @@ -803,7 +640,7 @@ void QgsWFSSourceSelect::updateSql()
const QString typeName = mSQLIndex.sibling( mSQLIndex.row(), MODEL_IDX_NAME ).data().toString();
QModelIndex filterIndex = mSQLIndex.sibling( mSQLIndex.row(), MODEL_IDX_SQL );

QString sql = mSQLComposerDialog->sql();
QString sql = mSQLComposerDialog->subsetString();
mSQLComposerDialog = nullptr;

QString displayedTypeName( typeName );
Expand Down
36 changes: 2 additions & 34 deletions src/providers/wfs/qgswfssourceselect.h
Expand Up @@ -25,14 +25,14 @@
#include "qgsoapifcollection.h"
#include "qgsproviderregistry.h"
#include "qgsabstractdatasourcewidget.h"
#include "qgssqlcomposerdialog.h"

#include <QItemDelegate>
#include <QStandardItemModel>
#include <QSortFilterProxyModel>

class QgsProjectionSelectionDialog;
class QgsWfsCapabilities;
class QgsSubsetStringEditorInterface;

class QgsWFSItemDelegate : public QItemDelegate
{
Expand All @@ -45,21 +45,6 @@ class QgsWFSItemDelegate : public QItemDelegate

};

class QgsWFSValidatorCallback: public QObject, public QgsSQLComposerDialog::SQLValidatorCallback
{
Q_OBJECT

public:
QgsWFSValidatorCallback( QObject *parent,
const QgsWFSDataSourceURI &uri, const QString &allSql,
const QgsWfsCapabilities::Capabilities &caps );
bool isValid( const QString &sql, QString &errorReason, QString &warningMsg ) override;
private:
QgsWFSDataSourceURI mURI;
QString mAllSql;
const QgsWfsCapabilities::Capabilities &mCaps;
};

class QgsWFSSourceSelect: public QgsAbstractDataSourceWidget, private Ui::QgsWFSSourceSelectBase
{
Q_OBJECT
Expand Down Expand Up @@ -91,7 +76,7 @@ class QgsWFSSourceSelect: public QgsAbstractDataSourceWidget, private Ui::QgsWFS
QPushButton *mBuildQueryButton = nullptr;
QgsWfsCapabilities::Capabilities mCaps;
QModelIndex mSQLIndex;
QgsSQLComposerDialog *mSQLComposerDialog = nullptr;
QgsSubsetStringEditorInterface *mSQLComposerDialog = nullptr;
QString mVersion;

/**
Expand Down Expand Up @@ -139,21 +124,4 @@ class QgsWFSSourceSelect: public QgsAbstractDataSourceWidget, private Ui::QgsWFS
bool isOapif() const { return mVersion == QLatin1String( "OGC_API_FEATURES" ); }
};


class QgsWFSTableSelectedCallback: public QObject, public QgsSQLComposerDialog::TableSelectedCallback
{
Q_OBJECT

public:
QgsWFSTableSelectedCallback( QgsSQLComposerDialog *dialog,
const QgsWFSDataSourceURI &uri,
const QgsWfsCapabilities::Capabilities &caps );
void tableSelected( const QString &name ) override;

private:
QgsSQLComposerDialog *mDialog = nullptr;
QgsWFSDataSourceURI mURI;
const QgsWfsCapabilities::Capabilities &mCaps;
};

#endif

0 comments on commit 4317d76

Please sign in to comment.