QGIS API Documentation  3.10.0-A Coruña (6c816b4204)
qgsnewhttpconnection.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsnewhttpconnection.cpp - selector for a new HTTP server for WMS, etc.
3  -------------------
4  begin : 3 April 2005
5  copyright : (C) 2005 by Brendan Morley
6  email : morb at ozemail dot com dot au
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 #include "qgsnewhttpconnection.h"
18 #include "qgsauthsettingswidget.h"
19 #include "qgssettings.h"
20 #include "qgshelp.h"
21 #include "qgsgui.h"
22 
23 #include <QMessageBox>
24 #include <QUrl>
25 #include <QPushButton>
26 #include <QRegExp>
27 #include <QRegExpValidator>
28 
29 QgsNewHttpConnection::QgsNewHttpConnection( QWidget *parent, ConnectionTypes types, const QString &baseKey, const QString &connectionName, QgsNewHttpConnection::Flags flags, Qt::WindowFlags fl )
30  : QDialog( parent, fl )
31  , mTypes( types )
32  , mBaseKey( baseKey )
33  , mOriginalConnName( connectionName )
34 {
35  setupUi( this );
36 
37  if ( !( flags & FlagShowHttpSettings ) )
38  mHttpGroupBox->hide();
39 
41 
42  connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsNewHttpConnection::showHelp );
43 
44  QRegExp rx( "/connections-([^/]+)/" );
45  if ( rx.indexIn( baseKey ) != -1 )
46  {
47  QString connectionType( rx.cap( 1 ).toUpper() );
48  if ( connectionType == QLatin1String( "WMS" ) )
49  {
50  connectionType = QStringLiteral( "WMS/WMTS" );
51  }
52  setWindowTitle( tr( "Create a New %1 Connection" ).arg( connectionType ) );
53  }
54 
55  // It would be obviously much better to use mBaseKey also for credentials,
56  // but for some strange reason a different hardcoded key was used instead.
57  // WFS and WMS credentials were mixed with the same key WMS.
58  // Only WMS and WFS providers are using QgsNewHttpConnection at this moment
59  // using connection-wms and connection-wfs -> parse credential key from it.
60  mCredentialsBaseKey = mBaseKey.split( '-' ).last().toUpper();
61 
62  txtName->setValidator( new QRegExpValidator( QRegExp( "[^\\/]+" ), txtName ) );
63 
64  cmbDpiMode->clear();
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" ) );
70 
71  cmbVersion->clear();
72  cmbVersion->addItem( tr( "Maximum" ) );
73  cmbVersion->addItem( tr( "1.0" ) );
74  cmbVersion->addItem( tr( "1.1" ) );
75  cmbVersion->addItem( tr( "2.0" ) );
76  connect( cmbVersion,
77  static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ),
78  this, &QgsNewHttpConnection::wfsVersionCurrentIndexChanged );
79 
80  connect( cbxWfsFeaturePaging, &QCheckBox::stateChanged,
81  this, &QgsNewHttpConnection::wfsFeaturePagingStateChanged );
82 
83  if ( !connectionName.isEmpty() )
84  {
85  // populate the dialog with the information stored for the connection
86  // populate the fields with the stored setting parameters
87 
88  QgsSettings settings;
89 
90  QString key = mBaseKey + connectionName;
91  QString credentialsKey = "qgis/" + mCredentialsBaseKey + '/' + connectionName;
92  txtName->setText( connectionName );
93  txtUrl->setText( settings.value( key + "/url" ).toString() );
94  mRefererLineEdit->setText( settings.value( key + "/referer" ).toString() );
95 
97 
98  // Authentication
99  mAuthSettings->setUsername( settings.value( credentialsKey + "/username" ).toString() );
100  mAuthSettings->setPassword( settings.value( credentialsKey + "/password" ).toString() );
101  mAuthSettings->setConfigId( settings.value( credentialsKey + "/authcfg" ).toString() );
102  }
103  mWfsVersionDetectButton->setDisabled( txtUrl->text().isEmpty() );
104 
105  if ( !( mTypes & ConnectionWms ) && !( mTypes & ConnectionWcs ) )
106  {
107  mWmsOptionsGroupBox->setVisible( false );
108  mGroupBox->layout()->removeWidget( mWmsOptionsGroupBox );
109  }
110  if ( !( mTypes & ConnectionWfs ) )
111  {
112  mWfsOptionsGroupBox->setVisible( false );
113  mGroupBox->layout()->removeWidget( mWfsOptionsGroupBox );
114  }
115 
116  if ( mTypes & ConnectionWcs )
117  {
118  cbxIgnoreGetMapURI->setText( tr( "Ignore GetCoverage URI reported in capabilities" ) );
119  cbxWmsIgnoreAxisOrientation->setText( tr( "Ignore axis orientation" ) );
120  if ( !( mTypes & ConnectionWms ) )
121  {
122  mWmsOptionsGroupBox->setTitle( tr( "WCS Options" ) );
123 
124  cbxIgnoreGetFeatureInfoURI->setVisible( false );
125  mGroupBox->layout()->removeWidget( cbxIgnoreGetFeatureInfoURI );
126 
127  cmbDpiMode->setVisible( false );
128  mGroupBox->layout()->removeWidget( cmbDpiMode );
129  lblDpiMode->setVisible( false );
130  mGroupBox->layout()->removeWidget( lblDpiMode );
131 
132  txtReferer->setVisible( false );
133  mGroupBox->layout()->removeWidget( txtReferer );
134  lblReferer->setVisible( false );
135  mGroupBox->layout()->removeWidget( lblReferer );
136  }
137  }
138 
139 
140  if ( !( flags & FlagShowTestConnection ) )
141  {
142  mTestConnectionButton->hide();
143  mGroupBox->layout()->removeWidget( mTestConnectionButton );
144  }
145 
146  if ( flags & FlagHideAuthenticationGroup )
147  {
148  mAuthGroupBox->hide();
149  mGroupBox->layout()->removeWidget( mAuthGroupBox );
150  }
151  // Adjust height
152  int w = width();
153  adjustSize();
154  resize( w, height() );
155 
156  connect( txtName, &QLineEdit::textChanged, this, &QgsNewHttpConnection::nameChanged );
157  connect( txtUrl, &QLineEdit::textChanged, this, &QgsNewHttpConnection::urlChanged );
158 
159  buttonBox->button( QDialogButtonBox::Ok )->setDisabled( true );
160  connect( txtName, &QLineEdit::textChanged, this, &QgsNewHttpConnection::updateOkButtonState );
161  connect( txtUrl, &QLineEdit::textChanged, this, &QgsNewHttpConnection::updateOkButtonState );
162 
163  nameChanged( connectionName );
164 }
165 
166 void QgsNewHttpConnection::wfsVersionCurrentIndexChanged( int index )
167 {
168  // For now 2019-06-06, leave paging checkable for some WFS version 1.1 servers with support
169  cbxWfsFeaturePaging->setEnabled( index == 0 || index >= 2 );
170  lblPageSize->setEnabled( cbxWfsFeaturePaging->isChecked() && ( index == 0 || index >= 2 ) );
171  txtPageSize->setEnabled( cbxWfsFeaturePaging->isChecked() && ( index == 0 || index >= 2 ) );
172  cbxWfsIgnoreAxisOrientation->setEnabled( index != 1 );
173 }
174 
175 void QgsNewHttpConnection::wfsFeaturePagingStateChanged( int state )
176 {
177  lblPageSize->setEnabled( state == Qt::Checked );
178  txtPageSize->setEnabled( state == Qt::Checked );
179 }
180 
182 {
183  return txtName->text();
184 }
185 
187 {
188  return txtUrl->text();
189 }
190 
191 void QgsNewHttpConnection::nameChanged( const QString &text )
192 {
193  Q_UNUSED( text )
194  buttonBox->button( QDialogButtonBox::Ok )->setDisabled( txtName->text().isEmpty() || txtUrl->text().isEmpty() );
195 }
196 
197 void QgsNewHttpConnection::urlChanged( const QString &text )
198 {
199  Q_UNUSED( text )
200  buttonBox->button( QDialogButtonBox::Ok )->setDisabled( txtName->text().isEmpty() || txtUrl->text().isEmpty() );
201  mWfsVersionDetectButton->setDisabled( txtUrl->text().isEmpty() );
202 }
203 
204 void QgsNewHttpConnection::updateOkButtonState()
205 {
206  bool enabled = !txtName->text().isEmpty() && !txtUrl->text().isEmpty();
207  buttonBox->button( QDialogButtonBox::Ok )->setEnabled( enabled );
208 }
209 
211 {
212  QgsSettings settings;
213  QString key = mBaseKey + txtName->text();
214 
215  // warn if entry was renamed to an existing connection
216  if ( ( mOriginalConnName.isNull() || mOriginalConnName.compare( txtName->text(), Qt::CaseInsensitive ) != 0 ) &&
217  settings.contains( key + "/url" ) &&
218  QMessageBox::question( this,
219  tr( "Save Connection" ),
220  tr( "Should the existing connection %1 be overwritten?" ).arg( txtName->text() ),
221  QMessageBox::Ok | QMessageBox::Cancel ) == QMessageBox::Cancel )
222  {
223  return false;
224  }
225 
226  if ( ! mAuthSettings->password().isEmpty() &&
227  QMessageBox::question( this,
228  tr( "Saving Passwords" ),
229  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." ),
230  QMessageBox::Ok | QMessageBox::Cancel ) == QMessageBox::Cancel )
231  {
232  return false;
233  }
234 
235  return true;
236 }
237 
239 {
240  return mTestConnectionButton;
241 }
242 
244 {
245  return mAuthSettings;
246 }
247 
249 {
250  return mWfsVersionDetectButton;
251 }
252 
254 {
255  return cmbVersion;
256 }
257 
259 {
260  return cbxWfsFeaturePaging;
261 }
262 
264 {
265  return txtPageSize;
266 }
267 
268 QString QgsNewHttpConnection::wfsSettingsKey( const QString &base, const QString &connectionName ) const
269 {
270  return base + connectionName;
271 }
272 
273 QString QgsNewHttpConnection::wmsSettingsKey( const QString &base, const QString &connectionName ) const
274 {
275  return base + connectionName;
276 }
277 
279 {
280  QgsSettings settings;
281  QString wfsKey = wfsSettingsKey( mBaseKey, mOriginalConnName );
282  QString wmsKey = wmsSettingsKey( mBaseKey, mOriginalConnName );
283 
284  cbxIgnoreGetMapURI->setChecked( settings.value( wmsKey + "/ignoreGetMapURI", false ).toBool() );
285  cbxWmsIgnoreReportedLayerExtents->setChecked( settings.value( wmsKey + QStringLiteral( "/ignoreReportedLayerExtents" ), false ).toBool() );
286  cbxWfsIgnoreAxisOrientation->setChecked( settings.value( wfsKey + "/ignoreAxisOrientation", false ).toBool() );
287  cbxWfsInvertAxisOrientation->setChecked( settings.value( wfsKey + "/invertAxisOrientation", false ).toBool() );
288  cbxWmsIgnoreAxisOrientation->setChecked( settings.value( wmsKey + "/ignoreAxisOrientation", false ).toBool() );
289  cbxWmsInvertAxisOrientation->setChecked( settings.value( wmsKey + "/invertAxisOrientation", false ).toBool() );
290  cbxIgnoreGetFeatureInfoURI->setChecked( settings.value( wmsKey + "/ignoreGetFeatureInfoURI", false ).toBool() );
291  cbxSmoothPixmapTransform->setChecked( settings.value( wmsKey + "/smoothPixmapTransform", false ).toBool() );
292 
293  int dpiIdx;
294  switch ( settings.value( wmsKey + "/dpiMode", 7 ).toInt() )
295  {
296  case 0: // off
297  dpiIdx = 1;
298  break;
299  case 1: // QGIS
300  dpiIdx = 2;
301  break;
302  case 2: // UMN
303  dpiIdx = 3;
304  break;
305  case 4: // GeoServer
306  dpiIdx = 4;
307  break;
308  default: // other => all
309  dpiIdx = 0;
310  break;
311  }
312  cmbDpiMode->setCurrentIndex( dpiIdx );
313 
314  QString version = settings.value( wfsKey + "/version" ).toString();
315  int versionIdx = 0; // AUTO
316  if ( version == QLatin1String( "1.0.0" ) )
317  versionIdx = 1;
318  else if ( version == QLatin1String( "1.1.0" ) )
319  versionIdx = 2;
320  else if ( version == QLatin1String( "2.0.0" ) )
321  versionIdx = 3;
322  cmbVersion->setCurrentIndex( versionIdx );
323 
324  txtReferer->setText( settings.value( wmsKey + "/referer" ).toString() );
325  txtMaxNumFeatures->setText( settings.value( wfsKey + "/maxnumfeatures" ).toString() );
326 
327  // Only default to paging enabled if WFS 2.0.0 or higher
328  bool pagingEnabled = settings.value( wfsKey + "/pagingenabled", ( versionIdx == 0 || versionIdx >= 3 ) ).toBool();
329  txtPageSize->setText( settings.value( wfsKey + "/pagesize" ).toString() );
330  cbxWfsFeaturePaging->setChecked( pagingEnabled );
331 
332  // Enable/disable these items per WFS versions
333  // For now 2019-06-06, leave paging checkable for some WFS version 1.1 servers with support
334  txtPageSize->setEnabled( pagingEnabled && ( versionIdx == 0 || versionIdx >= 2 ) );
335  lblPageSize->setEnabled( pagingEnabled && ( versionIdx == 0 || versionIdx >= 2 ) );
336  cbxWfsFeaturePaging->setEnabled( versionIdx == 0 || versionIdx >= 2 );
337  cbxWfsIgnoreAxisOrientation->setEnabled( versionIdx != 1 );
338 }
339 
341 {
342 
343  QUrl url( txtUrl->text().trimmed() );
344  const QList< QPair<QByteArray, QByteArray> > &items = url.encodedQueryItems();
345  QHash< QString, QPair<QByteArray, QByteArray> > params;
346  for ( QList< QPair<QByteArray, QByteArray> >::const_iterator it = items.constBegin(); it != items.constEnd(); ++it )
347  {
348  params.insert( QString( it->first ).toUpper(), *it );
349  }
350 
351  if ( params[QStringLiteral( "SERVICE" )].second.toUpper() == "WMS" ||
352  params[QStringLiteral( "SERVICE" )].second.toUpper() == "WFS" ||
353  params[QStringLiteral( "SERVICE" )].second.toUpper() == "WCS" )
354  {
355  url.removeEncodedQueryItem( params[QStringLiteral( "SERVICE" )].first );
356  url.removeEncodedQueryItem( params[QStringLiteral( "REQUEST" )].first );
357  url.removeEncodedQueryItem( params[QStringLiteral( "FORMAT" )].first );
358  }
359 
360  if ( url.encodedPath().isEmpty() )
361  {
362  url.setEncodedPath( "/" );
363  }
364  return url;
365 }
366 
368 {
369  QgsSettings settings;
370  QString key = mBaseKey + txtName->text();
371  QString credentialsKey = "qgis/" + mCredentialsBaseKey + '/' + txtName->text();
372 
373  if ( !validate() )
374  return;
375 
376  // on rename delete original entry first
377  if ( !mOriginalConnName.isNull() && mOriginalConnName != key )
378  {
379  settings.remove( mBaseKey + mOriginalConnName );
380  settings.remove( "qgis/" + mCredentialsBaseKey + '/' + mOriginalConnName );
381  settings.sync();
382  }
383 
384  QUrl url( urlTrimmed() );
385  settings.setValue( key + "/url", url.toString() );
386 
387  QString wfsKey = wfsSettingsKey( mBaseKey, txtName->text() );
388  QString wmsKey = wmsSettingsKey( mBaseKey, txtName->text() );
389 
390  if ( mTypes & ConnectionWfs )
391  {
392  settings.setValue( wfsKey + "/ignoreAxisOrientation", cbxWfsIgnoreAxisOrientation->isChecked() );
393  settings.setValue( wfsKey + "/invertAxisOrientation", cbxWfsInvertAxisOrientation->isChecked() );
394  }
395  if ( mTypes & ConnectionWms || mTypes & ConnectionWcs )
396  {
397  settings.setValue( wmsKey + "/ignoreAxisOrientation", cbxWmsIgnoreAxisOrientation->isChecked() );
398  settings.setValue( wmsKey + "/invertAxisOrientation", cbxWmsInvertAxisOrientation->isChecked() );
399 
400  settings.setValue( wmsKey + QStringLiteral( "/ignoreReportedLayerExtents" ), cbxWmsIgnoreReportedLayerExtents->isChecked() );
401  settings.setValue( wmsKey + "/ignoreGetMapURI", cbxIgnoreGetMapURI->isChecked() );
402  settings.setValue( wmsKey + "/smoothPixmapTransform", cbxSmoothPixmapTransform->isChecked() );
403 
404  int dpiMode = 0;
405  switch ( cmbDpiMode->currentIndex() )
406  {
407  case 0: // all => QGIS|UMN|GeoServer
408  dpiMode = 7;
409  break;
410  case 1: // off
411  dpiMode = 0;
412  break;
413  case 2: // QGIS
414  dpiMode = 1;
415  break;
416  case 3: // UMN
417  dpiMode = 2;
418  break;
419  case 4: // GeoServer
420  dpiMode = 4;
421  break;
422  }
423 
424  settings.setValue( wmsKey + "/dpiMode", dpiMode );
425 
426  settings.setValue( wmsKey + "/referer", txtReferer->text() );
427  }
428  if ( mTypes & ConnectionWms )
429  {
430  settings.setValue( wmsKey + "/ignoreGetFeatureInfoURI", cbxIgnoreGetFeatureInfoURI->isChecked() );
431  }
432  if ( mTypes & ConnectionWfs )
433  {
434  QString version = QStringLiteral( "auto" );
435  switch ( cmbVersion->currentIndex() )
436  {
437  case 0:
438  version = QStringLiteral( "auto" );
439  break;
440  case 1:
441  version = QStringLiteral( "1.0.0" );
442  break;
443  case 2:
444  version = QStringLiteral( "1.1.0" );
445  break;
446  case 3:
447  version = QStringLiteral( "2.0.0" );
448  break;
449  }
450  settings.setValue( wfsKey + "/version", version );
451 
452  settings.setValue( wfsKey + "/maxnumfeatures", txtMaxNumFeatures->text() );
453 
454  settings.setValue( wfsKey + "/pagesize", txtPageSize->text() );
455  settings.setValue( wfsKey + "/pagingenabled", cbxWfsFeaturePaging->isChecked() );
456  }
457 
458  settings.setValue( credentialsKey + "/username", mAuthSettings->username() );
459  settings.setValue( credentialsKey + "/password", mAuthSettings->password() );
460 
461  settings.setValue( credentialsKey + "/authcfg", mAuthSettings->configId() );
462 
463  if ( mHttpGroupBox->isVisible() )
464  settings.setValue( key + "/referer", mRefererLineEdit->text() );
465 
466  settings.setValue( mBaseKey + "/selected", txtName->text() );
467 
468  QDialog::accept();
469 }
470 
471 void QgsNewHttpConnection::showHelp()
472 {
473  QgsHelp::openHelp( QStringLiteral( "working_with_ogc/index.html" ) );
474 }
Display the &#39;http&#39; group.
This class is a composition of two QSettings instances:
Definition: qgssettings.h:58
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
void remove(const QString &key, QgsSettings::Section section=QgsSettings::NoSection)
Removes the setting key and any sub-settings of key in a section.
Widget for entering authentication credentials both in the form username/password and by using QGIS A...
void sync()
Writes any unsaved changes to permanent storage, and reloads any settings that have been changed in t...
void updateServiceSpecificSettings()
Triggers a resync of the GUI widgets for the service specific settings (i.e.
QString url() const
Returns the current connection url.
virtual QString wmsSettingsKey(const QString &base, const QString &connectionName) const
Returns the QSettings key for WMS related settings for the connection.
QString name() const
Returns the current connection name.
QComboBox * wfsVersionComboBox()
Returns the "WFS version" combobox.
QUrl urlTrimmed() const
Returns the url.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
virtual QString wfsSettingsKey(const QString &base, const QString &connectionName) const
Returns the QSettings key for WFS related settings for the connection.
QPushButton * testConnectButton()
Returns the "test connection" button.
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...
Definition: qgsgui.cpp:127
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition: qgshelp.cpp:36
bool contains(const QString &key, QgsSettings::Section section=QgsSettings::NoSection) const
Returns true if there exists a setting called key; returns false otherwise.
QCheckBox * wfsPagingEnabledCheckBox()
Returns the "WFS paging enabled" checkbox.
QgsNewHttpConnection(QWidget *parent=nullptr, QgsNewHttpConnection::ConnectionTypes types=ConnectionWms, const QString &baseKey="qgis/connections-wms/", const QString &connectionName=QString(), QgsNewHttpConnection::Flags flags=nullptr, Qt::WindowFlags fl=QgsGuiUtils::ModalDialogFlags)
Constructor for QgsNewHttpConnection.
QLineEdit * wfsPageSizeLineEdit()
Returns the "WFS page size" edit.
QPushButton * wfsVersionDetectButton()
Returns the "WFS version detect" button.
Display the &#39;test connection&#39; button.
QgsAuthSettingsWidget * authSettingsWidget()
Returns the current authentication settings widget.
virtual bool validate()
Returns true if dialog settings are valid, or false if current settings are not valid and the dialog ...