QGIS API Documentation  3.10.0-A Coruña (6c816b4204)
qgsowssourceselect.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsowssourceselect.cpp - selector for WMS,WFS,WCS
3  -------------------
4  begin : 3 April 2005
5  copyright :
6  original : (C) 2005 by Brendan Morley email : morb at ozemail dot com dot au
7  wms search : (C) 2009 Mathias Walker <mwa at sourcepole.ch>, Sourcepole AG
8  wms-c support : (C) 2010 Juergen E. Fischer < jef at norbit dot de >, norBIT GmbH
9 
10  generalized : (C) 2012 Radim Blazek, based on qgswmssourceselect.cpp
11 
12  ***************************************************************************/
13 
14 /***************************************************************************
15  * *
16  * This program is free software; you can redistribute it and/or modify *
17  * it under the terms of the GNU General Public License as published by *
18  * the Free Software Foundation; either version 2 of the License, or *
19  * (at your option) any later version. *
20  * *
21  ***************************************************************************/
22 
23 #include "qgis.h" // GEO_EPSG_CRS_ID
25 #include "qgsdatasourceuri.h"
27 #include "qgslogger.h"
29 #include "qgsmessageviewer.h"
30 #include "qgsnewhttpconnection.h"
31 #include "qgstreewidgetitem.h"
32 #include "qgsproject.h"
33 #include "qgsproviderregistry.h"
34 #include "qgsowsconnection.h"
35 #include "qgsdataprovider.h"
36 #include "qgsowssourceselect.h"
38 #include "qgsapplication.h"
39 #include "qgssettings.h"
40 #include "qgsgui.h"
41 
42 #include <QButtonGroup>
43 #include <QFileDialog>
44 #include <QRadioButton>
45 #include <QDomDocument>
46 #include <QHeaderView>
47 #include <QImageReader>
48 #include <QInputDialog>
49 #include <QMap>
50 #include <QMessageBox>
51 #include <QPicture>
52 #include <QUrl>
53 #include <QValidator>
54 #include <QNetworkRequest>
55 #include <QNetworkReply>
56 
57 QgsOWSSourceSelect::QgsOWSSourceSelect( const QString &service, QWidget *parent, Qt::WindowFlags fl, QgsProviderRegistry::WidgetMode theWidgetMode )
58  : QgsAbstractDataSourceWidget( parent, fl, theWidgetMode )
59  , mService( service )
60 
61 {
62  setupUi( this );
64  connect( mNewButton, &QPushButton::clicked, this, &QgsOWSSourceSelect::mNewButton_clicked );
65  connect( mEditButton, &QPushButton::clicked, this, &QgsOWSSourceSelect::mEditButton_clicked );
66  connect( mDeleteButton, &QPushButton::clicked, this, &QgsOWSSourceSelect::mDeleteButton_clicked );
67  connect( mSaveButton, &QPushButton::clicked, this, &QgsOWSSourceSelect::mSaveButton_clicked );
68  connect( mLoadButton, &QPushButton::clicked, this, &QgsOWSSourceSelect::mLoadButton_clicked );
69  connect( mConnectButton, &QPushButton::clicked, this, &QgsOWSSourceSelect::mConnectButton_clicked );
70  connect( mChangeCRSButton, &QPushButton::clicked, this, &QgsOWSSourceSelect::mChangeCRSButton_clicked );
71  connect( mLayersTreeWidget, &QTreeWidget::itemSelectionChanged, this, &QgsOWSSourceSelect::mLayersTreeWidget_itemSelectionChanged );
72  connect( mConnectionsComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::activated ), this, &QgsOWSSourceSelect::mConnectionsComboBox_activated );
73  connect( mAddDefaultButton, &QPushButton::clicked, this, &QgsOWSSourceSelect::mAddDefaultButton_clicked );
74  connect( mSearchButton, &QPushButton::clicked, this, &QgsOWSSourceSelect::mSearchButton_clicked );
75  connect( mSearchTableWidget, &QTableWidget::itemSelectionChanged, this, &QgsOWSSourceSelect::mSearchTableWidget_itemSelectionChanged );
76  connect( mTilesetsTableWidget, &QTableWidget::itemClicked, this, &QgsOWSSourceSelect::mTilesetsTableWidget_itemClicked );
77  connect( mLayerUpButton, &QPushButton::clicked, this, &QgsOWSSourceSelect::mLayerUpButton_clicked );
78  connect( mLayerDownButton, &QPushButton::clicked, this, &QgsOWSSourceSelect::mLayerDownButton_clicked );
79  setupButtons( buttonBox );
80 
81 
82  setWindowTitle( tr( "Add Layer(s) from a %1 Server" ).arg( service ) );
83 
84  clearCrs();
85 
86  mTileWidthLineEdit->setValidator( new QIntValidator( 0, 9999, this ) );
87  mTileHeightLineEdit->setValidator( new QIntValidator( 0, 9999, this ) );
88  mFeatureCountLineEdit->setValidator( new QIntValidator( 0, 9999, this ) );
89 
90  mCacheComboBox->addItem( tr( "Always cache" ), QNetworkRequest::AlwaysCache );
91  mCacheComboBox->addItem( tr( "Prefer cache" ), QNetworkRequest::PreferCache );
92  mCacheComboBox->addItem( tr( "Prefer network" ), QNetworkRequest::PreferNetwork );
93  mCacheComboBox->addItem( tr( "Always network" ), QNetworkRequest::AlwaysNetwork );
94 
95  // 'Prefer network' is the default noted in the combobox's tool tip
96  mCacheComboBox->setCurrentIndex( mCacheComboBox->findData( QNetworkRequest::PreferNetwork ) );
97 
98  if ( widgetMode() != QgsProviderRegistry::WidgetMode::Manager )
99  {
100  //set the current project CRS if available
102  //convert CRS id to epsg
103  if ( currentRefSys.isValid() )
104  {
105  mSelectedCRS = currentRefSys.authid();
106  }
107  }
108  else
109  {
110  mTabWidget->removeTab( mTabWidget->indexOf( mLayerOrderTab ) );
111  mTabWidget->removeTab( mTabWidget->indexOf( mTilesetsTab ) );
112  mTimeWidget->hide();
113  mFormatWidget->hide();
114  mCRSWidget->hide();
115  mCacheWidget->hide();
116  }
117 
118  // set up the WMS connections we already know about
120 }
121 
123 {
125 }
126 
128 {
129  mLayersTreeWidget->clearSelection();
130 }
131 
133 {
134  mFormatComboBox->clear();
135  mFormatComboBox->setEnabled( false );
136 }
137 
139 {
140 
141  // A server may offer more similar formats, which are mapped
142  // to the same GDAL format, e.g. GeoTIFF and TIFF
143  // -> recreate always buttons for all available formats, enable supported
144 
145  clearFormats();
146 
147  if ( mProviderFormats.isEmpty() )
148  {
149  mProviderFormats = providerFormats();
150  for ( int i = 0; i < mProviderFormats.size(); i++ )
151  {
152  // GDAL mime types may be image/tiff, image/png, ...
153  mMimeLabelMap.insert( mProviderFormats[i].format, mProviderFormats[i].label );
154  }
155  }
156 
157  // selectedLayersFormats may come in various forms:
158  // image/tiff, GTiff, GeoTIFF, TIFF, geotiff_int16, geotiff_rgb,
159  // PNG, GTOPO30, ARCGRID, IMAGEMOSAIC
160  // and even any string defined in server configuration, for example the
161  // value used in UMN Mapserver for OUTPUTFORMAT->NAME is used in
162  // WCS 1.0.0 SupportedFormats/Format
163 
164  // TODO: It is impossible to cover all possible formats coming from server
165  // -> enabled all formats, GDAL may be able to open them
166 
167  QMap<QString, QString> formatsMap;
168  formatsMap.insert( QStringLiteral( "geotiff" ), QStringLiteral( "tiff" ) );
169  formatsMap.insert( QStringLiteral( "gtiff" ), QStringLiteral( "tiff" ) );
170  formatsMap.insert( QStringLiteral( "tiff" ), QStringLiteral( "tiff" ) );
171  formatsMap.insert( QStringLiteral( "tif" ), QStringLiteral( "tiff" ) );
172  formatsMap.insert( QStringLiteral( "gif" ), QStringLiteral( "gif" ) );
173  formatsMap.insert( QStringLiteral( "jpeg" ), QStringLiteral( "jpeg" ) );
174  formatsMap.insert( QStringLiteral( "jpg" ), QStringLiteral( "jpeg" ) );
175  formatsMap.insert( QStringLiteral( "png" ), QStringLiteral( "png" ) );
176 
177  int preferred = -1;
178  QStringList layersFormats = selectedLayersFormats();
179  for ( int i = 0; i < layersFormats.size(); i++ )
180  {
181  QString format = layersFormats.value( i );
182  QgsDebugMsg( "server format = " + format );
183  QString simpleFormat = format.toLower().remove( QStringLiteral( "image/" ) ).remove( QRegExp( "_.*" ) );
184  QgsDebugMsg( "server simpleFormat = " + simpleFormat );
185  QString mimeFormat = "image/" + formatsMap.value( simpleFormat );
186  QgsDebugMsg( "server mimeFormat = " + mimeFormat );
187 
188  QString label = format;
189 
190  if ( mMimeLabelMap.contains( mimeFormat ) )
191  {
192  if ( format != mMimeLabelMap.value( mimeFormat ) )
193  {
194  // Append name of GDAL driver
195  label += " / " + mMimeLabelMap.value( mimeFormat );
196  }
197 
198  if ( simpleFormat.contains( QLatin1String( "tif" ) ) ) // prefer *tif*
199  {
200  if ( preferred < 0 || simpleFormat.startsWith( 'g' ) ) // prefer geotiff
201  {
202  preferred = i;
203  }
204  }
205  }
206  else
207  {
208  // We cannot always say that the format is not supported by GDAL because
209  // server can use strange names, but format itself is supported
210  QgsDebugMsg( QStringLiteral( "format %1 unknown" ).arg( format ) );
211  }
212 
213  mFormatComboBox->insertItem( i, label );
214  }
215  // Set preferred
216  // TODO: all enabled for now, see above
217  preferred = preferred >= 0 ? preferred : 0;
218  mFormatComboBox->setCurrentIndex( preferred );
219 
220  mFormatComboBox->setEnabled( true );
221 }
222 
224 {
225  mTimeComboBox->clear();
226  mTimeComboBox->insertItems( 0, selectedLayersTimes() );
227  mTimeComboBox->setEnabled( !selectedLayersTimes().isEmpty() );
228 }
229 
231 {
232  mTimeComboBox->clear();
233  mTimeComboBox->setEnabled( false );
234 }
235 
237 {
238  mConnectionsComboBox->clear();
239  mConnectionsComboBox->addItems( QgsOwsConnection::connectionList( mService ) );
240 
242 }
243 
245 {
246  if ( string.compare( QLatin1String( "wms" ), Qt::CaseInsensitive ) == 0 )
248  else if ( string.compare( QLatin1String( "wfs" ), Qt::CaseInsensitive ) == 0 )
250  else if ( string.compare( QLatin1String( "wcs" ), Qt::CaseInsensitive ) == 0 )
252  else
254 }
255 
256 void QgsOWSSourceSelect::mNewButton_clicked()
257 {
259  QgsNewHttpConnection *nc = new QgsNewHttpConnection( this, type, "/qgis/connections-" + mService.toLower() + '/' );
260 
261  if ( nc->exec() )
262  {
264  emit connectionsChanged();
265  }
266 
267  delete nc;
268 }
269 
270 void QgsOWSSourceSelect::mEditButton_clicked()
271 {
273  QgsNewHttpConnection *nc = new QgsNewHttpConnection( this, type, "/qgis/connections-" + mService.toLower() + '/', mConnectionsComboBox->currentText() );
274 
275  if ( nc->exec() )
276  {
278  emit connectionsChanged();
279  }
280 
281  delete nc;
282 }
283 
284 void QgsOWSSourceSelect::mDeleteButton_clicked()
285 {
286  QString msg = tr( "Are you sure you want to remove the %1 connection and all associated settings?" )
287  .arg( mConnectionsComboBox->currentText() );
288  QMessageBox::StandardButton result = QMessageBox::question( this, tr( "Delete Connection" ), msg, QMessageBox::Yes | QMessageBox::No );
289  if ( result == QMessageBox::Yes )
290  {
291  QgsOwsConnection::deleteConnection( mService, mConnectionsComboBox->currentText() );
292  mConnectionsComboBox->removeItem( mConnectionsComboBox->currentIndex() ); // populateConnectionList();
294  emit connectionsChanged();
295  }
296 }
297 
298 void QgsOWSSourceSelect::mSaveButton_clicked()
299 {
301  dlg.exec();
302 }
303 
304 void QgsOWSSourceSelect::mLoadButton_clicked()
305 {
306  QString fileName = QFileDialog::getOpenFileName( this, tr( "Load Connections" ), QDir::homePath(),
307  tr( "XML files (*.xml *.XML)" ) );
308  if ( fileName.isEmpty() )
309  {
310  return;
311  }
312 
314  dlg.exec();
316  emit connectionsChanged();
317 }
318 
320  int id,
321  const QStringList &names,
322  QMap<int, QgsTreeWidgetItem *> &items,
323  int &layerAndStyleCount,
324  const QMap<int, int> &layerParents,
325  const QMap<int, QStringList> &layerParentNames )
326 {
327  QgsDebugMsg( QStringLiteral( "id = %1 layerAndStyleCount = %2 names = %3 " ).arg( id ).arg( layerAndStyleCount ).arg( names.join( "," ) ) );
328  if ( items.contains( id ) )
329  return items[id];
330 
331 
332  QgsTreeWidgetItem *item = nullptr;
333  if ( layerParents.contains( id ) )
334  {
335  // it has parent -> create first its parent
336  int parent = layerParents[ id ];
337  item = new QgsTreeWidgetItem( createItem( parent, layerParentNames[ parent ], items, layerAndStyleCount, layerParents, layerParentNames ) );
338  }
339  else
340  item = new QgsTreeWidgetItem( mLayersTreeWidget );
341 
342  item->setText( 0, QString::number( ++layerAndStyleCount ) );
343  item->setText( 1, names[0].simplified() );
344  item->setText( 2, names[1].simplified() );
345  item->setText( 3, names[2].simplified() );
346  item->setToolTip( 3, "<font color=black>" + names[2].simplified() + "</font>" );
347 
348  items[ id ] = item;
349 
350  return item;
351 }
352 
354 {
355 }
356 
357 void QgsOWSSourceSelect::mConnectButton_clicked()
358 {
359 
360  mLayersTreeWidget->clear();
361  clearFormats();
362  clearTimes();
363  clearCrs();
364 
365  mConnName = mConnectionsComboBox->currentText();
366 
367  QgsOwsConnection connection( mService, mConnectionsComboBox->currentText() );
368  mUri = connection.uri();
369 
370  QApplication::setOverrideCursor( Qt::WaitCursor );
371 
372  QgsDebugMsg( QStringLiteral( "call populateLayerList" ) );
374 
375  QApplication::restoreOverrideCursor();
376 }
377 
378 void QgsOWSSourceSelect::enableLayersForCrs( QTreeWidgetItem * )
379 {
380 }
381 
382 void QgsOWSSourceSelect::mChangeCRSButton_clicked()
383 {
384  QStringList layers;
385  const auto constSelectedItems = mLayersTreeWidget->selectedItems();
386  for ( QTreeWidgetItem *item : constSelectedItems )
387  {
388  QString layer = item->data( 0, Qt::UserRole + 0 ).toString();
389  if ( !layer.isEmpty() )
390  layers << layer;
391  }
392 
394  mySelector->setMessage( QString() );
395  mySelector->setOgcWmsCrsFilter( mSelectedLayersCRSs );
396 
398  if ( defaultCRS.isValid() )
399  {
400  mySelector->setCrs( defaultCRS );
401  }
402 
403  if ( !mySelector->exec() )
404  return;
405 
406  mSelectedCRS = mySelector->crs().authid();
407  delete mySelector;
408 
409  mSelectedCRSLabel->setText( descriptionForAuthId( mSelectedCRS ) );
410 
411  for ( int i = 0; i < mLayersTreeWidget->topLevelItemCount(); i++ )
412  {
413  enableLayersForCrs( mLayersTreeWidget->topLevelItem( i ) );
414  }
415 
416  updateButtons();
417 }
418 
419 void QgsOWSSourceSelect::mLayersTreeWidget_itemSelectionChanged()
420 {
421 }
422 
424 {
425  clearCrs();
426  mSelectedLayersCRSs = selectedLayersCrses().toSet();
427  mCRSLabel->setText( tr( "Coordinate Reference System (%n available)", "crs count", mSelectedLayersCRSs.count() ) + ':' );
428 
429  mChangeCRSButton->setDisabled( mSelectedLayersCRSs.isEmpty() );
430 
431  if ( !mSelectedLayersCRSs.isEmpty() )
432  {
433  // check whether current CRS is supported
434  // if not, use one of the available CRS
435  QString defaultCRS;
436  QSet<QString>::const_iterator it = mSelectedLayersCRSs.constBegin();
437  for ( ; it != mSelectedLayersCRSs.constEnd(); ++it )
438  {
439  if ( it->compare( mSelectedCRS, Qt::CaseInsensitive ) == 0 )
440  break;
441 
442  // save first CRS in case the current CRS is not available
443  if ( it == mSelectedLayersCRSs.constBegin() )
444  defaultCRS = *it;
445 
446  // prefer value of DEFAULT_GEO_EPSG_CRS_ID if available
447  if ( *it == GEO_EPSG_CRS_AUTHID )
448  defaultCRS = *it;
449  }
450 
451  if ( it == mSelectedLayersCRSs.constEnd() )
452  {
453  // not found
454  mSelectedCRS = defaultCRS;
455  }
456  mSelectedCRSLabel->setText( descriptionForAuthId( mSelectedCRS ) );
457  mChangeCRSButton->setEnabled( true );
458  }
459  QgsDebugMsg( "mSelectedCRS = " + mSelectedCRS );
460 }
461 
463 {
464  mCRSLabel->setText( tr( "Coordinate Reference System" ) + ':' );
465  mSelectedCRS.clear();
466  mSelectedCRSLabel->clear();
467  mChangeCRSButton->setEnabled( false );
468 }
469 
470 void QgsOWSSourceSelect::mTilesetsTableWidget_itemClicked( QTableWidgetItem *item )
471 {
472  Q_UNUSED( item )
473 
474  QTableWidgetItem *rowItem = mTilesetsTableWidget->item( mTilesetsTableWidget->currentRow(), 0 );
475  bool wasSelected = mCurrentTileset == rowItem;
476 
477  mTilesetsTableWidget->blockSignals( true );
478  mTilesetsTableWidget->clearSelection();
479  if ( !wasSelected )
480  {
481  QgsDebugMsg( QStringLiteral( "selecting current row %1" ).arg( mTilesetsTableWidget->currentRow() ) );
482  mTilesetsTableWidget->selectRow( mTilesetsTableWidget->currentRow() );
483  mCurrentTileset = rowItem;
484  }
485  else
486  {
487  mCurrentTileset = nullptr;
488  }
489  mTilesetsTableWidget->blockSignals( false );
490 
491  updateButtons();
492 }
493 
494 
495 
497 {
498  return mConnName;
499 }
500 
502 {
503  return mConnectionInfo;
504 }
505 
507 {
508  return selectedLayersFormats().value( mFormatComboBox->currentIndex() );
509 }
510 
511 QNetworkRequest::CacheLoadControl QgsOWSSourceSelect::selectedCacheLoadControl()
512 {
513  int cache = mCacheComboBox->currentData().toInt();
514  return static_cast<QNetworkRequest::CacheLoadControl>( cache );
515 }
516 
518 {
519  return mSelectedCRS;
520 }
521 
523 {
524  return mTimeComboBox->currentText();
525 }
526 
528 {
529  QString toSelect = QgsOwsConnection::selectedConnection( mService );
530 
531  mConnectionsComboBox->setCurrentIndex( mConnectionsComboBox->findText( toSelect ) );
532 
533  if ( mConnectionsComboBox->currentIndex() < 0 )
534  {
535  if ( toSelect.isNull() )
536  mConnectionsComboBox->setCurrentIndex( 0 );
537  else
538  mConnectionsComboBox->setCurrentIndex( mConnectionsComboBox->count() - 1 );
539  }
540 
541  if ( mConnectionsComboBox->count() == 0 )
542  {
543  // No connections - disable various buttons
544  mConnectButton->setEnabled( false );
545  mEditButton->setEnabled( false );
546  mDeleteButton->setEnabled( false );
547  mSaveButton->setEnabled( false );
548  }
549  else
550  {
551  // Connections - enable various buttons
552  mConnectButton->setEnabled( true );
553  mEditButton->setEnabled( true );
554  mDeleteButton->setEnabled( true );
555  mSaveButton->setEnabled( true );
556  }
557 
558  QgsOwsConnection::setSelectedConnection( mService, mConnectionsComboBox->currentText() );
559 }
560 
561 void QgsOWSSourceSelect::showStatusMessage( QString const &message )
562 {
563  mStatusLabel->setText( message );
564 
565  // update the display of this widget
566  update();
567 }
568 
569 
570 void QgsOWSSourceSelect::showError( QString const &title, QString const &format, QString const &error )
571 {
572  QgsMessageViewer *mv = new QgsMessageViewer( this );
573  mv->setWindowTitle( title );
574 
575  if ( format == QLatin1String( "text/html" ) )
576  {
577  mv->setMessageAsHtml( error );
578  }
579  else
580  {
581  mv->setMessageAsPlainText( tr( "Could not understand the response:\n%1" ).arg( error ) );
582  }
583  mv->showMessage( true ); // Is deleted when closed
584 }
585 
586 void QgsOWSSourceSelect::mConnectionsComboBox_activated( int )
587 {
588  // Remember which server was selected.
589  QgsOwsConnection::setSelectedConnection( mService, mConnectionsComboBox->currentText() );
590 }
591 
592 void QgsOWSSourceSelect::mAddDefaultButton_clicked()
593 {
595 }
596 
597 QString QgsOWSSourceSelect::descriptionForAuthId( const QString &authId )
598 {
599  if ( mCrsNames.contains( authId ) )
600  return mCrsNames[ authId ];
601 
603  mCrsNames.insert( authId, qgisSrs.description() );
604  return qgisSrs.description();
605 }
606 
608 {
609  QMap<QString, QString> exampleServers;
610  exampleServers[QStringLiteral( "DM Solutions GMap" )] = QStringLiteral( "http://www2.dmsolutions.ca/cgi-bin/mswms_gmap" );
611  exampleServers[QStringLiteral( "Lizardtech server" )] = QStringLiteral( "http://wms.lizardtech.com/lizardtech/iserv/ows" );
612  // Nice to have the qgis users map, but I'm not sure of the URL at the moment.
613  // exampleServers["Qgis users map"] = "http://qgis.org/wms.cgi";
614 
615  QgsSettings settings;
616  settings.beginGroup( "/qgis/connections-" + mService.toLower() );
617  QMap<QString, QString>::const_iterator i = exampleServers.constBegin();
618  for ( ; i != exampleServers.constEnd(); ++i )
619  {
620  // Only do a server if it's name doesn't already exist.
621  QStringList keys = settings.childGroups();
622  if ( !keys.contains( i.key() ) )
623  {
624  QString path = i.key();
625  settings.setValue( path + "/url", i.value() );
626  }
627  }
628  settings.endGroup();
630 
631  QMessageBox::information( this, tr( "Add WMS Servers" ), "<p>" + tr( "Several WMS servers have "
632  "been added to the server list. Note that if "
633  "you access the Internet via a web proxy, you will "
634  "need to set the proxy settings in the QGIS options dialog." ) + "</p>" );
635 }
636 
637 void QgsOWSSourceSelect::addWmsListRow( const QDomElement &item, int row )
638 {
639  QDomElement title = item.firstChildElement( QStringLiteral( "title" ) );
640  addWmsListItem( title, row, 0 );
641  QDomElement description = item.firstChildElement( QStringLiteral( "description" ) );
642  addWmsListItem( description, row, 1 );
643  QDomElement link = item.firstChildElement( QStringLiteral( "link" ) );
644  addWmsListItem( link, row, 2 );
645 }
646 
647 void QgsOWSSourceSelect::addWmsListItem( const QDomElement &el, int row, int column )
648 {
649  if ( !el.isNull() )
650  {
651  QTableWidgetItem *tableItem = new QTableWidgetItem( el.text() );
652  // TODO: add linebreaks to long tooltips?
653  tableItem->setToolTip( el.text() );
654  mSearchTableWidget->setItem( row, column, tableItem );
655  }
656 }
657 
658 void QgsOWSSourceSelect::mSearchButton_clicked()
659 {
660  // clear results
661  mSearchTableWidget->clearContents();
662  mSearchTableWidget->setRowCount( 0 );
663 
664  // disable Add WMS button
665  mSearchAddButton->setEnabled( false );
666 
667  QApplication::setOverrideCursor( Qt::WaitCursor );
668 
669  QgsSettings settings;
670  // geopole.org (geopole.ch) 25.4.2012 : 503 Service Unavailable, archive: Recently added 20 Jul 2011
671  QString mySearchUrl = settings.value( QStringLiteral( "qgis/WMSSearchUrl" ), "http://geopole.org/wms/search?search=%1&type=rss" ).toString();
672  QUrl url( mySearchUrl.arg( mSearchTermLineEdit->text() ) );
673  QgsDebugMsg( url.toString() );
674 
675  QNetworkReply *r = QgsNetworkAccessManager::instance()->get( QNetworkRequest( url ) );
676  connect( r, &QNetworkReply::finished, this, &QgsOWSSourceSelect::searchFinished );
677 }
678 
679 void QgsOWSSourceSelect::searchFinished()
680 {
681  QApplication::restoreOverrideCursor();
682 
683  QNetworkReply *r = qobject_cast<QNetworkReply *>( sender() );
684  if ( !r )
685  return;
686 
687  if ( r->error() == QNetworkReply::NoError )
688  {
689  // parse results
690  QDomDocument doc( QStringLiteral( "RSS" ) );
691  QByteArray res = r->readAll();
692  QString error;
693  int line, column;
694  if ( doc.setContent( res, &error, &line, &column ) )
695  {
696  QDomNodeList list = doc.elementsByTagName( QStringLiteral( "item" ) );
697  mSearchTableWidget->setRowCount( list.size() );
698  for ( int i = 0; i < list.size(); i++ )
699  {
700  if ( list.item( i ).isElement() )
701  {
702  QDomElement item = list.item( i ).toElement();
703  addWmsListRow( item, i );
704  }
705  }
706 
707  mSearchTableWidget->resizeColumnsToContents();
708  }
709  else
710  {
711  QgsDebugMsg( QStringLiteral( "setContent failed" ) );
712  showStatusMessage( tr( "parse error at row %1, column %2: %3" ).arg( line ).arg( column ).arg( error ) );
713  }
714  }
715  else
716  {
717  showStatusMessage( tr( "network error: %1" ).arg( r->error() ) );
718  }
719 
720  r->deleteLater();
721 }
722 
723 void QgsOWSSourceSelect::mSearchTableWidget_itemSelectionChanged()
724 {
725  mSearchAddButton->setEnabled( mSearchTableWidget->currentRow() != -1 );
726 }
727 
728 void QgsOWSSourceSelect::mLayerUpButton_clicked()
729 {
730  QList<QTreeWidgetItem *> selectionList = mLayerOrderTreeWidget->selectedItems();
731  if ( selectionList.empty() )
732  {
733  return;
734  }
735  int selectedIndex = mLayerOrderTreeWidget->indexOfTopLevelItem( selectionList[0] );
736  if ( selectedIndex < 1 )
737  {
738  return; //item not existing or already on top
739  }
740 
741  QTreeWidgetItem *selectedItem = mLayerOrderTreeWidget->takeTopLevelItem( selectedIndex );
742  mLayerOrderTreeWidget->insertTopLevelItem( selectedIndex - 1, selectedItem );
743  mLayerOrderTreeWidget->clearSelection();
744  selectedItem->setSelected( true );
745 }
746 
747 void QgsOWSSourceSelect::mLayerDownButton_clicked()
748 {
749  QList<QTreeWidgetItem *> selectionList = mLayerOrderTreeWidget->selectedItems();
750  if ( selectionList.empty() )
751  {
752  return;
753  }
754  int selectedIndex = mLayerOrderTreeWidget->indexOfTopLevelItem( selectionList[0] );
755  if ( selectedIndex < 0 || selectedIndex > mLayerOrderTreeWidget->topLevelItemCount() - 2 )
756  {
757  return; //item not existing or already at bottom
758  }
759 
760  QTreeWidgetItem *selectedItem = mLayerOrderTreeWidget->takeTopLevelItem( selectedIndex );
761  mLayerOrderTreeWidget->insertTopLevelItem( selectedIndex + 1, selectedItem );
762  mLayerOrderTreeWidget->clearSelection();
763  selectedItem->setSelected( true );
764 }
765 
766 QList<QgsOWSSourceSelect::SupportedFormat> QgsOWSSourceSelect::providerFormats()
767 {
768  return QList<SupportedFormat>();
769 }
770 
772 {
773  return QStringList();
774 }
775 
777 {
778  return QStringList();
779 }
780 
782 {
783  return QStringList();
784 }
785 
786 void QgsOWSSourceSelect::updateButtons()
787 {
788 }
QStringList childGroups() const
Returns a list of all key top-level groups that contain keys that can be read using the QSettings obj...
void endGroup()
Resets the group to what it was before the corresponding beginGroup() call.
Definition: qgssettings.cpp:97
WidgetMode
Different ways a source select dialog can be used.
void setupButtons(QDialogButtonBox *buttonBox)
Connect the ok and apply/add buttons to the slots.
QMap< QString, QString > mCrsNames
void populateCrs()
Sets supported CRSs.
virtual void populateLayerList()
Populate the layer list.
void clearTimes()
Clear times.
This class is a composition of two QSettings instances:
Definition: qgssettings.h:58
Abstract base Data Source Widget to create connections and add layers This class provides common func...
QString connectionInfo()
Connection info (uri)
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QgsNewHttpConnection::ConnectionType connectionTypeFromServiceString(const QString &string)
void setMessage(const QString &message)
Sets a message to show in the dialog.
QgsOWSSourceSelect(const QString &service, QWidget *parent=nullptr, Qt::WindowFlags fl=QgsGuiUtils::ModalDialogFlags, QgsProviderRegistry::WidgetMode widgetMode=QgsProviderRegistry::WidgetMode::None)
Constructor.
QString selectedFormat()
Returns currently selected format.
virtual QStringList selectedLayersCrses()
Server CRS supported for currently selected layer item(s)
static QStringList connectionList(const QString &service)
Returns the list of connections for the specified service.
QString descriptionForAuthId(const QString &authId)
Returns a textual description for the authority id.
static QgsGui * instance()
Returns a pointer to the singleton instance.
Definition: qgsgui.cpp:61
virtual QStringList selectedLayersFormats()
List of formats supported for currently selected layer item(s)
QgsCoordinateReferenceSystem crs() const
Returns the CRS currently selected in the widget.
QNetworkRequest::CacheLoadControl selectedCacheLoadControl()
Returns currently selected cache load control.
A generic dialog to prompt the user for a Coordinate Reference System.
void populateConnectionList()
Populate the connection list combo box.
void addWmsListItem(const QDomElement &el, int row, int column)
virtual void enableLayersForCrs(QTreeWidgetItem *item)
void addDefaultServers()
Add a few example servers to the list.
QgsCoordinateReferenceSystem crs
Definition: qgsproject.h:95
QString description() const
Returns the descriptive name of the CRS, e.g., "WGS 84" or "GDA 94 / Vicgrid94".
QgsProviderRegistry::WidgetMode widgetMode() const
Returns the widget mode.
const QString GEO_EPSG_CRS_AUTHID
Geographic coord sys from EPSG authority.
Definition: qgis.cpp:70
static void setSelectedConnection(const QString &service, const QString &name)
Marks the specified connection for the specified service as selected.
void populateFormats()
Populate supported formats.
Connections management.
void clearCrs()
Clear CRSs.
virtual QStringList selectedLayersTimes()
List of times (temporalDomain timePosition/timePeriod for currently selected layer item(s) ...
void reset() override
Called when this source select widget is being shown in a "new and clean" dialog. ...
void setCrs(const QgsCoordinateReferenceSystem &crs)
Sets the initial crs to show within the dialog.
QString uri(bool expandAuthConfig=true) const
Returns the complete URI as a string.
void beginGroup(const QString &prefix, QgsSettings::Section section=QgsSettings::NoSection)
Appends prefix to the current group.
Definition: qgssettings.cpp:87
void setOgcWmsCrsFilter(const QSet< QString > &crsFilter)
filters this dialog by the given CRSs
static QgsNetworkAccessManager * instance(Qt::ConnectionType connectionType=Qt::BlockingQueuedConnection)
Returns a pointer to the active QgsNetworkAccessManager for the current thread.
ConnectionType
Available connection types for configuring in the dialog.
QString connName()
Connection name.
void showStatusMessage(const QString &message)
Sets status message to theMessage.
static QgsCoordinateReferenceSystem fromOgcWmsCrs(const QString &ogcCrs)
Creates a CRS from a given OGC WMS-format Coordinate Reference System string.
QString mConnectionInfo
Connection info for selected connection.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
QTreeWidgetItem subclass with custom handling for item sorting.
void showError(const QString &title, const QString &format, const QString &error)
show whatever error is exposed.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:442
This class represents a coordinate reference system (CRS).
virtual QList< QgsOWSSourceSelect::SupportedFormat > providerFormats()
List of image formats (encodings) supported by provider.
void connectionsChanged()
Emitted when the provider&#39;s connections have changed This signal is normally forwarded the app and us...
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
void refresh() override
Triggered when the provider&#39;s connections need to be refreshed.
QString selectedTime()
Returns currently selected time.
void addWmsListRow(const QDomElement &item, int row)
void clearFormats()
Clear previously set formats.
QString mService
Service name.
QTableWidgetItem * mCurrentTileset
Dialog to allow the user to configure and save connection information for an HTTP Server for WMS...
void setConnectionListPosition()
Sets the server connection combo box to that stored in the config file.
QgsTreeWidgetItem * createItem(int id, const QStringList &names, QMap< int, QgsTreeWidgetItem *> &items, int &layerAndStyleCount, const QMap< int, int > &layerParents, const QMap< int, QStringList > &layerParentNames)
create an item including possible parents
QgsDataSourceUri mUri
URI for selected connection.
void populateTimes()
Populate times.
static QString selectedConnection(const QString &service)
Retrieves the selected connection for the specified service.
QString authid() const
Returns the authority identifier for the CRS.
QString mConnName
Name for selected connection.
QString selectedCrs()
Returns currently selected Crs.
static void deleteConnection(const QString &service, const QString &name)
Deletes the connection for the specified service with the specified name.
bool isValid() const
Returns whether this CRS is correctly initialized and usable.