19 #include "qgssettings.h" 
   23 #include <QMessageBox> 
   25 #include <QPushButton> 
   27 #include <QRegExpValidator> 
   32   : QDialog( parent, fl )
 
   35   , mOriginalConnName( connectionName )
 
   40     mHttpGroupBox->hide();
 
   44   connect( buttonBox, &QDialogButtonBox::helpRequested, 
this, &QgsNewHttpConnection::showHelp );
 
   46   QRegExp rx( 
"/connections-([^/]+)/" );
 
   47   if ( rx.indexIn( baseKey ) != -1 )
 
   49     QString connectionType( rx.cap( 1 ).toUpper() );
 
   50     if ( connectionType == QLatin1String( 
"WMS" ) )
 
   52       connectionType = QStringLiteral( 
"WMS/WMTS" );
 
   54     setWindowTitle( tr( 
"Create a New %1 Connection" ).arg( connectionType ) );
 
   62   mCredentialsBaseKey = mBaseKey.split( 
'-' ).last().toUpper();
 
   64   txtName->setValidator( 
new QRegExpValidator( QRegExp( 
"[^\\/]+" ), txtName ) );
 
   67   cmbDpiMode->addItem( tr( 
"all" ) );
 
   68   cmbDpiMode->addItem( tr( 
"off" ) );
 
   69   cmbDpiMode->addItem( tr( 
"QGIS" ) );
 
   70   cmbDpiMode->addItem( tr( 
"UMN" ) );
 
   71   cmbDpiMode->addItem( tr( 
"GeoServer" ) );
 
   74   cmbVersion->addItem( tr( 
"Maximum" ) );
 
   75   cmbVersion->addItem( tr( 
"1.0" ) );
 
   76   cmbVersion->addItem( tr( 
"1.1" ) );
 
   77   cmbVersion->addItem( tr( 
"2.0" ) );
 
   78   cmbVersion->addItem( tr( 
"OGC API - Features" ) );
 
   80            static_cast<void ( QComboBox::* )( 
int )
>( &QComboBox::currentIndexChanged ),
 
   81            this, &QgsNewHttpConnection::wfsVersionCurrentIndexChanged );
 
   83   connect( cbxWfsFeaturePaging, &QCheckBox::stateChanged,
 
   84            this, &QgsNewHttpConnection::wfsFeaturePagingStateChanged );
 
   86   if ( !connectionName.isEmpty() )
 
   93     QString key = mBaseKey + connectionName;
 
   94     QString credentialsKey = 
"qgis/" + mCredentialsBaseKey + 
'/' + connectionName;
 
   95     txtName->setText( connectionName );
 
   96     txtUrl->setText( settings.value( key + 
"/url" ).toString() );
 
   97     mRefererLineEdit->setText( settings.value( key + 
"/referer" ).toString() );
 
  102     mAuthSettings->setUsername( settings.value( credentialsKey + 
"/username" ).toString() );
 
  103     mAuthSettings->setPassword( settings.value( credentialsKey + 
"/password" ).toString() );
 
  104     mAuthSettings->setConfigId( settings.value( credentialsKey + 
"/authcfg" ).toString() );
 
  106   mWfsVersionDetectButton->setDisabled( txtUrl->text().isEmpty() );
 
  110     mWmsOptionsGroupBox->setVisible( 
false );
 
  111     mGroupBox->layout()->removeWidget( mWmsOptionsGroupBox );
 
  115     mWfsOptionsGroupBox->setVisible( 
false );
 
  116     mGroupBox->layout()->removeWidget( mWfsOptionsGroupBox );
 
  120     txtUrl->setToolTip( tr( 
"HTTP address of the WFS service, or landing page of a OGC API service<br>(an ending slash might be needed for some OGC API servers)" ) );
 
  125     cbxIgnoreGetMapURI->setText( tr( 
"Ignore GetCoverage URI reported in capabilities" ) );
 
  126     cbxWmsIgnoreAxisOrientation->setText( tr( 
"Ignore axis orientation" ) );
 
  129       mWmsOptionsGroupBox->setTitle( tr( 
"WCS Options" ) );
 
  131       cbxIgnoreGetFeatureInfoURI->setVisible( 
false );
 
  132       mGroupBox->layout()->removeWidget( cbxIgnoreGetFeatureInfoURI );
 
  134       cmbDpiMode->setVisible( 
false );
 
  135       mGroupBox->layout()->removeWidget( cmbDpiMode );
 
  136       lblDpiMode->setVisible( 
false );
 
  137       mGroupBox->layout()->removeWidget( lblDpiMode );
 
  143     mTestConnectionButton->hide();
 
  144     mGroupBox->layout()->removeWidget( mTestConnectionButton );
 
  149     mAuthGroupBox->hide();
 
  150     mGroupBox->layout()->removeWidget( mAuthGroupBox );
 
  155   resize( w, height() );
 
  157   connect( txtName, &QLineEdit::textChanged, 
this, &QgsNewHttpConnection::nameChanged );
 
  158   connect( txtUrl, &QLineEdit::textChanged, 
this, &QgsNewHttpConnection::urlChanged );
 
  160   buttonBox->button( QDialogButtonBox::Ok )->setDisabled( 
true );
 
  161   connect( txtName, &QLineEdit::textChanged, 
this, &QgsNewHttpConnection::updateOkButtonState );
 
  162   connect( txtUrl, &QLineEdit::textChanged, 
this, &QgsNewHttpConnection::updateOkButtonState );
 
  164   nameChanged( connectionName );
 
  167 void QgsNewHttpConnection::wfsVersionCurrentIndexChanged( 
int index )
 
  178 void QgsNewHttpConnection::wfsFeaturePagingStateChanged( 
int state )
 
  180   lblPageSize->setEnabled( state == Qt::Checked );
 
  181   txtPageSize->setEnabled( state == Qt::Checked );
 
  186   return txtName->text();
 
  191   return txtUrl->text();
 
  194 void QgsNewHttpConnection::nameChanged( 
const QString &text )
 
  197   buttonBox->button( QDialogButtonBox::Ok )->setDisabled( txtName->text().isEmpty() || txtUrl->text().isEmpty() );
 
  200 void QgsNewHttpConnection::urlChanged( 
const QString &text )
 
  203   buttonBox->button( QDialogButtonBox::Ok )->setDisabled( txtName->text().isEmpty() || txtUrl->text().isEmpty() );
 
  204   mWfsVersionDetectButton->setDisabled( txtUrl->text().isEmpty() );
 
  207 void QgsNewHttpConnection::updateOkButtonState()
 
  209   bool enabled = !txtName->text().isEmpty() && !txtUrl->text().isEmpty();
 
  210   buttonBox->button( QDialogButtonBox::Ok )->setEnabled( enabled );
 
  215   QgsSettings settings;
 
  216   QString key = mBaseKey + txtName->text();
 
  219   if ( ( mOriginalConnName.isNull() || mOriginalConnName.compare( txtName->text(), Qt::CaseInsensitive ) != 0 ) &&
 
  220        settings.contains( key + 
"/url" ) &&
 
  221        QMessageBox::question( 
this,
 
  222                               tr( 
"Save Connection" ),
 
  223                               tr( 
"Should the existing connection %1 be overwritten?" ).arg( txtName->text() ),
 
  224                               QMessageBox::Ok | QMessageBox::Cancel ) == QMessageBox::Cancel )
 
  229   if ( ! mAuthSettings->password().isEmpty() &&
 
  230        QMessageBox::question( 
this,
 
  231                               tr( 
"Saving Passwords" ),
 
  232                               tr( 
"WARNING: You have entered a password. It will be stored in unsecured plain text in your project files and your home directory (Unix-like OS) or user profile (Windows). If you want to avoid this, press Cancel and either:\n\na) Don't provide a password in the connection settings — it will be requested interactively when needed;\nb) Use the Configuration tab to add your credentials in an HTTP Basic Authentication method and store them in an encrypted database." ),
 
  233                               QMessageBox::Ok | QMessageBox::Cancel ) == QMessageBox::Cancel )
 
  243   return mTestConnectionButton;
 
  248   return mAuthSettings;
 
  253   return mWfsVersionDetectButton;
 
  263   return cbxWfsFeaturePaging;
 
  268   return cbxWfsUseGml2EncodingForTransactions;
 
  278   return base + connectionName;
 
  283   return base + connectionName;
 
  288   QgsSettings settings;
 
  292   cbxIgnoreGetMapURI->setChecked( settings.value( wmsKey + 
"/ignoreGetMapURI", 
false ).toBool() );
 
  293   cbxWmsIgnoreReportedLayerExtents->setChecked( settings.value( wmsKey + QStringLiteral( 
"/ignoreReportedLayerExtents" ), 
false ).toBool() );
 
  294   cbxWfsIgnoreAxisOrientation->setChecked( settings.value( wfsKey + 
"/ignoreAxisOrientation", 
false ).toBool() );
 
  295   cbxWfsInvertAxisOrientation->setChecked( settings.value( wfsKey + 
"/invertAxisOrientation", 
false ).toBool() );
 
  296   cbxWfsUseGml2EncodingForTransactions->setChecked( settings.value( wfsKey + 
"/preferCoordinatesForWfsT11", 
false ).toBool() );
 
  298   cbxWmsIgnoreAxisOrientation->setChecked( settings.value( wmsKey + 
"/ignoreAxisOrientation", 
false ).toBool() );
 
  299   cbxWmsInvertAxisOrientation->setChecked( settings.value( wmsKey + 
"/invertAxisOrientation", 
false ).toBool() );
 
  300   cbxIgnoreGetFeatureInfoURI->setChecked( settings.value( wmsKey + 
"/ignoreGetFeatureInfoURI", 
false ).toBool() );
 
  301   cbxSmoothPixmapTransform->setChecked( settings.value( wmsKey + 
"/smoothPixmapTransform", 
false ).toBool() );
 
  304   switch ( settings.value( wmsKey + 
"/dpiMode", 7 ).toInt() )
 
  322   cmbDpiMode->setCurrentIndex( dpiIdx );
 
  324   QString version = settings.value( wfsKey + 
"/version" ).toString();
 
  326   if ( version == QLatin1String( 
"1.0.0" ) )
 
  328   else if ( version == QLatin1String( 
"1.1.0" ) )
 
  330   else if ( version == QLatin1String( 
"2.0.0" ) )
 
  332   else if ( version == QLatin1String( 
"OGC_API_FEATURES" ) )
 
  334   cmbVersion->setCurrentIndex( versionIdx );
 
  337   wfsVersionCurrentIndexChanged( versionIdx );
 
  339   mRefererLineEdit->setText( settings.value( wmsKey + 
"/referer" ).toString() );
 
  340   txtMaxNumFeatures->setText( settings.value( wfsKey + 
"/maxnumfeatures" ).toString() );
 
  344   txtPageSize->setText( settings.value( wfsKey + 
"/pagesize" ).toString() );
 
  345   cbxWfsFeaturePaging->setChecked( pagingEnabled );
 
  353   return "0123456789ABCDEF"[value & 0xF];
 
  356 static inline ushort encodeNibble( ushort 
c )
 
  363   while ( ptr + 4 <= end )
 
  365     quint32 data = qFromUnaligned<quint32>( ptr );
 
  366     if ( data &= 0x80808080U )
 
  368 #if Q_BYTE_ORDER == Q_BIG_ENDIAN 
  369       uint idx = qCountLeadingZeroBits( data );
 
  371       uint idx = qCountTrailingZeroBits( data );
 
  380     if ( quint8( *ptr ) & 0x80 )
 
  393   const char *in = ba.constData();
 
  394   const char *
const end = ba.constEnd();
 
  398     return QString::fromLatin1( ba, ba.size() );
 
  401   QByteArray intermediate = ba;
 
  402   intermediate.resize( ba.size() * 3 - ( in - ba.constData() ) );
 
  403   uchar *out = 
reinterpret_cast<uchar *
>( intermediate.data() + ( in - ba.constData() ) );
 
  404   for ( ; in < end; ++in )
 
  410       *out++ = encodeNibble( uchar( *in ) >> 4 );
 
  411       *out++ = encodeNibble( uchar( *in ) & 0xf );
 
  416       *out++ = uchar( *in );
 
  420   return QString::fromLatin1( intermediate, out - 
reinterpret_cast<uchar *
>( intermediate.data() ) );
 
  426   QUrl 
url( txtUrl->text().trimmed() );
 
  427   QUrlQuery query( 
url );
 
  428   const QList<QPair<QString, QString> > items = query.queryItems( QUrl::FullyEncoded );
 
  429   QHash< QString, QPair<QString, QString> > params;
 
  430   for ( 
const QPair<QString, QString> &it : items )
 
  432     params.insert( it.first.toUpper(), it );
 
  435   if ( params[QStringLiteral( 
"SERVICE" )].second.toUpper() == 
"WMS" ||
 
  436        params[QStringLiteral( 
"SERVICE" )].second.toUpper() == 
"WFS" ||
 
  437        params[QStringLiteral( 
"SERVICE" )].second.toUpper() == 
"WCS" )
 
  439     query.removeQueryItem( params.value( QStringLiteral( 
"SERVICE" ) ).first );
 
  440     query.removeQueryItem( params.value( QStringLiteral( 
"REQUEST" ) ).first );
 
  441     query.removeQueryItem( params.value( QStringLiteral( 
"FORMAT" ) ).first );
 
  444   url.setQuery( query );
 
  446   if ( 
url.path( QUrl::FullyEncoded ).isEmpty() )
 
  455   QgsSettings settings;
 
  456   QString key = mBaseKey + txtName->text();
 
  457   QString credentialsKey = 
"qgis/" + mCredentialsBaseKey + 
'/' + txtName->text();
 
  463   if ( !mOriginalConnName.isNull() && mOriginalConnName != key )
 
  465     settings.remove( mBaseKey + mOriginalConnName );
 
  466     settings.remove( 
"qgis/" + mCredentialsBaseKey + 
'/' + mOriginalConnName );
 
  471   settings.setValue( key + 
"/url", 
url.toString() );
 
  478     settings.setValue( wfsKey + 
"/ignoreAxisOrientation", cbxWfsIgnoreAxisOrientation->isChecked() );
 
  479     settings.setValue( wfsKey + 
"/invertAxisOrientation", cbxWfsInvertAxisOrientation->isChecked() );
 
  480     settings.setValue( wfsKey + 
"/preferCoordinatesForWfsT11", cbxWfsUseGml2EncodingForTransactions->isChecked() );
 
  484     settings.setValue( wmsKey + 
"/ignoreAxisOrientation", cbxWmsIgnoreAxisOrientation->isChecked() );
 
  485     settings.setValue( wmsKey + 
"/invertAxisOrientation", cbxWmsInvertAxisOrientation->isChecked() );
 
  487     settings.setValue( wmsKey + QStringLiteral( 
"/ignoreReportedLayerExtents" ), cbxWmsIgnoreReportedLayerExtents->isChecked() );
 
  488     settings.setValue( wmsKey + 
"/ignoreGetMapURI", cbxIgnoreGetMapURI->isChecked() );
 
  489     settings.setValue( wmsKey + 
"/smoothPixmapTransform", cbxSmoothPixmapTransform->isChecked() );
 
  492     switch ( cmbDpiMode->currentIndex() )
 
  511     settings.setValue( wmsKey + 
"/dpiMode", dpiMode );
 
  513     settings.setValue( wmsKey + 
"/referer", mRefererLineEdit->text() );
 
  517     settings.setValue( wmsKey + 
"/ignoreGetFeatureInfoURI", cbxIgnoreGetFeatureInfoURI->isChecked() );
 
  521     QString version = QStringLiteral( 
"auto" );
 
  522     switch ( cmbVersion->currentIndex() )
 
  525         version = QStringLiteral( 
"auto" );
 
  528         version = QStringLiteral( 
"1.0.0" );
 
  531         version = QStringLiteral( 
"1.1.0" );
 
  534         version = QStringLiteral( 
"2.0.0" );
 
  537         version = QStringLiteral( 
"OGC_API_FEATURES" );
 
  540     settings.setValue( wfsKey + 
"/version", version );
 
  542     settings.setValue( wfsKey + 
"/maxnumfeatures", txtMaxNumFeatures->text() );
 
  544     settings.setValue( wfsKey + 
"/pagesize", txtPageSize->text() );
 
  545     settings.setValue( wfsKey + 
"/pagingenabled", cbxWfsFeaturePaging->isChecked() );
 
  548   settings.setValue( credentialsKey + 
"/username", mAuthSettings->username() );
 
  549   settings.setValue( credentialsKey + 
"/password", mAuthSettings->password() );
 
  551   settings.setValue( credentialsKey + 
"/authcfg", mAuthSettings->configId() );
 
  553   if ( mHttpGroupBox->isVisible() )
 
  554     settings.setValue( key + 
"/referer", mRefererLineEdit->text() );
 
  556   settings.setValue( mBaseKey + 
"/selected", txtName->text() );
 
  561 void QgsNewHttpConnection::showHelp()
 
static void enableAutoGeometryRestore(QWidget *widget, const QString &key=QString())
Register the widget to allow its position to be automatically saved and restored when open and closed...
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
QgsNewHttpConnection(QWidget *parent=nullptr, QgsNewHttpConnection::ConnectionTypes types=ConnectionWms, const QString &baseKey="qgis/connections-wms/", const QString &connectionName=QString(), QgsNewHttpConnection::Flags flags=QgsNewHttpConnection::Flags(), Qt::WindowFlags fl=QgsGuiUtils::ModalDialogFlags)
Constructor for QgsNewHttpConnection.
QPushButton * testConnectButton()
Returns the "test connection" button.
QgsAuthSettingsWidget * authSettingsWidget()
Returns the current authentication settings widget.
QCheckBox * wfsPagingEnabledCheckBox()
Returns the "WFS paging enabled" checkbox.
virtual bool validate()
Returns true if dialog settings are valid, or false if current settings are not valid and the dialog ...
QString name() const
Returns the current connection name.
@ FlagShowHttpSettings
Display the 'http' group.
@ FlagHideAuthenticationGroup
Hide the Authentication group.
@ FlagShowTestConnection
Display the 'test connection' button.
QCheckBox * wfsUseGml2EncodingForTransactions()
Returns the "Use GML2 encoding for transactions" checkbox.
QComboBox * wfsVersionComboBox()
Returns the "WFS version" combobox.
virtual QString wmsSettingsKey(const QString &base, const QString &connectionName) const
Returns the QSettings key for WMS related settings for the connection.
virtual QString wfsSettingsKey(const QString &base, const QString &connectionName) const
Returns the QSettings key for WFS related settings for the connection.
QString url() const
Returns the current connection url.
QPushButton * wfsVersionDetectButton()
Returns the "WFS version detect" button.
@ WFS_VERSION_API_FEATURES_1_0
QUrl urlTrimmed() const
Returns the url.
QLineEdit * wfsPageSizeLineEdit()
Returns the "WFS page size" edit.
void updateServiceSpecificSettings()
Triggers a resync of the GUI widgets for the service specific settings (i.e.
@ ConnectionWms
WMS connection.
@ ConnectionWfs
WFS connection.
@ ConnectionWcs
WCS connection.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
QString fromEncodedComponent_helper(const QByteArray &ba)
bool qt_is_ascii(const char *&ptr, const char *end) noexcept
char toHexUpper(uint value) noexcept