QGIS API Documentation  3.8.0-Zanzibar (11aff65)
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 
41 #include <QButtonGroup>
42 #include <QFileDialog>
43 #include <QRadioButton>
44 #include <QDomDocument>
45 #include <QHeaderView>
46 #include <QImageReader>
47 #include <QInputDialog>
48 #include <QMap>
49 #include <QMessageBox>
50 #include <QPicture>
51 #include <QUrl>
52 #include <QValidator>
53 #include <QNetworkRequest>
54 #include <QNetworkReply>
55 
56 QgsOWSSourceSelect::QgsOWSSourceSelect( const QString &service, QWidget *parent, Qt::WindowFlags fl, QgsProviderRegistry::WidgetMode theWidgetMode )
57  : QgsAbstractDataSourceWidget( parent, fl, theWidgetMode )
58  , mService( service )
59 
60 {
61  setupUi( this );
62  connect( mNewButton, &QPushButton::clicked, this, &QgsOWSSourceSelect::mNewButton_clicked );
63  connect( mEditButton, &QPushButton::clicked, this, &QgsOWSSourceSelect::mEditButton_clicked );
64  connect( mDeleteButton, &QPushButton::clicked, this, &QgsOWSSourceSelect::mDeleteButton_clicked );
65  connect( mSaveButton, &QPushButton::clicked, this, &QgsOWSSourceSelect::mSaveButton_clicked );
66  connect( mLoadButton, &QPushButton::clicked, this, &QgsOWSSourceSelect::mLoadButton_clicked );
67  connect( mConnectButton, &QPushButton::clicked, this, &QgsOWSSourceSelect::mConnectButton_clicked );
68  connect( mChangeCRSButton, &QPushButton::clicked, this, &QgsOWSSourceSelect::mChangeCRSButton_clicked );
69  connect( mLayersTreeWidget, &QTreeWidget::itemSelectionChanged, this, &QgsOWSSourceSelect::mLayersTreeWidget_itemSelectionChanged );
70  connect( mConnectionsComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::activated ), this, &QgsOWSSourceSelect::mConnectionsComboBox_activated );
71  connect( mAddDefaultButton, &QPushButton::clicked, this, &QgsOWSSourceSelect::mAddDefaultButton_clicked );
72  connect( mSearchButton, &QPushButton::clicked, this, &QgsOWSSourceSelect::mSearchButton_clicked );
73  connect( mSearchTableWidget, &QTableWidget::itemSelectionChanged, this, &QgsOWSSourceSelect::mSearchTableWidget_itemSelectionChanged );
74  connect( mTilesetsTableWidget, &QTableWidget::itemClicked, this, &QgsOWSSourceSelect::mTilesetsTableWidget_itemClicked );
75  connect( mLayerUpButton, &QPushButton::clicked, this, &QgsOWSSourceSelect::mLayerUpButton_clicked );
76  connect( mLayerDownButton, &QPushButton::clicked, this, &QgsOWSSourceSelect::mLayerDownButton_clicked );
77  setupButtons( buttonBox );
78 
79 
80  setWindowTitle( tr( "Add Layer(s) from a %1 Server" ).arg( service ) );
81 
82  clearCrs();
83 
84  mTileWidthLineEdit->setValidator( new QIntValidator( 0, 9999, this ) );
85  mTileHeightLineEdit->setValidator( new QIntValidator( 0, 9999, this ) );
86  mFeatureCountLineEdit->setValidator( new QIntValidator( 0, 9999, this ) );
87 
88  mCacheComboBox->addItem( tr( "Always cache" ), QNetworkRequest::AlwaysCache );
89  mCacheComboBox->addItem( tr( "Prefer cache" ), QNetworkRequest::PreferCache );
90  mCacheComboBox->addItem( tr( "Prefer network" ), QNetworkRequest::PreferNetwork );
91  mCacheComboBox->addItem( tr( "Always network" ), QNetworkRequest::AlwaysNetwork );
92 
93  // 'Prefer network' is the default noted in the combobox's tool tip
94  mCacheComboBox->setCurrentIndex( mCacheComboBox->findData( QNetworkRequest::PreferNetwork ) );
95 
96  if ( widgetMode() != QgsProviderRegistry::WidgetMode::Manager )
97  {
98  //set the current project CRS if available
100  //convert CRS id to epsg
101  if ( currentRefSys.isValid() )
102  {
103  mSelectedCRS = currentRefSys.authid();
104  }
105  }
106  else
107  {
108  mTabWidget->removeTab( mTabWidget->indexOf( mLayerOrderTab ) );
109  mTabWidget->removeTab( mTabWidget->indexOf( mTilesetsTab ) );
110  mTimeWidget->hide();
111  mFormatWidget->hide();
112  mCRSWidget->hide();
113  mCacheWidget->hide();
114  }
115 
116  // set up the WMS connections we already know about
118 
119  QgsSettings settings;
120  QgsDebugMsg( QStringLiteral( "restoring geometry" ) );
121  restoreGeometry( settings.value( QStringLiteral( "Windows/WMSSourceSelect/geometry" ) ).toByteArray() );
122 }
123 
125 {
126  QgsSettings settings;
127  QgsDebugMsg( QStringLiteral( "saving geometry" ) );
128  settings.setValue( QStringLiteral( "Windows/WMSSourceSelect/geometry" ), saveGeometry() );
129 }
130 
132 {
134 }
135 
137 {
138  mFormatComboBox->clear();
139  mFormatComboBox->setEnabled( false );
140 }
141 
143 {
144 
145  // A server may offer more similar formats, which are mapped
146  // to the same GDAL format, e.g. GeoTIFF and TIFF
147  // -> recreate always buttons for all available formats, enable supported
148 
149  clearFormats();
150 
151  if ( mProviderFormats.isEmpty() )
152  {
153  mProviderFormats = providerFormats();
154  for ( int i = 0; i < mProviderFormats.size(); i++ )
155  {
156  // GDAL mime types may be image/tiff, image/png, ...
157  mMimeLabelMap.insert( mProviderFormats[i].format, mProviderFormats[i].label );
158  }
159  }
160 
161  // selectedLayersFormats may come in various forms:
162  // image/tiff, GTiff, GeoTIFF, TIFF, geotiff_int16, geotiff_rgb,
163  // PNG, GTOPO30, ARCGRID, IMAGEMOSAIC
164  // and even any string defined in server configuration, for example the
165  // value used in UMN Mapserver for OUTPUTFORMAT->NAME is used in
166  // WCS 1.0.0 SupportedFormats/Format
167 
168  // TODO: It is impossible to cover all possible formats coming from server
169  // -> enabled all formats, GDAL may be able to open them
170 
171  QMap<QString, QString> formatsMap;
172  formatsMap.insert( QStringLiteral( "geotiff" ), QStringLiteral( "tiff" ) );
173  formatsMap.insert( QStringLiteral( "gtiff" ), QStringLiteral( "tiff" ) );
174  formatsMap.insert( QStringLiteral( "tiff" ), QStringLiteral( "tiff" ) );
175  formatsMap.insert( QStringLiteral( "tif" ), QStringLiteral( "tiff" ) );
176  formatsMap.insert( QStringLiteral( "gif" ), QStringLiteral( "gif" ) );
177  formatsMap.insert( QStringLiteral( "jpeg" ), QStringLiteral( "jpeg" ) );
178  formatsMap.insert( QStringLiteral( "jpg" ), QStringLiteral( "jpeg" ) );
179  formatsMap.insert( QStringLiteral( "png" ), QStringLiteral( "png" ) );
180 
181  int preferred = -1;
182  QStringList layersFormats = selectedLayersFormats();
183  for ( int i = 0; i < layersFormats.size(); i++ )
184  {
185  QString format = layersFormats.value( i );
186  QgsDebugMsg( "server format = " + format );
187  QString simpleFormat = format.toLower().remove( QStringLiteral( "image/" ) ).remove( QRegExp( "_.*" ) );
188  QgsDebugMsg( "server simpleFormat = " + simpleFormat );
189  QString mimeFormat = "image/" + formatsMap.value( simpleFormat );
190  QgsDebugMsg( "server mimeFormat = " + mimeFormat );
191 
192  QString label = format;
193 
194  if ( mMimeLabelMap.contains( mimeFormat ) )
195  {
196  if ( format != mMimeLabelMap.value( mimeFormat ) )
197  {
198  // Append name of GDAL driver
199  label += " / " + mMimeLabelMap.value( mimeFormat );
200  }
201 
202  if ( simpleFormat.contains( QLatin1String( "tif" ) ) ) // prefer *tif*
203  {
204  if ( preferred < 0 || simpleFormat.startsWith( 'g' ) ) // prefer geotiff
205  {
206  preferred = i;
207  }
208  }
209  }
210  else
211  {
212  // We cannot always say that the format is not supported by GDAL because
213  // server can use strange names, but format itself is supported
214  QgsDebugMsg( QStringLiteral( "format %1 unknown" ).arg( format ) );
215  }
216 
217  mFormatComboBox->insertItem( i, label );
218  }
219  // Set preferred
220  // TODO: all enabled for now, see above
221  preferred = preferred >= 0 ? preferred : 0;
222  mFormatComboBox->setCurrentIndex( preferred );
223 
224  mFormatComboBox->setEnabled( true );
225 }
226 
228 {
229  mTimeComboBox->clear();
230  mTimeComboBox->insertItems( 0, selectedLayersTimes() );
231  mTimeComboBox->setEnabled( !selectedLayersTimes().isEmpty() );
232 }
233 
235 {
236  mTimeComboBox->clear();
237  mTimeComboBox->setEnabled( false );
238 }
239 
241 {
242  mConnectionsComboBox->clear();
243  mConnectionsComboBox->addItems( QgsOwsConnection::connectionList( mService ) );
244 
246 }
247 
249 {
250  if ( string.compare( QLatin1String( "wms" ), Qt::CaseInsensitive ) == 0 )
252  else if ( string.compare( QLatin1String( "wfs" ), Qt::CaseInsensitive ) == 0 )
254  else if ( string.compare( QLatin1String( "wcs" ), Qt::CaseInsensitive ) == 0 )
256  else
258 }
259 
260 void QgsOWSSourceSelect::mNewButton_clicked()
261 {
263  QgsNewHttpConnection *nc = new QgsNewHttpConnection( this, type, "/qgis/connections-" + mService.toLower() + '/' );
264 
265  if ( nc->exec() )
266  {
268  emit connectionsChanged();
269  }
270 
271  delete nc;
272 }
273 
274 void QgsOWSSourceSelect::mEditButton_clicked()
275 {
277  QgsNewHttpConnection *nc = new QgsNewHttpConnection( this, type, "/qgis/connections-" + mService.toLower() + '/', mConnectionsComboBox->currentText() );
278 
279  if ( nc->exec() )
280  {
282  emit connectionsChanged();
283  }
284 
285  delete nc;
286 }
287 
288 void QgsOWSSourceSelect::mDeleteButton_clicked()
289 {
290  QString msg = tr( "Are you sure you want to remove the %1 connection and all associated settings?" )
291  .arg( mConnectionsComboBox->currentText() );
292  QMessageBox::StandardButton result = QMessageBox::question( this, tr( "Delete Connection" ), msg, QMessageBox::Yes | QMessageBox::No );
293  if ( result == QMessageBox::Yes )
294  {
295  QgsOwsConnection::deleteConnection( mService, mConnectionsComboBox->currentText() );
296  mConnectionsComboBox->removeItem( mConnectionsComboBox->currentIndex() ); // populateConnectionList();
298  emit connectionsChanged();
299  }
300 }
301 
302 void QgsOWSSourceSelect::mSaveButton_clicked()
303 {
305  dlg.exec();
306 }
307 
308 void QgsOWSSourceSelect::mLoadButton_clicked()
309 {
310  QString fileName = QFileDialog::getOpenFileName( this, tr( "Load Connections" ), QDir::homePath(),
311  tr( "XML files (*.xml *.XML)" ) );
312  if ( fileName.isEmpty() )
313  {
314  return;
315  }
316 
318  dlg.exec();
320  emit connectionsChanged();
321 }
322 
324  int id,
325  const QStringList &names,
326  QMap<int, QgsTreeWidgetItem *> &items,
327  int &layerAndStyleCount,
328  const QMap<int, int> &layerParents,
329  const QMap<int, QStringList> &layerParentNames )
330 {
331  QgsDebugMsg( QStringLiteral( "id = %1 layerAndStyleCount = %2 names = %3 " ).arg( id ).arg( layerAndStyleCount ).arg( names.join( "," ) ) );
332  if ( items.contains( id ) )
333  return items[id];
334 
335 
336  QgsTreeWidgetItem *item = nullptr;
337  if ( layerParents.contains( id ) )
338  {
339  // it has parent -> create first its parent
340  int parent = layerParents[ id ];
341  item = new QgsTreeWidgetItem( createItem( parent, layerParentNames[ parent ], items, layerAndStyleCount, layerParents, layerParentNames ) );
342  }
343  else
344  item = new QgsTreeWidgetItem( mLayersTreeWidget );
345 
346  item->setText( 0, QString::number( ++layerAndStyleCount ) );
347  item->setText( 1, names[0].simplified() );
348  item->setText( 2, names[1].simplified() );
349  item->setText( 3, names[2].simplified() );
350  item->setToolTip( 3, "<font color=black>" + names[2].simplified() + "</font>" );
351 
352  items[ id ] = item;
353 
354  return item;
355 }
356 
358 {
359 }
360 
361 void QgsOWSSourceSelect::mConnectButton_clicked()
362 {
363 
364  mLayersTreeWidget->clear();
365  clearFormats();
366  clearTimes();
367  clearCrs();
368 
369  mConnName = mConnectionsComboBox->currentText();
370 
371  QgsOwsConnection connection( mService, mConnectionsComboBox->currentText() );
372  mUri = connection.uri();
373 
374  QApplication::setOverrideCursor( Qt::WaitCursor );
375 
376  QgsDebugMsg( QStringLiteral( "call populateLayerList" ) );
378 
379  QApplication::restoreOverrideCursor();
380 }
381 
382 void QgsOWSSourceSelect::enableLayersForCrs( QTreeWidgetItem * )
383 {
384 }
385 
386 void QgsOWSSourceSelect::mChangeCRSButton_clicked()
387 {
388  QStringList layers;
389  const auto constSelectedItems = mLayersTreeWidget->selectedItems();
390  for ( QTreeWidgetItem *item : constSelectedItems )
391  {
392  QString layer = item->data( 0, Qt::UserRole + 0 ).toString();
393  if ( !layer.isEmpty() )
394  layers << layer;
395  }
396 
398  mySelector->setMessage( QString() );
399  mySelector->setOgcWmsCrsFilter( mSelectedLayersCRSs );
400 
402  if ( defaultCRS.isValid() )
403  {
404  mySelector->setCrs( defaultCRS );
405  }
406 
407  if ( !mySelector->exec() )
408  return;
409 
410  mSelectedCRS = mySelector->crs().authid();
411  delete mySelector;
412 
413  mSelectedCRSLabel->setText( descriptionForAuthId( mSelectedCRS ) );
414 
415  for ( int i = 0; i < mLayersTreeWidget->topLevelItemCount(); i++ )
416  {
417  enableLayersForCrs( mLayersTreeWidget->topLevelItem( i ) );
418  }
419 
420  updateButtons();
421 }
422 
423 void QgsOWSSourceSelect::mLayersTreeWidget_itemSelectionChanged()
424 {
425 }
426 
428 {
429  clearCrs();
430  mSelectedLayersCRSs = selectedLayersCrses().toSet();
431  mCRSLabel->setText( tr( "Coordinate Reference System (%n available)", "crs count", mSelectedLayersCRSs.count() ) + ':' );
432 
433  mChangeCRSButton->setDisabled( mSelectedLayersCRSs.isEmpty() );
434 
435  if ( !mSelectedLayersCRSs.isEmpty() )
436  {
437  // check whether current CRS is supported
438  // if not, use one of the available CRS
439  QString defaultCRS;
440  QSet<QString>::const_iterator it = mSelectedLayersCRSs.constBegin();
441  for ( ; it != mSelectedLayersCRSs.constEnd(); ++it )
442  {
443  if ( it->compare( mSelectedCRS, Qt::CaseInsensitive ) == 0 )
444  break;
445 
446  // save first CRS in case the current CRS is not available
447  if ( it == mSelectedLayersCRSs.constBegin() )
448  defaultCRS = *it;
449 
450  // prefer value of DEFAULT_GEO_EPSG_CRS_ID if available
451  if ( *it == GEO_EPSG_CRS_AUTHID )
452  defaultCRS = *it;
453  }
454 
455  if ( it == mSelectedLayersCRSs.constEnd() )
456  {
457  // not found
458  mSelectedCRS = defaultCRS;
459  }
460  mSelectedCRSLabel->setText( descriptionForAuthId( mSelectedCRS ) );
461  mChangeCRSButton->setEnabled( true );
462  }
463  QgsDebugMsg( "mSelectedCRS = " + mSelectedCRS );
464 }
465 
467 {
468  mCRSLabel->setText( tr( "Coordinate Reference System" ) + ':' );
469  mSelectedCRS.clear();
470  mSelectedCRSLabel->clear();
471  mChangeCRSButton->setEnabled( false );
472 }
473 
474 void QgsOWSSourceSelect::mTilesetsTableWidget_itemClicked( QTableWidgetItem *item )
475 {
476  Q_UNUSED( item )
477 
478  QTableWidgetItem *rowItem = mTilesetsTableWidget->item( mTilesetsTableWidget->currentRow(), 0 );
479  bool wasSelected = mCurrentTileset == rowItem;
480 
481  mTilesetsTableWidget->blockSignals( true );
482  mTilesetsTableWidget->clearSelection();
483  if ( !wasSelected )
484  {
485  QgsDebugMsg( QStringLiteral( "selecting current row %1" ).arg( mTilesetsTableWidget->currentRow() ) );
486  mTilesetsTableWidget->selectRow( mTilesetsTableWidget->currentRow() );
487  mCurrentTileset = rowItem;
488  }
489  else
490  {
491  mCurrentTileset = nullptr;
492  }
493  mTilesetsTableWidget->blockSignals( false );
494 
495  updateButtons();
496 }
497 
498 
499 
501 {
502  return mConnName;
503 }
504 
506 {
507  return mConnectionInfo;
508 }
509 
511 {
512  return selectedLayersFormats().value( mFormatComboBox->currentIndex() );
513 }
514 
515 QNetworkRequest::CacheLoadControl QgsOWSSourceSelect::selectedCacheLoadControl()
516 {
517  int cache = mCacheComboBox->currentData().toInt();
518  return static_cast<QNetworkRequest::CacheLoadControl>( cache );
519 }
520 
522 {
523  return mSelectedCRS;
524 }
525 
527 {
528  return mTimeComboBox->currentText();
529 }
530 
532 {
533  QString toSelect = QgsOwsConnection::selectedConnection( mService );
534 
535  mConnectionsComboBox->setCurrentIndex( mConnectionsComboBox->findText( toSelect ) );
536 
537  if ( mConnectionsComboBox->currentIndex() < 0 )
538  {
539  if ( toSelect.isNull() )
540  mConnectionsComboBox->setCurrentIndex( 0 );
541  else
542  mConnectionsComboBox->setCurrentIndex( mConnectionsComboBox->count() - 1 );
543  }
544 
545  if ( mConnectionsComboBox->count() == 0 )
546  {
547  // No connections - disable various buttons
548  mConnectButton->setEnabled( false );
549  mEditButton->setEnabled( false );
550  mDeleteButton->setEnabled( false );
551  mSaveButton->setEnabled( false );
552  }
553  else
554  {
555  // Connections - enable various buttons
556  mConnectButton->setEnabled( true );
557  mEditButton->setEnabled( true );
558  mDeleteButton->setEnabled( true );
559  mSaveButton->setEnabled( true );
560  }
561 
562  QgsOwsConnection::setSelectedConnection( mService, mConnectionsComboBox->currentText() );
563 }
564 
565 void QgsOWSSourceSelect::showStatusMessage( QString const &message )
566 {
567  mStatusLabel->setText( message );
568 
569  // update the display of this widget
570  update();
571 }
572 
573 
574 void QgsOWSSourceSelect::showError( QString const &title, QString const &format, QString const &error )
575 {
576  QgsMessageViewer *mv = new QgsMessageViewer( this );
577  mv->setWindowTitle( title );
578 
579  if ( format == QLatin1String( "text/html" ) )
580  {
581  mv->setMessageAsHtml( error );
582  }
583  else
584  {
585  mv->setMessageAsPlainText( tr( "Could not understand the response:\n%1" ).arg( error ) );
586  }
587  mv->showMessage( true ); // Is deleted when closed
588 }
589 
590 void QgsOWSSourceSelect::mConnectionsComboBox_activated( int )
591 {
592  // Remember which server was selected.
593  QgsOwsConnection::setSelectedConnection( mService, mConnectionsComboBox->currentText() );
594 }
595 
596 void QgsOWSSourceSelect::mAddDefaultButton_clicked()
597 {
599 }
600 
601 QString QgsOWSSourceSelect::descriptionForAuthId( const QString &authId )
602 {
603  if ( mCrsNames.contains( authId ) )
604  return mCrsNames[ authId ];
605 
607  mCrsNames.insert( authId, qgisSrs.description() );
608  return qgisSrs.description();
609 }
610 
612 {
613  QMap<QString, QString> exampleServers;
614  exampleServers[QStringLiteral( "DM Solutions GMap" )] = QStringLiteral( "http://www2.dmsolutions.ca/cgi-bin/mswms_gmap" );
615  exampleServers[QStringLiteral( "Lizardtech server" )] = QStringLiteral( "http://wms.lizardtech.com/lizardtech/iserv/ows" );
616  // Nice to have the qgis users map, but I'm not sure of the URL at the moment.
617  // exampleServers["Qgis users map"] = "http://qgis.org/wms.cgi";
618 
619  QgsSettings settings;
620  settings.beginGroup( "/qgis/connections-" + mService.toLower() );
621  QMap<QString, QString>::const_iterator i = exampleServers.constBegin();
622  for ( ; i != exampleServers.constEnd(); ++i )
623  {
624  // Only do a server if it's name doesn't already exist.
625  QStringList keys = settings.childGroups();
626  if ( !keys.contains( i.key() ) )
627  {
628  QString path = i.key();
629  settings.setValue( path + "/url", i.value() );
630  }
631  }
632  settings.endGroup();
634 
635  QMessageBox::information( this, tr( "Add WMS Servers" ), "<p>" + tr( "Several WMS servers have "
636  "been added to the server list. Note that if "
637  "you access the Internet via a web proxy, you will "
638  "need to set the proxy settings in the QGIS options dialog." ) + "</p>" );
639 }
640 
641 void QgsOWSSourceSelect::addWmsListRow( const QDomElement &item, int row )
642 {
643  QDomElement title = item.firstChildElement( QStringLiteral( "title" ) );
644  addWmsListItem( title, row, 0 );
645  QDomElement description = item.firstChildElement( QStringLiteral( "description" ) );
646  addWmsListItem( description, row, 1 );
647  QDomElement link = item.firstChildElement( QStringLiteral( "link" ) );
648  addWmsListItem( link, row, 2 );
649 }
650 
651 void QgsOWSSourceSelect::addWmsListItem( const QDomElement &el, int row, int column )
652 {
653  if ( !el.isNull() )
654  {
655  QTableWidgetItem *tableItem = new QTableWidgetItem( el.text() );
656  // TODO: add linebreaks to long tooltips?
657  tableItem->setToolTip( el.text() );
658  mSearchTableWidget->setItem( row, column, tableItem );
659  }
660 }
661 
662 void QgsOWSSourceSelect::mSearchButton_clicked()
663 {
664  // clear results
665  mSearchTableWidget->clearContents();
666  mSearchTableWidget->setRowCount( 0 );
667 
668  // disable Add WMS button
669  mSearchAddButton->setEnabled( false );
670 
671  QApplication::setOverrideCursor( Qt::WaitCursor );
672 
673  QgsSettings settings;
674  // geopole.org (geopole.ch) 25.4.2012 : 503 Service Unavailable, archive: Recently added 20 Jul 2011
675  QString mySearchUrl = settings.value( QStringLiteral( "qgis/WMSSearchUrl" ), "http://geopole.org/wms/search?search=%1&type=rss" ).toString();
676  QUrl url( mySearchUrl.arg( mSearchTermLineEdit->text() ) );
677  QgsDebugMsg( url.toString() );
678 
679  QNetworkReply *r = QgsNetworkAccessManager::instance()->get( QNetworkRequest( url ) );
680  connect( r, &QNetworkReply::finished, this, &QgsOWSSourceSelect::searchFinished );
681 }
682 
683 void QgsOWSSourceSelect::searchFinished()
684 {
685  QApplication::restoreOverrideCursor();
686 
687  QNetworkReply *r = qobject_cast<QNetworkReply *>( sender() );
688  if ( !r )
689  return;
690 
691  if ( r->error() == QNetworkReply::NoError )
692  {
693  // parse results
694  QDomDocument doc( QStringLiteral( "RSS" ) );
695  QByteArray res = r->readAll();
696  QString error;
697  int line, column;
698  if ( doc.setContent( res, &error, &line, &column ) )
699  {
700  QDomNodeList list = doc.elementsByTagName( QStringLiteral( "item" ) );
701  mSearchTableWidget->setRowCount( list.size() );
702  for ( int i = 0; i < list.size(); i++ )
703  {
704  if ( list.item( i ).isElement() )
705  {
706  QDomElement item = list.item( i ).toElement();
707  addWmsListRow( item, i );
708  }
709  }
710 
711  mSearchTableWidget->resizeColumnsToContents();
712  }
713  else
714  {
715  QgsDebugMsg( QStringLiteral( "setContent failed" ) );
716  showStatusMessage( tr( "parse error at row %1, column %2: %3" ).arg( line ).arg( column ).arg( error ) );
717  }
718  }
719  else
720  {
721  showStatusMessage( tr( "network error: %1" ).arg( r->error() ) );
722  }
723 
724  r->deleteLater();
725 }
726 
727 void QgsOWSSourceSelect::mSearchTableWidget_itemSelectionChanged()
728 {
729  mSearchAddButton->setEnabled( mSearchTableWidget->currentRow() != -1 );
730 }
731 
732 void QgsOWSSourceSelect::mLayerUpButton_clicked()
733 {
734  QList<QTreeWidgetItem *> selectionList = mLayerOrderTreeWidget->selectedItems();
735  if ( selectionList.empty() )
736  {
737  return;
738  }
739  int selectedIndex = mLayerOrderTreeWidget->indexOfTopLevelItem( selectionList[0] );
740  if ( selectedIndex < 1 )
741  {
742  return; //item not existing or already on top
743  }
744 
745  QTreeWidgetItem *selectedItem = mLayerOrderTreeWidget->takeTopLevelItem( selectedIndex );
746  mLayerOrderTreeWidget->insertTopLevelItem( selectedIndex - 1, selectedItem );
747  mLayerOrderTreeWidget->clearSelection();
748  selectedItem->setSelected( true );
749 }
750 
751 void QgsOWSSourceSelect::mLayerDownButton_clicked()
752 {
753  QList<QTreeWidgetItem *> selectionList = mLayerOrderTreeWidget->selectedItems();
754  if ( selectionList.empty() )
755  {
756  return;
757  }
758  int selectedIndex = mLayerOrderTreeWidget->indexOfTopLevelItem( selectionList[0] );
759  if ( selectedIndex < 0 || selectedIndex > mLayerOrderTreeWidget->topLevelItemCount() - 2 )
760  {
761  return; //item not existing or already at bottom
762  }
763 
764  QTreeWidgetItem *selectedItem = mLayerOrderTreeWidget->takeTopLevelItem( selectedIndex );
765  mLayerOrderTreeWidget->insertTopLevelItem( selectedIndex + 1, selectedItem );
766  mLayerOrderTreeWidget->clearSelection();
767  selectedItem->setSelected( true );
768 }
769 
770 QList<QgsOWSSourceSelect::SupportedFormat> QgsOWSSourceSelect::providerFormats()
771 {
772  return QList<SupportedFormat>();
773 }
774 
776 {
777  return QStringList();
778 }
779 
781 {
782  return QStringList();
783 }
784 
786 {
787  return QStringList();
788 }
789 
790 void QgsOWSSourceSelect::updateButtons()
791 {
792 }
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 (embedded is for the data source manager dialog) ...
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.
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.
void saveGeometry(QWidget *widget, const QString &keyName)
Save the wigget geometry into settings.
A generic dialog to prompt the user for a Coordinate Reference System.
void setMessageAsHtml(const QString &msg)
bool restoreGeometry(QWidget *widget, const QString &keyName)
Restore the wigget geometry from settings.
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
void setMessageAsPlainText(const QString &msg)
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:69
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 showMessage(bool blocking=true) override
display the message to the user and deletes itself
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:438
This class represents a coordinate reference system (CRS).
A generic message view for displaying QGIS messages.
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...
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.