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 );
121 cbxIgnoreGetMapURI->setText( tr(
"Ignore GetCoverage URI reported in capabilities" ) );
122 cbxWmsIgnoreAxisOrientation->setText( tr(
"Ignore axis orientation" ) );
125 mWmsOptionsGroupBox->setTitle( tr(
"WCS Options" ) );
127 cbxIgnoreGetFeatureInfoURI->setVisible(
false );
128 mGroupBox->layout()->removeWidget( cbxIgnoreGetFeatureInfoURI );
130 cmbDpiMode->setVisible(
false );
131 mGroupBox->layout()->removeWidget( cmbDpiMode );
132 lblDpiMode->setVisible(
false );
133 mGroupBox->layout()->removeWidget( lblDpiMode );
139 mTestConnectionButton->hide();
140 mGroupBox->layout()->removeWidget( mTestConnectionButton );
145 mAuthGroupBox->hide();
146 mGroupBox->layout()->removeWidget( mAuthGroupBox );
151 resize( w, height() );
153 connect( txtName, &QLineEdit::textChanged,
this, &QgsNewHttpConnection::nameChanged );
154 connect( txtUrl, &QLineEdit::textChanged,
this, &QgsNewHttpConnection::urlChanged );
156 buttonBox->button( QDialogButtonBox::Ok )->setDisabled(
true );
157 connect( txtName, &QLineEdit::textChanged,
this, &QgsNewHttpConnection::updateOkButtonState );
158 connect( txtUrl, &QLineEdit::textChanged,
this, &QgsNewHttpConnection::updateOkButtonState );
160 nameChanged( connectionName );
163 void QgsNewHttpConnection::wfsVersionCurrentIndexChanged(
int index )
174 void QgsNewHttpConnection::wfsFeaturePagingStateChanged(
int state )
176 lblPageSize->setEnabled( state == Qt::Checked );
177 txtPageSize->setEnabled( state == Qt::Checked );
182 return txtName->text();
187 return txtUrl->text();
190 void QgsNewHttpConnection::nameChanged(
const QString &text )
193 buttonBox->button( QDialogButtonBox::Ok )->setDisabled( txtName->text().isEmpty() || txtUrl->text().isEmpty() );
196 void QgsNewHttpConnection::urlChanged(
const QString &text )
199 buttonBox->button( QDialogButtonBox::Ok )->setDisabled( txtName->text().isEmpty() || txtUrl->text().isEmpty() );
200 mWfsVersionDetectButton->setDisabled( txtUrl->text().isEmpty() );
203 void QgsNewHttpConnection::updateOkButtonState()
205 bool enabled = !txtName->text().isEmpty() && !txtUrl->text().isEmpty();
206 buttonBox->button( QDialogButtonBox::Ok )->setEnabled( enabled );
212 QString key = mBaseKey + txtName->text();
215 if ( ( mOriginalConnName.isNull() || mOriginalConnName.compare( txtName->text(), Qt::CaseInsensitive ) != 0 ) &&
216 settings.
contains( key +
"/url" ) &&
217 QMessageBox::question(
this,
218 tr(
"Save Connection" ),
219 tr(
"Should the existing connection %1 be overwritten?" ).arg( txtName->text() ),
220 QMessageBox::Ok | QMessageBox::Cancel ) == QMessageBox::Cancel )
225 if ( ! mAuthSettings->password().isEmpty() &&
226 QMessageBox::question(
this,
227 tr(
"Saving Passwords" ),
228 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." ),
229 QMessageBox::Ok | QMessageBox::Cancel ) == QMessageBox::Cancel )
239 return mTestConnectionButton;
244 return mAuthSettings;
249 return mWfsVersionDetectButton;
259 return cbxWfsFeaturePaging;
264 return cbxWfsUseGml2EncodingForTransactions;
274 return base + connectionName;
279 return base + connectionName;
288 cbxIgnoreGetMapURI->setChecked( settings.
value( wmsKey +
"/ignoreGetMapURI",
false ).toBool() );
289 cbxWmsIgnoreReportedLayerExtents->setChecked( settings.
value( wmsKey + QStringLiteral(
"/ignoreReportedLayerExtents" ),
false ).toBool() );
290 cbxWfsIgnoreAxisOrientation->setChecked( settings.
value( wfsKey +
"/ignoreAxisOrientation",
false ).toBool() );
291 cbxWfsInvertAxisOrientation->setChecked( settings.
value( wfsKey +
"/invertAxisOrientation",
false ).toBool() );
292 cbxWfsUseGml2EncodingForTransactions->setChecked( settings.
value( wfsKey +
"/preferCoordinatesForWfsT11",
false ).toBool() );
294 cbxWmsIgnoreAxisOrientation->setChecked( settings.
value( wmsKey +
"/ignoreAxisOrientation",
false ).toBool() );
295 cbxWmsInvertAxisOrientation->setChecked( settings.
value( wmsKey +
"/invertAxisOrientation",
false ).toBool() );
296 cbxIgnoreGetFeatureInfoURI->setChecked( settings.
value( wmsKey +
"/ignoreGetFeatureInfoURI",
false ).toBool() );
297 cbxSmoothPixmapTransform->setChecked( settings.
value( wmsKey +
"/smoothPixmapTransform",
false ).toBool() );
300 switch ( settings.
value( wmsKey +
"/dpiMode", 7 ).toInt() )
318 cmbDpiMode->setCurrentIndex( dpiIdx );
320 QString version = settings.
value( wfsKey +
"/version" ).toString();
322 if ( version == QLatin1String(
"1.0.0" ) )
324 else if ( version == QLatin1String(
"1.1.0" ) )
326 else if ( version == QLatin1String(
"2.0.0" ) )
328 else if ( version == QLatin1String(
"OGC_API_FEATURES" ) )
330 cmbVersion->setCurrentIndex( versionIdx );
333 wfsVersionCurrentIndexChanged( versionIdx );
335 mRefererLineEdit->setText( settings.
value( wmsKey +
"/referer" ).toString() );
336 txtMaxNumFeatures->setText( settings.
value( wfsKey +
"/maxnumfeatures" ).toString() );
340 txtPageSize->setText( settings.
value( wfsKey +
"/pagesize" ).toString() );
341 cbxWfsFeaturePaging->setChecked( pagingEnabled );
349 return "0123456789ABCDEF"[value & 0xF];
352 static inline ushort encodeNibble( ushort
c )
359 while ( ptr + 4 <= end )
361 quint32 data = qFromUnaligned<quint32>( ptr );
362 if ( data &= 0x80808080U )
364 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
365 uint idx = qCountLeadingZeroBits( data );
367 uint idx = qCountTrailingZeroBits( data );
376 if ( quint8( *ptr ) & 0x80 )
389 const char *in = ba.constData();
390 const char *
const end = ba.constEnd();
394 return QString::fromLatin1( ba, ba.size() );
397 QByteArray intermediate = ba;
398 intermediate.resize( ba.size() * 3 - ( in - ba.constData() ) );
399 uchar *out =
reinterpret_cast<uchar *
>( intermediate.data() + ( in - ba.constData() ) );
400 for ( ; in < end; ++in )
406 *out++ = encodeNibble( uchar( *in ) >> 4 );
407 *out++ = encodeNibble( uchar( *in ) & 0xf );
412 *out++ = uchar( *in );
416 return QString::fromLatin1( intermediate, out -
reinterpret_cast<uchar *
>( intermediate.data() ) );
422 QUrl
url( txtUrl->text().trimmed() );
423 QUrlQuery query(
url );
424 const QList<QPair<QString, QString> > items = query.queryItems( QUrl::FullyEncoded );
425 QHash< QString, QPair<QString, QString> > params;
426 for (
const QPair<QString, QString> &it : items )
428 params.insert( it.first.toUpper(), it );
431 if ( params[QStringLiteral(
"SERVICE" )].second.toUpper() ==
"WMS" ||
432 params[QStringLiteral(
"SERVICE" )].second.toUpper() ==
"WFS" ||
433 params[QStringLiteral(
"SERVICE" )].second.toUpper() ==
"WCS" )
435 query.removeQueryItem( params.value( QStringLiteral(
"SERVICE" ) ).first );
436 query.removeQueryItem( params.value( QStringLiteral(
"REQUEST" ) ).first );
437 query.removeQueryItem( params.value( QStringLiteral(
"FORMAT" ) ).first );
440 url.setQuery( query );
442 if (
url.path( QUrl::FullyEncoded ).isEmpty() )
452 QString key = mBaseKey + txtName->text();
453 QString credentialsKey =
"qgis/" + mCredentialsBaseKey +
'/' + txtName->text();
459 if ( !mOriginalConnName.isNull() && mOriginalConnName != key )
461 settings.
remove( mBaseKey + mOriginalConnName );
462 settings.
remove(
"qgis/" + mCredentialsBaseKey +
'/' + mOriginalConnName );
474 settings.
setValue( wfsKey +
"/ignoreAxisOrientation", cbxWfsIgnoreAxisOrientation->isChecked() );
475 settings.
setValue( wfsKey +
"/invertAxisOrientation", cbxWfsInvertAxisOrientation->isChecked() );
476 settings.
setValue( wfsKey +
"/preferCoordinatesForWfsT11", cbxWfsUseGml2EncodingForTransactions->isChecked() );
480 settings.
setValue( wmsKey +
"/ignoreAxisOrientation", cbxWmsIgnoreAxisOrientation->isChecked() );
481 settings.
setValue( wmsKey +
"/invertAxisOrientation", cbxWmsInvertAxisOrientation->isChecked() );
483 settings.
setValue( wmsKey + QStringLiteral(
"/ignoreReportedLayerExtents" ), cbxWmsIgnoreReportedLayerExtents->isChecked() );
484 settings.
setValue( wmsKey +
"/ignoreGetMapURI", cbxIgnoreGetMapURI->isChecked() );
485 settings.
setValue( wmsKey +
"/smoothPixmapTransform", cbxSmoothPixmapTransform->isChecked() );
488 switch ( cmbDpiMode->currentIndex() )
507 settings.
setValue( wmsKey +
"/dpiMode", dpiMode );
509 settings.
setValue( wmsKey +
"/referer", mRefererLineEdit->text() );
513 settings.
setValue( wmsKey +
"/ignoreGetFeatureInfoURI", cbxIgnoreGetFeatureInfoURI->isChecked() );
517 QString version = QStringLiteral(
"auto" );
518 switch ( cmbVersion->currentIndex() )
521 version = QStringLiteral(
"auto" );
524 version = QStringLiteral(
"1.0.0" );
527 version = QStringLiteral(
"1.1.0" );
530 version = QStringLiteral(
"2.0.0" );
533 version = QStringLiteral(
"OGC_API_FEATURES" );
536 settings.
setValue( wfsKey +
"/version", version );
538 settings.
setValue( wfsKey +
"/maxnumfeatures", txtMaxNumFeatures->text() );
540 settings.
setValue( wfsKey +
"/pagesize", txtPageSize->text() );
541 settings.
setValue( wfsKey +
"/pagingenabled", cbxWfsFeaturePaging->isChecked() );
544 settings.
setValue( credentialsKey +
"/username", mAuthSettings->username() );
545 settings.
setValue( credentialsKey +
"/password", mAuthSettings->password() );
547 settings.
setValue( credentialsKey +
"/authcfg", mAuthSettings->configId() );
549 if ( mHttpGroupBox->isVisible() )
550 settings.
setValue( key +
"/referer", mRefererLineEdit->text() );
552 settings.
setValue( mBaseKey +
"/selected", txtName->text() );
557 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.
This class is a composition of two QSettings instances:
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
bool contains(const QString &key, QgsSettings::Section section=QgsSettings::NoSection) const
Returns true if there exists a setting called key; returns false otherwise.
void sync()
Writes any unsaved changes to permanent storage, and reloads any settings that have been changed in t...
void remove(const QString &key, QgsSettings::Section section=QgsSettings::NoSection)
Removes the setting key and any sub-settings of key in a section.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
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