23 #include <QMessageBox>
25 #include <QPushButton>
27 #include <QRegExpValidator>
30 : QDialog( parent, fl )
33 , mOriginalConnName( connectionName )
38 mHttpGroupBox->hide();
42 connect( buttonBox, &QDialogButtonBox::helpRequested,
this, &QgsNewHttpConnection::showHelp );
44 QRegExp rx(
"/connections-([^/]+)/" );
45 if ( rx.indexIn( baseKey ) != -1 )
47 QString connectionType( rx.cap( 1 ).toUpper() );
48 if ( connectionType == QLatin1String(
"WMS" ) )
50 connectionType = QStringLiteral(
"WMS/WMTS" );
52 setWindowTitle( tr(
"Create a New %1 Connection" ).arg( connectionType ) );
60 mCredentialsBaseKey = mBaseKey.split(
'-' ).last().toUpper();
62 txtName->setValidator(
new QRegExpValidator( QRegExp(
"[^\\/]+" ), txtName ) );
65 cmbDpiMode->addItem( tr(
"all" ) );
66 cmbDpiMode->addItem( tr(
"off" ) );
67 cmbDpiMode->addItem( tr(
"QGIS" ) );
68 cmbDpiMode->addItem( tr(
"UMN" ) );
69 cmbDpiMode->addItem( tr(
"GeoServer" ) );
72 cmbVersion->addItem( tr(
"Maximum" ) );
73 cmbVersion->addItem( tr(
"1.0" ) );
74 cmbVersion->addItem( tr(
"1.1" ) );
75 cmbVersion->addItem( tr(
"2.0" ) );
76 cmbVersion->addItem( tr(
"OGC API - Features" ) );
78 static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
79 this, &QgsNewHttpConnection::wfsVersionCurrentIndexChanged );
81 connect( cbxWfsFeaturePaging, &QCheckBox::stateChanged,
82 this, &QgsNewHttpConnection::wfsFeaturePagingStateChanged );
84 if ( !connectionName.isEmpty() )
91 QString key = mBaseKey + connectionName;
92 QString credentialsKey =
"qgis/" + mCredentialsBaseKey +
'/' + connectionName;
93 txtName->setText( connectionName );
94 txtUrl->setText( settings.
value( key +
"/url" ).toString() );
95 mRefererLineEdit->setText( settings.
value( key +
"/referer" ).toString() );
100 mAuthSettings->setUsername( settings.
value( credentialsKey +
"/username" ).toString() );
101 mAuthSettings->setPassword( settings.
value( credentialsKey +
"/password" ).toString() );
102 mAuthSettings->setConfigId( settings.
value( credentialsKey +
"/authcfg" ).toString() );
104 mWfsVersionDetectButton->setDisabled( txtUrl->text().isEmpty() );
108 mWmsOptionsGroupBox->setVisible(
false );
109 mGroupBox->layout()->removeWidget( mWmsOptionsGroupBox );
113 mWfsOptionsGroupBox->setVisible(
false );
114 mGroupBox->layout()->removeWidget( mWfsOptionsGroupBox );
119 cbxIgnoreGetMapURI->setText( tr(
"Ignore GetCoverage URI reported in capabilities" ) );
120 cbxWmsIgnoreAxisOrientation->setText( tr(
"Ignore axis orientation" ) );
123 mWmsOptionsGroupBox->setTitle( tr(
"WCS Options" ) );
125 cbxIgnoreGetFeatureInfoURI->setVisible(
false );
126 mGroupBox->layout()->removeWidget( cbxIgnoreGetFeatureInfoURI );
128 cmbDpiMode->setVisible(
false );
129 mGroupBox->layout()->removeWidget( cmbDpiMode );
130 lblDpiMode->setVisible(
false );
131 mGroupBox->layout()->removeWidget( lblDpiMode );
137 mTestConnectionButton->hide();
138 mGroupBox->layout()->removeWidget( mTestConnectionButton );
143 mAuthGroupBox->hide();
144 mGroupBox->layout()->removeWidget( mAuthGroupBox );
149 resize( w, height() );
151 connect( txtName, &QLineEdit::textChanged,
this, &QgsNewHttpConnection::nameChanged );
152 connect( txtUrl, &QLineEdit::textChanged,
this, &QgsNewHttpConnection::urlChanged );
154 buttonBox->button( QDialogButtonBox::Ok )->setDisabled(
true );
155 connect( txtName, &QLineEdit::textChanged,
this, &QgsNewHttpConnection::updateOkButtonState );
156 connect( txtUrl, &QLineEdit::textChanged,
this, &QgsNewHttpConnection::updateOkButtonState );
158 nameChanged( connectionName );
161 void QgsNewHttpConnection::wfsVersionCurrentIndexChanged(
int index )
172 void QgsNewHttpConnection::wfsFeaturePagingStateChanged(
int state )
174 lblPageSize->setEnabled( state == Qt::Checked );
175 txtPageSize->setEnabled( state == Qt::Checked );
180 return txtName->text();
185 return txtUrl->text();
188 void QgsNewHttpConnection::nameChanged(
const QString &text )
191 buttonBox->button( QDialogButtonBox::Ok )->setDisabled( txtName->text().isEmpty() || txtUrl->text().isEmpty() );
194 void QgsNewHttpConnection::urlChanged(
const QString &text )
197 buttonBox->button( QDialogButtonBox::Ok )->setDisabled( txtName->text().isEmpty() || txtUrl->text().isEmpty() );
198 mWfsVersionDetectButton->setDisabled( txtUrl->text().isEmpty() );
201 void QgsNewHttpConnection::updateOkButtonState()
203 bool enabled = !txtName->text().isEmpty() && !txtUrl->text().isEmpty();
204 buttonBox->button( QDialogButtonBox::Ok )->setEnabled( enabled );
210 QString key = mBaseKey + txtName->text();
213 if ( ( mOriginalConnName.isNull() || mOriginalConnName.compare( txtName->text(), Qt::CaseInsensitive ) != 0 ) &&
214 settings.
contains( key +
"/url" ) &&
215 QMessageBox::question(
this,
216 tr(
"Save Connection" ),
217 tr(
"Should the existing connection %1 be overwritten?" ).arg( txtName->text() ),
218 QMessageBox::Ok | QMessageBox::Cancel ) == QMessageBox::Cancel )
223 if ( ! mAuthSettings->password().isEmpty() &&
224 QMessageBox::question(
this,
225 tr(
"Saving Passwords" ),
226 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." ),
227 QMessageBox::Ok | QMessageBox::Cancel ) == QMessageBox::Cancel )
237 return mTestConnectionButton;
242 return mAuthSettings;
247 return mWfsVersionDetectButton;
257 return cbxWfsFeaturePaging;
262 return cbxWfsUseGml2EncodingForTransactions;
272 return base + connectionName;
277 return base + connectionName;
286 cbxIgnoreGetMapURI->setChecked( settings.
value( wmsKey +
"/ignoreGetMapURI",
false ).toBool() );
287 cbxWmsIgnoreReportedLayerExtents->setChecked( settings.
value( wmsKey + QStringLiteral(
"/ignoreReportedLayerExtents" ),
false ).toBool() );
288 cbxWfsIgnoreAxisOrientation->setChecked( settings.
value( wfsKey +
"/ignoreAxisOrientation",
false ).toBool() );
289 cbxWfsInvertAxisOrientation->setChecked( settings.
value( wfsKey +
"/invertAxisOrientation",
false ).toBool() );
290 cbxWfsUseGml2EncodingForTransactions->setChecked( settings.
value( wfsKey +
"/preferCoordinatesForWfsT11",
false ).toBool() );
292 cbxWmsIgnoreAxisOrientation->setChecked( settings.
value( wmsKey +
"/ignoreAxisOrientation",
false ).toBool() );
293 cbxWmsInvertAxisOrientation->setChecked( settings.
value( wmsKey +
"/invertAxisOrientation",
false ).toBool() );
294 cbxIgnoreGetFeatureInfoURI->setChecked( settings.
value( wmsKey +
"/ignoreGetFeatureInfoURI",
false ).toBool() );
295 cbxSmoothPixmapTransform->setChecked( settings.
value( wmsKey +
"/smoothPixmapTransform",
false ).toBool() );
298 switch ( settings.
value( wmsKey +
"/dpiMode", 7 ).toInt() )
316 cmbDpiMode->setCurrentIndex( dpiIdx );
318 QString version = settings.
value( wfsKey +
"/version" ).toString();
320 if ( version == QLatin1String(
"1.0.0" ) )
322 else if ( version == QLatin1String(
"1.1.0" ) )
324 else if ( version == QLatin1String(
"2.0.0" ) )
326 else if ( version == QLatin1String(
"OGC_API_FEATURES" ) )
328 cmbVersion->setCurrentIndex( versionIdx );
331 wfsVersionCurrentIndexChanged( versionIdx );
333 mRefererLineEdit->setText( settings.
value( wmsKey +
"/referer" ).toString() );
334 txtMaxNumFeatures->setText( settings.
value( wfsKey +
"/maxnumfeatures" ).toString() );
338 txtPageSize->setText( settings.
value( wfsKey +
"/pagesize" ).toString() );
339 cbxWfsFeaturePaging->setChecked( pagingEnabled );
347 return "0123456789ABCDEF"[value & 0xF];
350 static inline ushort encodeNibble( ushort
c )
357 while ( ptr + 4 <= end )
359 quint32 data = qFromUnaligned<quint32>( ptr );
360 if ( data &= 0x80808080U )
362 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
363 uint idx = qCountLeadingZeroBits( data );
365 uint idx = qCountTrailingZeroBits( data );
374 if ( quint8( *ptr ) & 0x80 )
387 const char *in = ba.constData();
388 const char *
const end = ba.constEnd();
392 return QString::fromLatin1( ba, ba.size() );
395 QByteArray intermediate = ba;
396 intermediate.resize( ba.size() * 3 - ( in - ba.constData() ) );
397 uchar *out =
reinterpret_cast<uchar *
>( intermediate.data() + ( in - ba.constData() ) );
398 for ( ; in < end; ++in )
404 *out++ = encodeNibble( uchar( *in ) >> 4 );
405 *out++ = encodeNibble( uchar( *in ) & 0xf );
410 *out++ = uchar( *in );
414 return QString::fromLatin1( intermediate, out -
reinterpret_cast<uchar *
>( intermediate.data() ) );
420 QUrl
url( txtUrl->text().trimmed() );
421 QUrlQuery query(
url );
422 const QList<QPair<QString, QString> > items = query.queryItems( QUrl::FullyEncoded );
423 QHash< QString, QPair<QString, QString> > params;
424 for (
const QPair<QString, QString> &it : items )
426 params.insert( it.first.toUpper(), it );
429 if ( params[QStringLiteral(
"SERVICE" )].second.toUpper() ==
"WMS" ||
430 params[QStringLiteral(
"SERVICE" )].second.toUpper() ==
"WFS" ||
431 params[QStringLiteral(
"SERVICE" )].second.toUpper() ==
"WCS" )
433 query.removeQueryItem( params.value( QStringLiteral(
"SERVICE" ) ).first );
434 query.removeQueryItem( params.value( QStringLiteral(
"REQUEST" ) ).first );
435 query.removeQueryItem( params.value( QStringLiteral(
"FORMAT" ) ).first );
438 url.setQuery( query );
440 if (
url.path( QUrl::FullyEncoded ).isEmpty() )
450 QString key = mBaseKey + txtName->text();
451 QString credentialsKey =
"qgis/" + mCredentialsBaseKey +
'/' + txtName->text();
457 if ( !mOriginalConnName.isNull() && mOriginalConnName != key )
459 settings.
remove( mBaseKey + mOriginalConnName );
460 settings.
remove(
"qgis/" + mCredentialsBaseKey +
'/' + mOriginalConnName );
472 settings.
setValue( wfsKey +
"/ignoreAxisOrientation", cbxWfsIgnoreAxisOrientation->isChecked() );
473 settings.
setValue( wfsKey +
"/invertAxisOrientation", cbxWfsInvertAxisOrientation->isChecked() );
474 settings.
setValue( wfsKey +
"/preferCoordinatesForWfsT11", cbxWfsUseGml2EncodingForTransactions->isChecked() );
478 settings.
setValue( wmsKey +
"/ignoreAxisOrientation", cbxWmsIgnoreAxisOrientation->isChecked() );
479 settings.
setValue( wmsKey +
"/invertAxisOrientation", cbxWmsInvertAxisOrientation->isChecked() );
481 settings.
setValue( wmsKey + QStringLiteral(
"/ignoreReportedLayerExtents" ), cbxWmsIgnoreReportedLayerExtents->isChecked() );
482 settings.
setValue( wmsKey +
"/ignoreGetMapURI", cbxIgnoreGetMapURI->isChecked() );
483 settings.
setValue( wmsKey +
"/smoothPixmapTransform", cbxSmoothPixmapTransform->isChecked() );
486 switch ( cmbDpiMode->currentIndex() )
505 settings.
setValue( wmsKey +
"/dpiMode", dpiMode );
507 settings.
setValue( wmsKey +
"/referer", mRefererLineEdit->text() );
511 settings.
setValue( wmsKey +
"/ignoreGetFeatureInfoURI", cbxIgnoreGetFeatureInfoURI->isChecked() );
515 QString version = QStringLiteral(
"auto" );
516 switch ( cmbVersion->currentIndex() )
519 version = QStringLiteral(
"auto" );
522 version = QStringLiteral(
"1.0.0" );
525 version = QStringLiteral(
"1.1.0" );
528 version = QStringLiteral(
"2.0.0" );
531 version = QStringLiteral(
"OGC_API_FEATURES" );
534 settings.
setValue( wfsKey +
"/version", version );
536 settings.
setValue( wfsKey +
"/maxnumfeatures", txtMaxNumFeatures->text() );
538 settings.
setValue( wfsKey +
"/pagesize", txtPageSize->text() );
539 settings.
setValue( wfsKey +
"/pagingenabled", cbxWfsFeaturePaging->isChecked() );
542 settings.
setValue( credentialsKey +
"/username", mAuthSettings->username() );
543 settings.
setValue( credentialsKey +
"/password", mAuthSettings->password() );
545 settings.
setValue( credentialsKey +
"/authcfg", mAuthSettings->configId() );
547 if ( mHttpGroupBox->isVisible() )
548 settings.
setValue( key +
"/referer", mRefererLineEdit->text() );
550 settings.
setValue( mBaseKey +
"/selected", txtName->text() );
555 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