QGIS API Documentation  2.99.0-Master (f1c3692)
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 
22 #include <QMessageBox>
23 #include <QUrl>
24 #include <QPushButton>
25 #include <QRegExp>
26 #include <QRegExpValidator>
27 
28 QgsNewHttpConnection::QgsNewHttpConnection( QWidget *parent, ConnectionTypes types, const QString &baseKey, const QString &connectionName, QgsNewHttpConnection::Flags flags, Qt::WindowFlags fl )
29  : QDialog( parent, fl )
30  , mTypes( types )
31  , mBaseKey( baseKey )
32  , mOriginalConnName( connectionName )
33 {
34  setupUi( this );
35  connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsNewHttpConnection::showHelp );
36 
37  QRegExp rx( "/connections-([^/]+)/" );
38  if ( rx.indexIn( baseKey ) != -1 )
39  setWindowTitle( tr( "Create a New %1 Connection" ).arg( rx.cap( 1 ).toUpper() ) );
40 
41  // It would be obviously much better to use mBaseKey also for credentials,
42  // but for some strange reason a different hardcoded key was used instead.
43  // WFS and WMS credentials were mixed with the same key WMS.
44  // Only WMS and WFS providers are using QgsNewHttpConnection at this moment
45  // using connection-wms and connection-wfs -> parse credential key fro it.
46  mCredentialsBaseKey = mBaseKey.split( '-' ).last().toUpper();
47 
48  txtName->setValidator( new QRegExpValidator( QRegExp( "[^\\/]+" ), txtName ) );
49 
50  cmbDpiMode->clear();
51  cmbDpiMode->addItem( tr( "all" ) );
52  cmbDpiMode->addItem( tr( "off" ) );
53  cmbDpiMode->addItem( tr( "QGIS" ) );
54  cmbDpiMode->addItem( tr( "UMN" ) );
55  cmbDpiMode->addItem( tr( "GeoServer" ) );
56 
57  cmbVersion->clear();
58  cmbVersion->addItem( tr( "Auto-detect" ) );
59  cmbVersion->addItem( tr( "1.0" ) );
60  cmbVersion->addItem( tr( "1.1" ) );
61  cmbVersion->addItem( tr( "2.0" ) );
62 
63  if ( !connectionName.isEmpty() )
64  {
65  // populate the dialog with the information stored for the connection
66  // populate the fields with the stored setting parameters
67 
68  QgsSettings settings;
69 
70  QString key = mBaseKey + connectionName;
71  QString credentialsKey = "qgis/" + mCredentialsBaseKey + '/' + connectionName;
72  txtName->setText( connectionName );
73  txtUrl->setText( settings.value( key + "/url" ).toString() );
74 
76 
77  // Authentication
78  mAuthSettings->setUsername( settings.value( credentialsKey + "/username" ).toString() );
79  mAuthSettings->setPassword( settings.value( credentialsKey + "/password" ).toString() );
80  mAuthSettings->setConfigId( settings.value( credentialsKey + "/authcfg" ).toString() );
81  }
82 
83  if ( !( mTypes & ConnectionWms ) && !( mTypes & ConnectionWcs ) )
84  {
85  mWmsOptionsGroupBox->setVisible( false );
86  mGroupBox->layout()->removeWidget( mWmsOptionsGroupBox );
87  }
88  if ( !( mTypes & ConnectionWfs ) )
89  {
90  mWfsOptionsGroupBox->setVisible( false );
91  mGroupBox->layout()->removeWidget( mWfsOptionsGroupBox );
92  }
93 
94  if ( mTypes & ConnectionWcs )
95  {
96  cbxIgnoreGetMapURI->setText( tr( "Ignore GetCoverage URI reported in capabilities" ) );
97  cbxWmsIgnoreAxisOrientation->setText( tr( "Ignore axis orientation" ) );
98  if ( !( mTypes & ConnectionWms ) )
99  {
100  mWmsOptionsGroupBox->setTitle( tr( "WCS Options" ) );
101 
102  cbxIgnoreGetFeatureInfoURI->setVisible( false );
103  mGroupBox->layout()->removeWidget( cbxIgnoreGetFeatureInfoURI );
104 
105  cmbDpiMode->setVisible( false );
106  mGroupBox->layout()->removeWidget( cmbDpiMode );
107  lblDpiMode->setVisible( false );
108  mGroupBox->layout()->removeWidget( lblDpiMode );
109 
110  txtReferer->setVisible( false );
111  mGroupBox->layout()->removeWidget( txtReferer );
112  lblReferer->setVisible( false );
113  mGroupBox->layout()->removeWidget( lblReferer );
114  }
115  }
116 
117 
118  if ( !( flags & FlagShowTestConnection ) )
119  {
120  mTestConnectionButton->hide();
121  mGroupBox->layout()->removeWidget( mTestConnectionButton );
122  }
123 
124  if ( flags & FlagHideAuthenticationGroup )
125  {
126  mAuthGroupBox->hide();
127  mGroupBox->layout()->removeWidget( mAuthGroupBox );
128  }
129  // Adjust height
130  int w = width();
131  adjustSize();
132  resize( w, height() );
133 
134  connect( txtName, &QLineEdit::textChanged, this, &QgsNewHttpConnection::nameChanged );
135  connect( txtUrl, &QLineEdit::textChanged, this, &QgsNewHttpConnection::urlChanged );
136 
137  buttonBox->button( QDialogButtonBox::Ok )->setDisabled( true );
138  connect( txtName, &QLineEdit::textChanged, this, &QgsNewHttpConnection::updateOkButtonState );
139  connect( txtUrl, &QLineEdit::textChanged, this, &QgsNewHttpConnection::updateOkButtonState );
140 
141  nameChanged( connectionName );
142 }
143 
145 {
146  return txtName->text();
147 }
148 
150 {
151  return txtUrl->text();
152 }
153 
154 void QgsNewHttpConnection::nameChanged( const QString &text )
155 {
156  Q_UNUSED( text );
157  buttonBox->button( QDialogButtonBox::Ok )->setDisabled( txtName->text().isEmpty() || txtUrl->text().isEmpty() );
158 }
159 
160 void QgsNewHttpConnection::urlChanged( const QString &text )
161 {
162  Q_UNUSED( text );
163  buttonBox->button( QDialogButtonBox::Ok )->setDisabled( txtName->text().isEmpty() || txtUrl->text().isEmpty() );
164 }
165 
166 void QgsNewHttpConnection::updateOkButtonState()
167 {
168  bool enabled = !txtName->text().isEmpty() && !txtUrl->text().isEmpty();
169  buttonBox->button( QDialogButtonBox::Ok )->setEnabled( enabled );
170 }
171 
173 {
174  QgsSettings settings;
175  QString key = mBaseKey + txtName->text();
176 
177  // warn if entry was renamed to an existing connection
178  if ( ( mOriginalConnName.isNull() || mOriginalConnName.compare( txtName->text(), Qt::CaseInsensitive ) != 0 ) &&
179  settings.contains( key + "/url" ) &&
180  QMessageBox::question( this,
181  tr( "Save Connection" ),
182  tr( "Should the existing connection %1 be overwritten?" ).arg( txtName->text() ),
183  QMessageBox::Ok | QMessageBox::Cancel ) == QMessageBox::Cancel )
184  {
185  return false;
186  }
187 
188  if ( ! mAuthSettings->password().isEmpty() &&
189  QMessageBox::question( this,
190  tr( "Saving Passwords" ),
191  trUtf8( "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." ),
192  QMessageBox::Ok | QMessageBox::Cancel ) == QMessageBox::Cancel )
193  {
194  return false;
195  }
196 
197  return true;
198 }
199 
201 {
202  return mTestConnectionButton;
203 }
204 
205 QString QgsNewHttpConnection::wfsSettingsKey( const QString &base, const QString &connectionName ) const
206 {
207  return base + connectionName;
208 }
209 
210 QString QgsNewHttpConnection::wmsSettingsKey( const QString &base, const QString &connectionName ) const
211 {
212  return base + connectionName;
213 }
214 
216 {
217  QgsSettings settings;
218  QString wfsKey = wfsSettingsKey( mBaseKey, mOriginalConnName );
219  QString wmsKey = wmsSettingsKey( mBaseKey, mOriginalConnName );
220 
221  cbxIgnoreGetMapURI->setChecked( settings.value( wmsKey + "/ignoreGetMapURI", false ).toBool() );
222  cbxWfsIgnoreAxisOrientation->setChecked( settings.value( wfsKey + "/ignoreAxisOrientation", false ).toBool() );
223  cbxWfsInvertAxisOrientation->setChecked( settings.value( wfsKey + "/invertAxisOrientation", false ).toBool() );
224  cbxWmsIgnoreAxisOrientation->setChecked( settings.value( wmsKey + "/ignoreAxisOrientation", false ).toBool() );
225  cbxWmsInvertAxisOrientation->setChecked( settings.value( wmsKey + "/invertAxisOrientation", false ).toBool() );
226  cbxIgnoreGetFeatureInfoURI->setChecked( settings.value( wmsKey + "/ignoreGetFeatureInfoURI", false ).toBool() );
227  cbxSmoothPixmapTransform->setChecked( settings.value( wmsKey + "/smoothPixmapTransform", false ).toBool() );
228 
229  int dpiIdx;
230  switch ( settings.value( wmsKey + "/dpiMode", 7 ).toInt() )
231  {
232  case 0: // off
233  dpiIdx = 1;
234  break;
235  case 1: // QGIS
236  dpiIdx = 2;
237  break;
238  case 2: // UMN
239  dpiIdx = 3;
240  break;
241  case 4: // GeoServer
242  dpiIdx = 4;
243  break;
244  default: // other => all
245  dpiIdx = 0;
246  break;
247  }
248  cmbDpiMode->setCurrentIndex( dpiIdx );
249 
250  QString version = settings.value( wfsKey + "/version" ).toString();
251  int versionIdx = 0; // AUTO
252  if ( version == QLatin1String( "1.0.0" ) )
253  versionIdx = 1;
254  else if ( version == QLatin1String( "1.1.0" ) )
255  versionIdx = 2;
256  else if ( version == QLatin1String( "2.0.0" ) )
257  versionIdx = 3;
258  cmbVersion->setCurrentIndex( versionIdx );
259 
260  txtReferer->setText( settings.value( wmsKey + "/referer" ).toString() );
261  txtMaxNumFeatures->setText( settings.value( wfsKey + "/maxnumfeatures" ).toString() );
262 }
263 
265 {
266  QgsSettings settings;
267  QString key = mBaseKey + txtName->text();
268  QString credentialsKey = "qgis/" + mCredentialsBaseKey + '/' + txtName->text();
269 
270  if ( !validate() )
271  return;
272 
273  // on rename delete original entry first
274  if ( !mOriginalConnName.isNull() && mOriginalConnName != key )
275  {
276  settings.remove( mBaseKey + mOriginalConnName );
277  settings.remove( "qgis/" + mCredentialsBaseKey + '/' + mOriginalConnName );
278  settings.sync();
279  }
280 
281  QUrl url( txtUrl->text().trimmed() );
282  const QList< QPair<QByteArray, QByteArray> > &items = url.encodedQueryItems();
283  QHash< QString, QPair<QByteArray, QByteArray> > params;
284  for ( QList< QPair<QByteArray, QByteArray> >::const_iterator it = items.constBegin(); it != items.constEnd(); ++it )
285  {
286  params.insert( QString( it->first ).toUpper(), *it );
287  }
288 
289  if ( params[QStringLiteral( "SERVICE" )].second.toUpper() == "WMS" ||
290  params[QStringLiteral( "SERVICE" )].second.toUpper() == "WFS" ||
291  params[QStringLiteral( "SERVICE" )].second.toUpper() == "WCS" )
292  {
293  url.removeEncodedQueryItem( params[QStringLiteral( "SERVICE" )].first );
294  url.removeEncodedQueryItem( params[QStringLiteral( "REQUEST" )].first );
295  url.removeEncodedQueryItem( params[QStringLiteral( "FORMAT" )].first );
296  }
297 
298  if ( url.encodedPath().isEmpty() )
299  {
300  url.setEncodedPath( "/" );
301  }
302 
303  settings.setValue( key + "/url", url.toString() );
304 
305  QString wfsKey = wfsSettingsKey( mBaseKey, txtName->text() );
306  QString wmsKey = wmsSettingsKey( mBaseKey, txtName->text() );
307 
308  if ( mTypes & ConnectionWfs )
309  {
310  settings.setValue( wfsKey + "/ignoreAxisOrientation", cbxWfsIgnoreAxisOrientation->isChecked() );
311  settings.setValue( wfsKey + "/invertAxisOrientation", cbxWfsInvertAxisOrientation->isChecked() );
312  }
313  if ( mTypes & ConnectionWms || mTypes & ConnectionWcs )
314  {
315  settings.setValue( wmsKey + "/ignoreAxisOrientation", cbxWmsIgnoreAxisOrientation->isChecked() );
316  settings.setValue( wmsKey + "/invertAxisOrientation", cbxWmsInvertAxisOrientation->isChecked() );
317 
318  settings.setValue( wmsKey + "/ignoreGetMapURI", cbxIgnoreGetMapURI->isChecked() );
319  settings.setValue( wmsKey + "/smoothPixmapTransform", cbxSmoothPixmapTransform->isChecked() );
320 
321  int dpiMode = 0;
322  switch ( cmbDpiMode->currentIndex() )
323  {
324  case 0: // all => QGIS|UMN|GeoServer
325  dpiMode = 7;
326  break;
327  case 1: // off
328  dpiMode = 0;
329  break;
330  case 2: // QGIS
331  dpiMode = 1;
332  break;
333  case 3: // UMN
334  dpiMode = 2;
335  break;
336  case 4: // GeoServer
337  dpiMode = 4;
338  break;
339  }
340 
341  settings.setValue( wmsKey + "/dpiMode", dpiMode );
342 
343  settings.setValue( wmsKey + "/referer", txtReferer->text() );
344  }
345  if ( mTypes & ConnectionWms )
346  {
347  settings.setValue( wmsKey + "/ignoreGetFeatureInfoURI", cbxIgnoreGetFeatureInfoURI->isChecked() );
348  }
349  if ( mTypes & ConnectionWfs )
350  {
351  QString version = QStringLiteral( "auto" );
352  switch ( cmbVersion->currentIndex() )
353  {
354  case 0:
355  version = QStringLiteral( "auto" );
356  break;
357  case 1:
358  version = QStringLiteral( "1.0.0" );
359  break;
360  case 2:
361  version = QStringLiteral( "1.1.0" );
362  break;
363  case 3:
364  version = QStringLiteral( "2.0.0" );
365  break;
366  }
367  settings.setValue( wfsKey + "/version", version );
368 
369  settings.setValue( wfsKey + "/maxnumfeatures", txtMaxNumFeatures->text() );
370  }
371 
372  settings.setValue( credentialsKey + "/username", mAuthSettings->username() );
373  settings.setValue( credentialsKey + "/password", mAuthSettings->password() );
374 
375  settings.setValue( credentialsKey + "/authcfg", mAuthSettings->configId() );
376 
377  settings.setValue( mBaseKey + "/selected", txtName->text() );
378 
379  QDialog::accept();
380 }
381 
382 void QgsNewHttpConnection::showHelp()
383 {
384  QgsHelp::openHelp( QStringLiteral( "working_with_ogc/index.html" ) );
385 }
void remove(const QString &key, const QgsSettings::Section section=QgsSettings::NoSection)
Removes the setting key and any sub-settings of key in a section.
This class is a composition of two QSettings instances:
Definition: qgssettings.h:55
bool contains(const QString &key, const QgsSettings::Section section=QgsSettings::NoSection) const
Returns true if there exists a setting called key; returns false otherwise.
QgsNewHttpConnection(QWidget *parent=nullptr, QgsNewHttpConnection::ConnectionTypes types=ConnectionWms, const QString &baseKey="qgis/connections-wms/", const QString &connectionName=QString(), QgsNewHttpConnection::Flags flags=0, Qt::WindowFlags fl=QgsGuiUtils::ModalDialogFlags)
Constructor for QgsNewHttpConnection.
void sync()
Writes any unsaved changes to permanent storage, and reloads any settings that have been changed in t...
void setValue(const QString &key, const QVariant &value, const QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
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.
virtual QString wfsSettingsKey(const QString &base, const QString &connectionName) const
Returns the QSettings key for WFS related settings for the connection.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), const Section section=NoSection) const
Returns the value for setting key.
QPushButton * testConnectButton()
Returns the "test connection" button.
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition: qgshelp.cpp:34
Display the &#39;test connection&#39; button.
virtual bool validate()
Returns true if dialog settings are valid, or false if current settings are not valid and the dialog ...