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()