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