[afs][needs-docs] Allow users to set a specific referer for AFS connections, for

use with ArcGIS feature server requests

Some servers are locked down to only allow requests with a specific
referer URL - this allows us to open them in QGIS (but it requires
users to manually determine the correct referer string and populate
this setting for the connection -- we cannot do this for them!)
This commit is contained in:
Nyall Dawson 2019-01-24 10:07:37 +10:00
parent b0b196a97c
commit 996f48670d
14 changed files with 287 additions and 211 deletions

View File

@ -36,6 +36,7 @@ information for an HTTP Server for WMS, etc.
{ {
FlagShowTestConnection, FlagShowTestConnection,
FlagHideAuthenticationGroup, FlagHideAuthenticationGroup,
FlagShowHttpSettings,
}; };
typedef QFlags<QgsNewHttpConnection::Flag> Flags; typedef QFlags<QgsNewHttpConnection::Flag> Flags;

View File

@ -65,6 +65,13 @@ QgsOwsConnection::QgsOwsConnection( const QString &service, const QString &connN
} }
mConnectionInfo.append( ",authcfg=" + authcfg ); mConnectionInfo.append( ",authcfg=" + authcfg );
const QString referer = settings.value( key + "/referer" ).toString();
if ( !referer.isEmpty() )
{
mUri.setParam( QStringLiteral( "referer" ), referer );
mConnectionInfo.append( ",referer=" + referer );
}
if ( mService.compare( QLatin1String( "WMS" ), Qt::CaseInsensitive ) == 0 if ( mService.compare( QLatin1String( "WMS" ), Qt::CaseInsensitive ) == 0
|| mService.compare( QLatin1String( "WCS" ), Qt::CaseInsensitive ) == 0 ) || mService.compare( QLatin1String( "WCS" ), Qt::CaseInsensitive ) == 0 )
{ {

View File

@ -34,6 +34,9 @@ QgsNewHttpConnection::QgsNewHttpConnection( QWidget *parent, ConnectionTypes typ
{ {
setupUi( this ); setupUi( this );
if ( !( flags & FlagShowHttpSettings ) )
mHttpGroupBox->hide();
QgsGui::enableAutoGeometryRestore( this ); QgsGui::enableAutoGeometryRestore( this );
connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsNewHttpConnection::showHelp ); connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsNewHttpConnection::showHelp );
@ -88,6 +91,7 @@ QgsNewHttpConnection::QgsNewHttpConnection( QWidget *parent, ConnectionTypes typ
QString credentialsKey = "qgis/" + mCredentialsBaseKey + '/' + connectionName; QString credentialsKey = "qgis/" + mCredentialsBaseKey + '/' + connectionName;
txtName->setText( connectionName ); txtName->setText( connectionName );
txtUrl->setText( settings.value( key + "/url" ).toString() ); txtUrl->setText( settings.value( key + "/url" ).toString() );
mRefererLineEdit->setText( settings.value( key + "/referer" ).toString() );
updateServiceSpecificSettings(); updateServiceSpecificSettings();
@ -444,6 +448,9 @@ void QgsNewHttpConnection::accept()
settings.setValue( credentialsKey + "/authcfg", mAuthSettings->configId() ); settings.setValue( credentialsKey + "/authcfg", mAuthSettings->configId() );
if ( mHttpGroupBox->isVisible() )
settings.setValue( key + "/referer", mRefererLineEdit->text() );
settings.setValue( mBaseKey + "/selected", txtName->text() ); settings.setValue( mBaseKey + "/selected", txtName->text() );
QDialog::accept(); QDialog::accept();

View File

@ -57,6 +57,7 @@ class GUI_EXPORT QgsNewHttpConnection : public QDialog, private Ui::QgsNewHttpCo
{ {
FlagShowTestConnection = 1 << 1, //!< Display the 'test connection' button FlagShowTestConnection = 1 << 1, //!< Display the 'test connection' button
FlagHideAuthenticationGroup = 1 << 2, //!< Hide the Authentication group FlagHideAuthenticationGroup = 1 << 2, //!< Hide the Authentication group
FlagShowHttpSettings = 1 << 3, //!< Display the 'http' group
}; };
Q_DECLARE_FLAGS( Flags, Flag ) Q_DECLARE_FLAGS( Flags, Flag )

View File

@ -75,7 +75,7 @@ void QgsAfsRootItem::onConnectionsChanged()
void QgsAfsRootItem::newConnection() void QgsAfsRootItem::newConnection()
{ {
QgsNewHttpConnection nc( nullptr, QgsNewHttpConnection::ConnectionOther, QStringLiteral( "qgis/connections-arcgisfeatureserver/" ) ); QgsNewHttpConnection nc( nullptr, QgsNewHttpConnection::ConnectionOther, QStringLiteral( "qgis/connections-arcgisfeatureserver/" ), QString(), QgsNewHttpConnection::FlagShowHttpSettings );
nc.setWindowTitle( tr( "Create a New ArcGIS Feature Server Connection" ) ); nc.setWindowTitle( tr( "Create a New ArcGIS Feature Server Connection" ) );
if ( nc.exec() ) if ( nc.exec() )
@ -87,31 +87,31 @@ void QgsAfsRootItem::newConnection()
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
void addFolderItems( QVector< QgsDataItem * > &items, const QVariantMap &serviceData, const QString &baseUrl, const QString &authcfg, QgsDataItem *parent ) void addFolderItems( QVector< QgsDataItem * > &items, const QVariantMap &serviceData, const QString &baseUrl, const QString &authcfg, const QgsStringMap &headers, QgsDataItem *parent )
{ {
QgsArcGisRestUtils::visitFolderItems( [parent, &baseUrl, &items, authcfg]( const QString & name, const QString & url ) QgsArcGisRestUtils::visitFolderItems( [parent, &baseUrl, &items, headers, authcfg]( const QString & name, const QString & url )
{ {
std::unique_ptr< QgsAfsFolderItem > folderItem = qgis::make_unique< QgsAfsFolderItem >( parent, name, url, baseUrl, authcfg ); std::unique_ptr< QgsAfsFolderItem > folderItem = qgis::make_unique< QgsAfsFolderItem >( parent, name, url, baseUrl, authcfg, headers );
items.append( folderItem.release() ); items.append( folderItem.release() );
}, serviceData, baseUrl ); }, serviceData, baseUrl );
} }
void addServiceItems( QVector< QgsDataItem * > &items, const QVariantMap &serviceData, const QString &baseUrl, const QString &authcfg, QgsDataItem *parent ) void addServiceItems( QVector< QgsDataItem * > &items, const QVariantMap &serviceData, const QString &baseUrl, const QString &authcfg, const QgsStringMap &headers, QgsDataItem *parent )
{ {
QgsArcGisRestUtils::visitServiceItems( QgsArcGisRestUtils::visitServiceItems(
[&items, parent, authcfg]( const QString & name, const QString & url ) [&items, parent, authcfg, headers]( const QString & name, const QString & url )
{ {
std::unique_ptr< QgsAfsServiceItem > serviceItem = qgis::make_unique< QgsAfsServiceItem >( parent, name, url, url, authcfg ); std::unique_ptr< QgsAfsServiceItem > serviceItem = qgis::make_unique< QgsAfsServiceItem >( parent, name, url, url, authcfg, headers );
items.append( serviceItem.release() ); items.append( serviceItem.release() );
}, serviceData, baseUrl ); }, serviceData, baseUrl );
} }
void addLayerItems( QVector< QgsDataItem * > &items, const QVariantMap &serviceData, const QString &parentUrl, const QString &authcfg, QgsDataItem *parent ) void addLayerItems( QVector< QgsDataItem * > &items, const QVariantMap &serviceData, const QString &parentUrl, const QString &authcfg, const QgsStringMap &headers, QgsDataItem *parent )
{ {
QMap< QString, QgsDataItem * > layerItems; QMap< QString, QgsDataItem * > layerItems;
QMap< QString, QString > parents; QMap< QString, QString > parents;
QgsArcGisRestUtils::addLayerItems( [parent, &layerItems, &parents, authcfg]( const QString & parentLayerId, const QString & id, const QString & name, const QString & description, const QString & url, bool isParent, const QString & authid ) QgsArcGisRestUtils::addLayerItems( [parent, &layerItems, &parents, authcfg, headers]( const QString & parentLayerId, const QString & id, const QString & name, const QString & description, const QString & url, bool isParent, const QString & authid )
{ {
Q_UNUSED( description ); Q_UNUSED( description );
@ -120,12 +120,12 @@ void addLayerItems( QVector< QgsDataItem * > &items, const QVariantMap &serviceD
if ( isParent ) if ( isParent )
{ {
std::unique_ptr< QgsAfsParentLayerItem > layerItem = qgis::make_unique< QgsAfsParentLayerItem >( parent, name, url, authcfg ); std::unique_ptr< QgsAfsParentLayerItem > layerItem = qgis::make_unique< QgsAfsParentLayerItem >( parent, name, url, authcfg, headers );
layerItems.insert( id, layerItem.release() ); layerItems.insert( id, layerItem.release() );
} }
else else
{ {
std::unique_ptr< QgsAfsLayerItem > layerItem = qgis::make_unique< QgsAfsLayerItem >( parent, name, url, name, authid, authcfg ); std::unique_ptr< QgsAfsLayerItem > layerItem = qgis::make_unique< QgsAfsLayerItem >( parent, name, url, name, authid, authcfg, headers );
layerItems.insert( id, layerItem.release() ); layerItems.insert( id, layerItem.release() );
} }
@ -158,10 +158,14 @@ QVector<QgsDataItem *> QgsAfsConnectionItem::createChildren()
const QgsOwsConnection connection( QStringLiteral( "ARCGISFEATURESERVER" ), mConnName ); const QgsOwsConnection connection( QStringLiteral( "ARCGISFEATURESERVER" ), mConnName );
const QString url = connection.uri().param( QStringLiteral( "url" ) ); const QString url = connection.uri().param( QStringLiteral( "url" ) );
const QString authcfg = connection.uri().param( QStringLiteral( "authcfg" ) ); const QString authcfg = connection.uri().param( QStringLiteral( "authcfg" ) );
const QString referer = connection.uri().param( QStringLiteral( "referer" ) );
QgsStringMap headers;
if ( ! referer.isEmpty() )
headers[ QStringLiteral( "Referer" )] = referer;
QVector<QgsDataItem *> items; QVector<QgsDataItem *> items;
QString errorTitle, errorMessage; QString errorTitle, errorMessage;
const QVariantMap serviceData = QgsArcGisRestUtils::getServiceInfo( url, authcfg, errorTitle, errorMessage ); const QVariantMap serviceData = QgsArcGisRestUtils::getServiceInfo( url, authcfg, errorTitle, errorMessage, headers );
if ( serviceData.isEmpty() ) if ( serviceData.isEmpty() )
{ {
if ( !errorMessage.isEmpty() ) if ( !errorMessage.isEmpty() )
@ -174,9 +178,9 @@ QVector<QgsDataItem *> QgsAfsConnectionItem::createChildren()
return items; return items;
} }
addFolderItems( items, serviceData, url, authcfg, this ); addFolderItems( items, serviceData, url, authcfg, headers, this );
addServiceItems( items, serviceData, url, authcfg, this ); addServiceItems( items, serviceData, url, authcfg, headers, this );
addLayerItems( items, serviceData, url, authcfg, this ); addLayerItems( items, serviceData, url, authcfg, headers, this );
return items; return items;
} }
@ -219,7 +223,7 @@ QList<QAction *> QgsAfsConnectionItem::actions( QWidget *parent )
void QgsAfsConnectionItem::editConnection() void QgsAfsConnectionItem::editConnection()
{ {
QgsNewHttpConnection nc( nullptr, QgsNewHttpConnection::ConnectionOther, QStringLiteral( "qgis/connections-arcgisfeatureserver/" ), mName ); QgsNewHttpConnection nc( nullptr, QgsNewHttpConnection::ConnectionOther, QStringLiteral( "qgis/connections-arcgisfeatureserver/" ), mName, QgsNewHttpConnection::FlagShowHttpSettings );
nc.setWindowTitle( tr( "Modify ArcGIS Feature Server Connection" ) ); nc.setWindowTitle( tr( "Modify ArcGIS Feature Server Connection" ) );
if ( nc.exec() ) if ( nc.exec() )
@ -255,10 +259,11 @@ void QgsAfsConnectionItem::refreshConnection()
#endif #endif
QgsAfsFolderItem::QgsAfsFolderItem( QgsDataItem *parent, const QString &name, const QString &path, const QString &baseUrl, const QString &authcfg ) QgsAfsFolderItem::QgsAfsFolderItem( QgsDataItem *parent, const QString &name, const QString &path, const QString &baseUrl, const QString &authcfg, const QgsStringMap &headers )
: QgsDataCollectionItem( parent, name, path ) : QgsDataCollectionItem( parent, name, path )
, mBaseUrl( baseUrl ) , mBaseUrl( baseUrl )
, mAuthCfg( authcfg ) , mAuthCfg( authcfg )
, mHeaders( headers )
{ {
mIconName = QStringLiteral( "mIconDbSchema.svg" ); mIconName = QStringLiteral( "mIconDbSchema.svg" );
mCapabilities |= Collapse; mCapabilities |= Collapse;
@ -272,7 +277,7 @@ QVector<QgsDataItem *> QgsAfsFolderItem::createChildren()
QVector<QgsDataItem *> items; QVector<QgsDataItem *> items;
QString errorTitle, errorMessage; QString errorTitle, errorMessage;
const QVariantMap serviceData = QgsArcGisRestUtils::getServiceInfo( url, mAuthCfg, errorTitle, errorMessage ); const QVariantMap serviceData = QgsArcGisRestUtils::getServiceInfo( url, mAuthCfg, errorTitle, errorMessage, mHeaders );
if ( serviceData.isEmpty() ) if ( serviceData.isEmpty() )
{ {
if ( !errorMessage.isEmpty() ) if ( !errorMessage.isEmpty() )
@ -285,9 +290,9 @@ QVector<QgsDataItem *> QgsAfsFolderItem::createChildren()
return items; return items;
} }
addFolderItems( items, serviceData, mBaseUrl, mAuthCfg, this ); addFolderItems( items, serviceData, mBaseUrl, mAuthCfg, mHeaders, this );
addServiceItems( items, serviceData, mBaseUrl, mAuthCfg, this ); addServiceItems( items, serviceData, mBaseUrl, mAuthCfg, mHeaders, this );
addLayerItems( items, serviceData, mPath, mAuthCfg, this ); addLayerItems( items, serviceData, mPath, mAuthCfg, mHeaders, this );
return items; return items;
} }
@ -297,10 +302,11 @@ bool QgsAfsFolderItem::equal( const QgsDataItem *other )
return ( type() == other->type() && o && mPath == o->mPath && mName == o->mName ); return ( type() == other->type() && o && mPath == o->mPath && mName == o->mName );
} }
QgsAfsServiceItem::QgsAfsServiceItem( QgsDataItem *parent, const QString &name, const QString &path, const QString &baseUrl, const QString &authcfg ) QgsAfsServiceItem::QgsAfsServiceItem( QgsDataItem *parent, const QString &name, const QString &path, const QString &baseUrl, const QString &authcfg, const QgsStringMap &headers )
: QgsDataCollectionItem( parent, name, path ) : QgsDataCollectionItem( parent, name, path )
, mBaseUrl( baseUrl ) , mBaseUrl( baseUrl )
, mAuthCfg( authcfg ) , mAuthCfg( authcfg )
, mHeaders( headers )
{ {
mIconName = QStringLiteral( "mIconDbSchema.svg" ); mIconName = QStringLiteral( "mIconDbSchema.svg" );
mCapabilities |= Collapse; mCapabilities |= Collapse;
@ -313,7 +319,7 @@ QVector<QgsDataItem *> QgsAfsServiceItem::createChildren()
QVector<QgsDataItem *> items; QVector<QgsDataItem *> items;
QString errorTitle, errorMessage; QString errorTitle, errorMessage;
const QVariantMap serviceData = QgsArcGisRestUtils::getServiceInfo( url, mAuthCfg, errorTitle, errorMessage ); const QVariantMap serviceData = QgsArcGisRestUtils::getServiceInfo( url, mAuthCfg, errorTitle, errorMessage, mHeaders );
if ( serviceData.isEmpty() ) if ( serviceData.isEmpty() )
{ {
if ( !errorMessage.isEmpty() ) if ( !errorMessage.isEmpty() )
@ -326,9 +332,9 @@ QVector<QgsDataItem *> QgsAfsServiceItem::createChildren()
return items; return items;
} }
addFolderItems( items, serviceData, mBaseUrl, mAuthCfg, this ); addFolderItems( items, serviceData, mBaseUrl, mAuthCfg, mHeaders, this );
addServiceItems( items, serviceData, mBaseUrl, mAuthCfg, this ); addServiceItems( items, serviceData, mBaseUrl, mAuthCfg, mHeaders, this );
addLayerItems( items, serviceData, mPath, mAuthCfg, this ); addLayerItems( items, serviceData, mPath, mAuthCfg, mHeaders, this );
return items; return items;
} }
@ -338,20 +344,23 @@ bool QgsAfsServiceItem::equal( const QgsDataItem *other )
return ( type() == other->type() && o && mPath == o->mPath && mName == o->mName ); return ( type() == other->type() && o && mPath == o->mPath && mName == o->mName );
} }
QgsAfsLayerItem::QgsAfsLayerItem( QgsDataItem *parent, const QString &, const QString &url, const QString &title, const QString &authid, const QString &authcfg ) QgsAfsLayerItem::QgsAfsLayerItem( QgsDataItem *parent, const QString &, const QString &url, const QString &title, const QString &authid, const QString &authcfg, const QgsStringMap &headers )
: QgsLayerItem( parent, title, url, QString(), QgsLayerItem::Vector, QStringLiteral( "arcgisfeatureserver" ) ) : QgsLayerItem( parent, title, url, QString(), QgsLayerItem::Vector, QStringLiteral( "arcgisfeatureserver" ) )
{ {
mUri = QStringLiteral( "crs='%1' url='%2'" ).arg( authid, url ); mUri = QStringLiteral( "crs='%1' url='%2'" ).arg( authid, url );
if ( !authcfg.isEmpty() ) if ( !authcfg.isEmpty() )
mUri += QStringLiteral( " authcfg='%1'" ).arg( authcfg ); mUri += QStringLiteral( " authcfg='%1'" ).arg( authcfg );
if ( !headers.value( QStringLiteral( "Referer" ) ).isEmpty() )
mUri += QStringLiteral( " referer='%1'" ).arg( headers.value( QStringLiteral( "Referer" ) ) );
setState( Populated ); setState( Populated );
mIconName = QStringLiteral( "mIconAfs.svg" ); mIconName = QStringLiteral( "mIconAfs.svg" );
setToolTip( url ); setToolTip( url );
} }
QgsAfsParentLayerItem::QgsAfsParentLayerItem( QgsDataItem *parent, const QString &name, const QString &path, const QString &authcfg ) QgsAfsParentLayerItem::QgsAfsParentLayerItem( QgsDataItem *parent, const QString &name, const QString &path, const QString &authcfg, const QgsStringMap &headers )
: QgsDataItem( QgsDataItem::Collection, parent, name, path ) : QgsDataItem( QgsDataItem::Collection, parent, name, path )
, mAuthCfg( authcfg ) , mAuthCfg( authcfg )
, mHeaders( headers )
{ {
mCapabilities |= Fast; mCapabilities |= Fast;
mIconName = QStringLiteral( "mIconDbSchema.svg" ); mIconName = QStringLiteral( "mIconDbSchema.svg" );

View File

@ -73,7 +73,7 @@ class QgsAfsFolderItem : public QgsDataCollectionItem
{ {
Q_OBJECT Q_OBJECT
public: public:
QgsAfsFolderItem( QgsDataItem *parent, const QString &name, const QString &path, const QString &baseUrl, const QString &authcfg ); QgsAfsFolderItem( QgsDataItem *parent, const QString &name, const QString &path, const QString &baseUrl, const QString &authcfg, const QgsStringMap &headers );
QVector<QgsDataItem *> createChildren() override; QVector<QgsDataItem *> createChildren() override;
bool equal( const QgsDataItem *other ) override; bool equal( const QgsDataItem *other ) override;
@ -81,13 +81,14 @@ class QgsAfsFolderItem : public QgsDataCollectionItem
QString mFolder; QString mFolder;
QString mBaseUrl; QString mBaseUrl;
QString mAuthCfg; QString mAuthCfg;
QgsStringMap mHeaders;
}; };
class QgsAfsServiceItem : public QgsDataCollectionItem class QgsAfsServiceItem : public QgsDataCollectionItem
{ {
Q_OBJECT Q_OBJECT
public: public:
QgsAfsServiceItem( QgsDataItem *parent, const QString &name, const QString &path, const QString &baseUrl, const QString &authcfg ); QgsAfsServiceItem( QgsDataItem *parent, const QString &name, const QString &path, const QString &baseUrl, const QString &authcfg, const QgsStringMap &headers );
QVector<QgsDataItem *> createChildren() override; QVector<QgsDataItem *> createChildren() override;
bool equal( const QgsDataItem *other ) override; bool equal( const QgsDataItem *other ) override;
@ -95,6 +96,7 @@ class QgsAfsServiceItem : public QgsDataCollectionItem
QString mFolder; QString mFolder;
QString mBaseUrl; QString mBaseUrl;
QString mAuthCfg; QString mAuthCfg;
QgsStringMap mHeaders;
}; };
class QgsAfsParentLayerItem : public QgsDataItem class QgsAfsParentLayerItem : public QgsDataItem
@ -102,12 +104,13 @@ class QgsAfsParentLayerItem : public QgsDataItem
Q_OBJECT Q_OBJECT
public: public:
QgsAfsParentLayerItem( QgsDataItem *parent, const QString &name, const QString &path, const QString &authcfg ); QgsAfsParentLayerItem( QgsDataItem *parent, const QString &name, const QString &path, const QString &authcfg, const QgsStringMap &headers );
bool equal( const QgsDataItem *other ) override; bool equal( const QgsDataItem *other ) override;
private: private:
QString mAuthCfg; QString mAuthCfg;
QgsStringMap mHeaders;
}; };
@ -117,7 +120,7 @@ class QgsAfsLayerItem : public QgsLayerItem
public: public:
QgsAfsLayerItem( QgsDataItem *parent, const QString &name, const QString &url, const QString &title, const QString &authid, const QString &authcfg ); QgsAfsLayerItem( QgsDataItem *parent, const QString &name, const QString &url, const QString &title, const QString &authid, const QString &authcfg, const QgsStringMap &headers );
}; };

View File

@ -54,8 +54,13 @@ QgsAfsProvider::QgsAfsProvider( const QString &uri, const ProviderOptions &optio
// Get layer info // Get layer info
QString errorTitle, errorMessage; QString errorTitle, errorMessage;
const QString referer = mSharedData->mDataSource.param( QStringLiteral( "referer" ) );
if ( !referer.isEmpty() )
mRequestHeaders[ QStringLiteral( "Referer" )] = referer;
const QVariantMap layerData = QgsArcGisRestUtils::getLayerInfo( mSharedData->mDataSource.param( QStringLiteral( "url" ) ), const QVariantMap layerData = QgsArcGisRestUtils::getLayerInfo( mSharedData->mDataSource.param( QStringLiteral( "url" ) ),
authcfg, errorTitle, errorMessage ); authcfg, errorTitle, errorMessage, mRequestHeaders );
if ( layerData.isEmpty() ) if ( layerData.isEmpty() )
{ {
pushError( errorTitle + ": " + errorMessage ); pushError( errorTitle + ": " + errorMessage );
@ -170,7 +175,7 @@ QgsAfsProvider::QgsAfsProvider( const QString &uri, const ProviderOptions &optio
// and we need to store these to iterate through the features. This query // and we need to store these to iterate through the features. This query
// also returns the name of the ObjectID field. // also returns the name of the ObjectID field.
QVariantMap objectIdData = QgsArcGisRestUtils::getObjectIds( mSharedData->mDataSource.param( QStringLiteral( "url" ) ), authcfg, QVariantMap objectIdData = QgsArcGisRestUtils::getObjectIds( mSharedData->mDataSource.param( QStringLiteral( "url" ) ), authcfg,
objectIdFieldName, errorTitle, errorMessage, limitBbox ? mSharedData->mExtent : QgsRectangle() ); objectIdFieldName, errorTitle, errorMessage, mRequestHeaders, limitBbox ? mSharedData->mExtent : QgsRectangle() );
if ( objectIdData.isEmpty() ) if ( objectIdData.isEmpty() )
{ {
appendError( QgsErrorMessage( tr( "getObjectIds failed: %1 - %2" ).arg( errorTitle, errorMessage ), QStringLiteral( "AFSProvider" ) ) ); appendError( QgsErrorMessage( tr( "getObjectIds failed: %1 - %2" ).arg( errorTitle, errorMessage ), QStringLiteral( "AFSProvider" ) ) );

View File

@ -82,6 +82,7 @@ class QgsAfsProvider : public QgsVectorDataProvider
QgsLayerMetadata mLayerMetadata; QgsLayerMetadata mLayerMetadata;
QVariantMap mRendererDataMap; QVariantMap mRendererDataMap;
QVariantList mLabelingDataList; QVariantList mLabelingDataList;
QgsStringMap mRequestHeaders;
}; };
#endif // QGSAFSPROVIDER_H #endif // QGSAFSPROVIDER_H

View File

@ -70,10 +70,15 @@ bool QgsAfsSharedData::getFeature( QgsFeatureId id, QgsFeature &f, const QgsRect
QString errorTitle, errorMessage; QString errorTitle, errorMessage;
const QString authcfg = mDataSource.authConfigId(); const QString authcfg = mDataSource.authConfigId();
QgsStringMap headers;
const QString referer = mDataSource.param( QStringLiteral( "referer" ) );
if ( !referer.isEmpty() )
headers[ QStringLiteral( "Referer" )] = referer;
const QVariantMap queryData = QgsArcGisRestUtils::getObjects( const QVariantMap queryData = QgsArcGisRestUtils::getObjects(
mDataSource.param( QStringLiteral( "url" ) ), authcfg, objectIds, mDataSource.param( QStringLiteral( "crs" ) ), true, mDataSource.param( QStringLiteral( "url" ) ), authcfg, objectIds, mDataSource.param( QStringLiteral( "crs" ) ), true,
fetchAttribNames, QgsWkbTypes::hasM( mGeometryType ), QgsWkbTypes::hasZ( mGeometryType ), fetchAttribNames, QgsWkbTypes::hasM( mGeometryType ), QgsWkbTypes::hasZ( mGeometryType ),
filterRect, errorTitle, errorMessage, feedback ); filterRect, errorTitle, errorMessage, headers, feedback );
if ( queryData.isEmpty() ) if ( queryData.isEmpty() )
{ {
@ -159,9 +164,13 @@ QgsFeatureIds QgsAfsSharedData::getFeatureIdsInExtent( const QgsRectangle &exten
QString errorText; QString errorText;
const QString authcfg = mDataSource.authConfigId(); const QString authcfg = mDataSource.authConfigId();
QgsStringMap headers;
const QString referer = mDataSource.param( QStringLiteral( "referer" ) );
if ( !referer.isEmpty() )
headers[ QStringLiteral( "Referer" )] = referer;
const QList<quint32> featuresInRect = QgsArcGisRestUtils::getObjectIdsByExtent( mDataSource.param( QStringLiteral( "url" ) ), const QList<quint32> featuresInRect = QgsArcGisRestUtils::getObjectIdsByExtent( mDataSource.param( QStringLiteral( "url" ) ),
mObjectIdFieldName, mObjectIdFieldName,
extent, errorTitle, errorText, authcfg, feedback ); extent, errorTitle, errorText, authcfg, headers, feedback );
QgsFeatureIds ids; QgsFeatureIds ids;
for ( quint32 id : featuresInRect ) for ( quint32 id : featuresInRect )

View File

@ -40,11 +40,15 @@ bool QgsAfsSourceSelect::connectToService( const QgsOwsConnection &connection )
const QString authcfg = connection.uri().param( QStringLiteral( "authcfg" ) ); const QString authcfg = connection.uri().param( QStringLiteral( "authcfg" ) );
const QString baseUrl = connection.uri().param( QStringLiteral( "url" ) ); const QString baseUrl = connection.uri().param( QStringLiteral( "url" ) );
const QString referer = connection.uri().param( QStringLiteral( "referer" ) );
QgsStringMap headers;
if ( ! referer.isEmpty() )
headers[ QStringLiteral( "Referer" )] = referer;
std::function< bool( const QString &, QStandardItem * )> visitItemsRecursive; std::function< bool( const QString &, QStandardItem * )> visitItemsRecursive;
visitItemsRecursive = [this, &visitItemsRecursive, baseUrl, authcfg, &errorTitle, &errorMessage]( const QString & baseItemUrl, QStandardItem * parentItem ) -> bool visitItemsRecursive = [this, &visitItemsRecursive, baseUrl, authcfg, headers, &errorTitle, &errorMessage]( const QString & baseItemUrl, QStandardItem * parentItem ) -> bool
{ {
const QVariantMap serviceInfoMap = QgsArcGisRestUtils::getServiceInfo( baseItemUrl, authcfg, errorTitle, errorMessage ); const QVariantMap serviceInfoMap = QgsArcGisRestUtils::getServiceInfo( baseItemUrl, authcfg, errorTitle, errorMessage, headers );
if ( serviceInfoMap.isEmpty() ) if ( serviceInfoMap.isEmpty() )
{ {

View File

@ -367,23 +367,23 @@ QgsCoordinateReferenceSystem QgsArcGisRestUtils::parseSpatialReference( const QV
} }
QVariantMap QgsArcGisRestUtils::getServiceInfo( const QString &baseurl, const QString &authcfg, QString &errorTitle, QString &errorText ) QVariantMap QgsArcGisRestUtils::getServiceInfo( const QString &baseurl, const QString &authcfg, QString &errorTitle, QString &errorText, const QgsStringMap &requestHeaders )
{ {
// http://sampleserver5.arcgisonline.com/arcgis/rest/services/Energy/Geology/FeatureServer?f=json // http://sampleserver5.arcgisonline.com/arcgis/rest/services/Energy/Geology/FeatureServer?f=json
QUrl queryUrl( baseurl ); QUrl queryUrl( baseurl );
queryUrl.addQueryItem( QStringLiteral( "f" ), QStringLiteral( "json" ) ); queryUrl.addQueryItem( QStringLiteral( "f" ), QStringLiteral( "json" ) );
return queryServiceJSON( queryUrl, authcfg, errorTitle, errorText ); return queryServiceJSON( queryUrl, authcfg, errorTitle, errorText, requestHeaders );
} }
QVariantMap QgsArcGisRestUtils::getLayerInfo( const QString &layerurl, const QString &authcfg, QString &errorTitle, QString &errorText ) QVariantMap QgsArcGisRestUtils::getLayerInfo( const QString &layerurl, const QString &authcfg, QString &errorTitle, QString &errorText, const QgsStringMap &requestHeaders )
{ {
// http://sampleserver5.arcgisonline.com/arcgis/rest/services/Energy/Geology/FeatureServer/1?f=json // http://sampleserver5.arcgisonline.com/arcgis/rest/services/Energy/Geology/FeatureServer/1?f=json
QUrl queryUrl( layerurl ); QUrl queryUrl( layerurl );
queryUrl.addQueryItem( QStringLiteral( "f" ), QStringLiteral( "json" ) ); queryUrl.addQueryItem( QStringLiteral( "f" ), QStringLiteral( "json" ) );
return queryServiceJSON( queryUrl, authcfg, errorTitle, errorText ); return queryServiceJSON( queryUrl, authcfg, errorTitle, errorText, requestHeaders );
} }
QVariantMap QgsArcGisRestUtils::getObjectIds( const QString &layerurl, const QString &authcfg, const QString &objectIdFieldName, QString &errorTitle, QString &errorText, const QgsRectangle &bbox ) QVariantMap QgsArcGisRestUtils::getObjectIds( const QString &layerurl, const QString &authcfg, const QString &objectIdFieldName, QString &errorTitle, QString &errorText, const QgsStringMap &requestHeaders, const QgsRectangle &bbox )
{ {
// http://sampleserver5.arcgisonline.com/arcgis/rest/services/Energy/Geology/FeatureServer/1/query?where=objectid%3Dobjectid&returnIdsOnly=true&f=json // http://sampleserver5.arcgisonline.com/arcgis/rest/services/Energy/Geology/FeatureServer/1/query?where=objectid%3Dobjectid&returnIdsOnly=true&f=json
QUrl queryUrl( layerurl + "/query" ); QUrl queryUrl( layerurl + "/query" );
@ -398,14 +398,14 @@ QVariantMap QgsArcGisRestUtils::getObjectIds( const QString &layerurl, const QSt
queryUrl.addQueryItem( QStringLiteral( "geometryType" ), QStringLiteral( "esriGeometryEnvelope" ) ); queryUrl.addQueryItem( QStringLiteral( "geometryType" ), QStringLiteral( "esriGeometryEnvelope" ) );
queryUrl.addQueryItem( QStringLiteral( "spatialRel" ), QStringLiteral( "esriSpatialRelEnvelopeIntersects" ) ); queryUrl.addQueryItem( QStringLiteral( "spatialRel" ), QStringLiteral( "esriSpatialRelEnvelopeIntersects" ) );
} }
return queryServiceJSON( queryUrl, authcfg, errorTitle, errorText ); return queryServiceJSON( queryUrl, authcfg, errorTitle, errorText, requestHeaders );
} }
QVariantMap QgsArcGisRestUtils::getObjects( const QString &layerurl, const QString &authcfg, const QList<quint32> &objectIds, const QString &crs, QVariantMap QgsArcGisRestUtils::getObjects( const QString &layerurl, const QString &authcfg, const QList<quint32> &objectIds, const QString &crs,
bool fetchGeometry, const QStringList &fetchAttributes, bool fetchGeometry, const QStringList &fetchAttributes,
bool fetchM, bool fetchZ, bool fetchM, bool fetchZ,
const QgsRectangle &filterRect, const QgsRectangle &filterRect,
QString &errorTitle, QString &errorText, QgsFeedback *feedback ) QString &errorTitle, QString &errorText, const QgsStringMap &requestHeaders, QgsFeedback *feedback )
{ {
QStringList ids; QStringList ids;
for ( int id : objectIds ) for ( int id : objectIds )
@ -439,10 +439,10 @@ QVariantMap QgsArcGisRestUtils::getObjects( const QString &layerurl, const QStri
queryUrl.addQueryItem( QStringLiteral( "geometryType" ), QStringLiteral( "esriGeometryEnvelope" ) ); queryUrl.addQueryItem( QStringLiteral( "geometryType" ), QStringLiteral( "esriGeometryEnvelope" ) );
queryUrl.addQueryItem( QStringLiteral( "spatialRel" ), QStringLiteral( "esriSpatialRelEnvelopeIntersects" ) ); queryUrl.addQueryItem( QStringLiteral( "spatialRel" ), QStringLiteral( "esriSpatialRelEnvelopeIntersects" ) );
} }
return queryServiceJSON( queryUrl, authcfg, errorTitle, errorText, feedback ); return queryServiceJSON( queryUrl, authcfg, errorTitle, errorText, requestHeaders, feedback );
} }
QList<quint32> QgsArcGisRestUtils::getObjectIdsByExtent( const QString &layerurl, const QString &objectIdField, const QgsRectangle &filterRect, QString &errorTitle, QString &errorText, const QString &authcfg, QgsFeedback *feedback ) QList<quint32> QgsArcGisRestUtils::getObjectIdsByExtent( const QString &layerurl, const QString &objectIdField, const QgsRectangle &filterRect, QString &errorTitle, QString &errorText, const QString &authcfg, const QgsStringMap &requestHeaders, QgsFeedback *feedback )
{ {
QUrl queryUrl( layerurl + "/query" ); QUrl queryUrl( layerurl + "/query" );
queryUrl.addQueryItem( QStringLiteral( "f" ), QStringLiteral( "json" ) ); queryUrl.addQueryItem( QStringLiteral( "f" ), QStringLiteral( "json" ) );
@ -453,7 +453,7 @@ QList<quint32> QgsArcGisRestUtils::getObjectIdsByExtent( const QString &layerurl
.arg( filterRect.xMaximum(), 0, 'f', -1 ).arg( filterRect.yMaximum(), 0, 'f', -1 ) ); .arg( filterRect.xMaximum(), 0, 'f', -1 ).arg( filterRect.yMaximum(), 0, 'f', -1 ) );
queryUrl.addQueryItem( QStringLiteral( "geometryType" ), QStringLiteral( "esriGeometryEnvelope" ) ); queryUrl.addQueryItem( QStringLiteral( "geometryType" ), QStringLiteral( "esriGeometryEnvelope" ) );
queryUrl.addQueryItem( QStringLiteral( "spatialRel" ), QStringLiteral( "esriSpatialRelEnvelopeIntersects" ) ); queryUrl.addQueryItem( QStringLiteral( "spatialRel" ), QStringLiteral( "esriSpatialRelEnvelopeIntersects" ) );
const QVariantMap objectIdData = queryServiceJSON( queryUrl, authcfg, errorTitle, errorText, feedback ); const QVariantMap objectIdData = queryServiceJSON( queryUrl, authcfg, errorTitle, errorText, requestHeaders, feedback );
if ( objectIdData.isEmpty() ) if ( objectIdData.isEmpty() )
{ {
@ -470,12 +470,16 @@ QList<quint32> QgsArcGisRestUtils::getObjectIdsByExtent( const QString &layerurl
return ids; return ids;
} }
QByteArray QgsArcGisRestUtils::queryService( const QUrl &u, const QString &authcfg, QString &errorTitle, QString &errorText, QgsFeedback *feedback ) QByteArray QgsArcGisRestUtils::queryService( const QUrl &u, const QString &authcfg, QString &errorTitle, QString &errorText, const QgsStringMap &requestHeaders, QgsFeedback *feedback )
{ {
QEventLoop loop; QEventLoop loop;
QUrl url = parseUrl( u ); QUrl url = parseUrl( u );
QNetworkRequest request( url ); QNetworkRequest request( url );
for ( auto it = requestHeaders.constBegin(); it != requestHeaders.constEnd(); ++it )
{
request.setRawHeader( it.key().toUtf8(), it.value().toUtf8() );
}
if ( !authcfg.isEmpty() ) if ( !authcfg.isEmpty() )
{ {
@ -525,9 +529,9 @@ QByteArray QgsArcGisRestUtils::queryService( const QUrl &u, const QString &authc
return result; return result;
} }
QVariantMap QgsArcGisRestUtils::queryServiceJSON( const QUrl &url, const QString &authcfg, QString &errorTitle, QString &errorText, QgsFeedback *feedback ) QVariantMap QgsArcGisRestUtils::queryServiceJSON( const QUrl &url, const QString &authcfg, QString &errorTitle, QString &errorText, const QgsStringMap &requestHeaders, QgsFeedback *feedback )
{ {
QByteArray reply = queryService( url, authcfg, errorTitle, errorText, feedback ); QByteArray reply = queryService( url, authcfg, errorTitle, errorText, requestHeaders, feedback );
if ( !errorTitle.isEmpty() ) if ( !errorTitle.isEmpty() )
{ {
return QVariantMap(); return QVariantMap();

View File

@ -41,16 +41,16 @@ class QgsArcGisRestUtils
static std::unique_ptr< QgsAbstractGeometry > parseEsriGeoJSON( const QVariantMap &geometryData, const QString &esriGeometryType, bool readM, bool readZ, QgsCoordinateReferenceSystem *crs = nullptr ); static std::unique_ptr< QgsAbstractGeometry > parseEsriGeoJSON( const QVariantMap &geometryData, const QString &esriGeometryType, bool readM, bool readZ, QgsCoordinateReferenceSystem *crs = nullptr );
static QgsCoordinateReferenceSystem parseSpatialReference( const QVariantMap &spatialReferenceMap ); static QgsCoordinateReferenceSystem parseSpatialReference( const QVariantMap &spatialReferenceMap );
static QVariantMap getServiceInfo( const QString &baseurl, const QString &authcfg, QString &errorTitle, QString &errorText ); static QVariantMap getServiceInfo( const QString &baseurl, const QString &authcfg, QString &errorTitle, QString &errorText, const QgsStringMap &requestHeaders = QgsStringMap() );
static QVariantMap getLayerInfo( const QString &layerurl, const QString &authcfg, QString &errorTitle, QString &errorText ); static QVariantMap getLayerInfo( const QString &layerurl, const QString &authcfg, QString &errorTitle, QString &errorText, const QgsStringMap &requestHeaders = QgsStringMap() );
static QVariantMap getObjectIds( const QString &layerurl, const QString &authcfg, const QString &objectIdFieldName, QString &errorTitle, QString &errorText, static QVariantMap getObjectIds( const QString &layerurl, const QString &authcfg, const QString &objectIdFieldName, QString &errorTitle, QString &errorText, const QgsStringMap &requestHeaders = QgsStringMap(),
const QgsRectangle &bbox = QgsRectangle() ); const QgsRectangle &bbox = QgsRectangle() );
static QVariantMap getObjects( const QString &layerurl, const QString &authcfg, const QList<quint32> &objectIds, const QString &crs, static QVariantMap getObjects( const QString &layerurl, const QString &authcfg, const QList<quint32> &objectIds, const QString &crs,
bool fetchGeometry, const QStringList &fetchAttributes, bool fetchM, bool fetchZ, bool fetchGeometry, const QStringList &fetchAttributes, bool fetchM, bool fetchZ,
const QgsRectangle &filterRect, QString &errorTitle, QString &errorText, QgsFeedback *feedback = nullptr ); const QgsRectangle &filterRect, QString &errorTitle, QString &errorText, const QgsStringMap &requestHeaders = QgsStringMap(), QgsFeedback *feedback = nullptr );
static QList<quint32> getObjectIdsByExtent( const QString &layerurl, const QString &objectIdField, const QgsRectangle &filterRect, QString &errorTitle, QString &errorText, const QString &authcfg, QgsFeedback *feedback = nullptr ); static QList<quint32> getObjectIdsByExtent( const QString &layerurl, const QString &objectIdField, const QgsRectangle &filterRect, QString &errorTitle, QString &errorText, const QString &authcfg, const QgsStringMap &requestHeaders = QgsStringMap(), QgsFeedback *feedback = nullptr );
static QByteArray queryService( const QUrl &url, const QString &authcfg, QString &errorTitle, QString &errorText, QgsFeedback *feedback = nullptr ); static QByteArray queryService( const QUrl &url, const QString &authcfg, QString &errorTitle, QString &errorText, const QgsStringMap &requestHeaders = QgsStringMap(), QgsFeedback *feedback = nullptr );
static QVariantMap queryServiceJSON( const QUrl &url, const QString &authcfg, QString &errorTitle, QString &errorText, QgsFeedback *feedback = nullptr ); static QVariantMap queryServiceJSON( const QUrl &url, const QString &authcfg, QString &errorTitle, QString &errorText, const QgsStringMap &requestHeaders = QgsStringMap(), QgsFeedback *feedback = nullptr );
static std::unique_ptr< QgsSymbol > parseEsriSymbolJson( const QVariantMap &symbolData ); static std::unique_ptr< QgsSymbol > parseEsriSymbolJson( const QVariantMap &symbolData );
static std::unique_ptr< QgsLineSymbol > parseEsriLineSymbolJson( const QVariantMap &symbolData ); static std::unique_ptr< QgsLineSymbol > parseEsriLineSymbolJson( const QVariantMap &symbolData );

View File

@ -208,7 +208,7 @@ void QgsArcGisServiceSourceSelect::refresh()
void QgsArcGisServiceSourceSelect::addEntryToServerList() void QgsArcGisServiceSourceSelect::addEntryToServerList()
{ {
QgsNewHttpConnection nc( nullptr, QgsNewHttpConnection::ConnectionOther, QStringLiteral( "qgis/connections-%1/" ).arg( mServiceName.toLower() ) ); QgsNewHttpConnection nc( nullptr, QgsNewHttpConnection::ConnectionOther, QStringLiteral( "qgis/connections-%1/" ).arg( mServiceName.toLower() ), QString(), QgsNewHttpConnection::FlagShowHttpSettings );
nc.setWindowTitle( tr( "Create a New %1 Connection" ).arg( mServiceName ) ); nc.setWindowTitle( tr( "Create a New %1 Connection" ).arg( mServiceName ) );
if ( nc.exec() ) if ( nc.exec() )
@ -220,7 +220,7 @@ void QgsArcGisServiceSourceSelect::addEntryToServerList()
void QgsArcGisServiceSourceSelect::modifyEntryOfServerList() void QgsArcGisServiceSourceSelect::modifyEntryOfServerList()
{ {
QgsNewHttpConnection nc( nullptr, QgsNewHttpConnection::ConnectionOther, QStringLiteral( "qgis/connections-%1/" ).arg( mServiceName.toLower() ), cmbConnections->currentText() ); QgsNewHttpConnection nc( nullptr, QgsNewHttpConnection::ConnectionOther, QStringLiteral( "qgis/connections-%1/" ).arg( mServiceName.toLower() ), cmbConnections->currentText(), QgsNewHttpConnection::FlagShowHttpSettings );
nc.setWindowTitle( tr( "Modify %1 Connection" ).arg( mServiceName ) ); nc.setWindowTitle( tr( "Modify %1 Connection" ).arg( mServiceName ) );
if ( nc.exec() ) if ( nc.exec() )

View File

@ -26,7 +26,160 @@
<string>Connection Details</string> <string>Connection Details</string>
</property> </property>
<layout class="QGridLayout"> <layout class="QGridLayout">
<item row="2" column="0" colspan="2"> <item row="0" column="0" colspan="2">
<widget class="QFrame" name="frame">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="TextLabel1_2">
<property name="text">
<string>Name</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="margin">
<number>5</number>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="txtName">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Name of the new connection</string>
</property>
<property name="frame">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="TextLabel1">
<property name="text">
<string>URL</string>
</property>
<property name="margin">
<number>5</number>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="txtUrl">
<property name="toolTip">
<string>HTTP address of the Web Map Server</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="4" column="0" colspan="2">
<widget class="QGroupBox" name="mWmsOptionsGroupBox">
<property name="title">
<string>WMS/WMTS Options</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="5" column="0" colspan="2">
<widget class="QCheckBox" name="cbxWmsInvertAxisOrientation">
<property name="text">
<string>Invert axis orientation</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QCheckBox" name="cbxIgnoreGetFeatureInfoURI">
<property name="text">
<string>Ignore GetFeatureInfo URI reported in capabilities</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QCheckBox" name="cbxIgnoreGetMapURI">
<property name="text">
<string>Ignore GetMap/GetTile URI reported in capabilities</string>
</property>
</widget>
</item>
<item row="9" column="0" colspan="2">
<widget class="QCheckBox" name="cbxSmoothPixmapTransform">
<property name="text">
<string>Smooth pixmap transform</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="txtReferer"/>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="cmbDpiMode"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="lblDpiMode">
<property name="text">
<string>DPI-&amp;Mode</string>
</property>
<property name="buddy">
<cstring>cmbDpiMode</cstring>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="lblReferer">
<property name="text">
<string>&amp;Referer</string>
</property>
<property name="buddy">
<cstring>txtReferer</cstring>
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<widget class="QCheckBox" name="cbxWmsIgnoreAxisOrientation">
<property name="text">
<string>Ignore axis orientation (WMS 1.3/WMTS)</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="6" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="0" colspan="2">
<widget class="QGroupBox" name="mWfsOptionsGroupBox"> <widget class="QGroupBox" name="mWfsOptionsGroupBox">
<property name="title"> <property name="title">
<string>WFS Options</string> <string>WFS Options</string>
@ -108,13 +261,6 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="4" column="0" colspan="2">
<widget class="QPushButton" name="mTestConnectionButton">
<property name="text">
<string>&amp;Test Connection</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2"> <item row="1" column="0" colspan="2">
<widget class="QGroupBox" name="mAuthGroupBox"> <widget class="QGroupBox" name="mAuthGroupBox">
<property name="title"> <property name="title">
@ -146,159 +292,32 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="3" column="0" colspan="2"> <item row="5" column="0" colspan="2">
<widget class="QGroupBox" name="mWmsOptionsGroupBox"> <widget class="QPushButton" name="mTestConnectionButton">
<property name="text">
<string>&amp;Test Connection</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QGroupBox" name="mHttpGroupBox">
<property name="title"> <property name="title">
<string>WMS/WMTS Options</string> <string>HTTP</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout_2"> <layout class="QHBoxLayout" name="horizontalLayout">
<item row="5" column="0" colspan="2"> <item>
<widget class="QCheckBox" name="cbxWmsInvertAxisOrientation"> <widget class="QLabel" name="label">
<property name="text"> <property name="text">
<string>Invert axis orientation</string> <string>Referer</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="0" colspan="2"> <item>
<widget class="QCheckBox" name="cbxIgnoreGetFeatureInfoURI"> <widget class="QgsFilterLineEdit" name="mRefererLineEdit"/>
<property name="text">
<string>Ignore GetFeatureInfo URI reported in capabilities</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QCheckBox" name="cbxIgnoreGetMapURI">
<property name="text">
<string>Ignore GetMap/GetTile URI reported in capabilities</string>
</property>
</widget>
</item>
<item row="9" column="0" colspan="2">
<widget class="QCheckBox" name="cbxSmoothPixmapTransform">
<property name="text">
<string>Smooth pixmap transform</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="txtReferer"/>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="cmbDpiMode"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="lblDpiMode">
<property name="text">
<string>DPI-&amp;Mode</string>
</property>
<property name="buddy">
<cstring>cmbDpiMode</cstring>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="lblReferer">
<property name="text">
<string>&amp;Referer</string>
</property>
<property name="buddy">
<cstring>txtReferer</cstring>
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<widget class="QCheckBox" name="cbxWmsIgnoreAxisOrientation">
<property name="text">
<string>Ignore axis orientation (WMS 1.3/WMTS)</string>
</property>
</widget>
</item> </item>
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="0" column="0" colspan="2">
<widget class="QFrame" name="frame">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="TextLabel1_2">
<property name="text">
<string>Name</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="margin">
<number>5</number>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="txtName">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Name of the new connection</string>
</property>
<property name="frame">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="TextLabel1">
<property name="text">
<string>URL</string>
</property>
<property name="margin">
<number>5</number>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="txtUrl">
<property name="toolTip">
<string>HTTP address of the Web Map Server</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="5" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>
@ -313,6 +332,11 @@
</widget> </widget>
<layoutdefault spacing="6" margin="11"/> <layoutdefault spacing="6" margin="11"/>
<customwidgets> <customwidgets>
<customwidget>
<class>QgsFilterLineEdit</class>
<extends>QLineEdit</extends>
<header>qgsfilterlineedit.h</header>
</customwidget>
<customwidget> <customwidget>
<class>QgsAuthSettingsWidget</class> <class>QgsAuthSettingsWidget</class>
<extends>QWidget</extends> <extends>QWidget</extends>
@ -323,6 +347,7 @@
<tabstops> <tabstops>
<tabstop>txtName</tabstop> <tabstop>txtName</tabstop>
<tabstop>txtUrl</tabstop> <tabstop>txtUrl</tabstop>
<tabstop>mRefererLineEdit</tabstop>
<tabstop>cmbVersion</tabstop> <tabstop>cmbVersion</tabstop>
<tabstop>mWfsVersionDetectButton</tabstop> <tabstop>mWfsVersionDetectButton</tabstop>
<tabstop>txtMaxNumFeatures</tabstop> <tabstop>txtMaxNumFeatures</tabstop>