QGIS API Documentation  3.4.15-Madeira (e83d02e274)
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  Q_FOREACH ( QTreeWidgetItem *item, mLayersTreeWidget->selectedItems() )
390  {
391  QString layer = item->data( 0, Qt::UserRole + 0 ).toString();
392  if ( !layer.isEmpty() )
393  layers << layer;
394  }
395 
397  mySelector->setMessage( QString() );
398  mySelector->setOgcWmsCrsFilter( mSelectedLayersCRSs );
399 
401  if ( defaultCRS.isValid() )
402  {
403  mySelector->setCrs( defaultCRS );
404  }
405 
406  if ( !mySelector->exec() )
407  return;
408 
409  mSelectedCRS = mySelector->crs().authid();
410  delete mySelector;
411 
412  mSelectedCRSLabel->setText( descriptionForAuthId( mSelectedCRS ) );
413 
414  for ( int i = 0; i < mLayersTreeWidget->topLevelItemCount(); i++ )
415  {
416  enableLayersForCrs( mLayersTreeWidget->topLevelItem( i ) );
417  }
418 
419  updateButtons();
420 }
421 
422 void QgsOWSSourceSelect::mLayersTreeWidget_itemSelectionChanged()
423 {
424 }
425 
427 {
428  clearCrs();
429  mSelectedLayersCRSs = selectedLayersCrses().toSet();
430  mCRSLabel->setText( tr( "Coordinate Reference System (%n available)", "crs count", mSelectedLayersCRSs.count() ) + ':' );
431 
432  mChangeCRSButton->setDisabled( mSelectedLayersCRSs.isEmpty() );
433 
434  if ( !mSelectedLayersCRSs.isEmpty() )
435  {
436  // check whether current CRS is supported
437  // if not, use one of the available CRS
438  QString defaultCRS;
439  QSet<QString>::const_iterator it = mSelectedLayersCRSs.constBegin();
440  for ( ; it != mSelectedLayersCRSs.constEnd(); ++it )
441  {
442  if ( it->compare( mSelectedCRS, Qt::CaseInsensitive ) == 0 )
443  break;
444 
445  // save first CRS in case the current CRS is not available
446  if ( it == mSelectedLayersCRSs.constBegin() )
447  defaultCRS = *it;
448 
449  // prefer value of DEFAULT_GEO_EPSG_CRS_ID if available
450  if ( *it == GEO_EPSG_CRS_AUTHID )
451  defaultCRS = *it;
452  }
453 
454  if ( it == mSelectedLayersCRSs.constEnd() )
455  {
456  // not found
457  mSelectedCRS = defaultCRS;
458  }
459  mSelectedCRSLabel->setText( descriptionForAuthId( mSelectedCRS ) );
460  mChangeCRSButton->setEnabled( true );
461  }
462  QgsDebugMsg( "mSelectedCRS = " + mSelectedCRS );
463 }
464 
466 {
467  mCRSLabel->setText( tr( "Coordinate Reference System" ) + ':' );
468  mSelectedCRS.clear();
469  mSelectedCRSLabel->clear();
470  mChangeCRSButton->setEnabled( false );
471 }
472 
473 void QgsOWSSourceSelect::mTilesetsTableWidget_itemClicked( QTableWidgetItem *item )
474 {
475  Q_UNUSED( item );
476 
477  QTableWidgetItem *rowItem = mTilesetsTableWidget->item( mTilesetsTableWidget->currentRow(), 0 );
478  bool wasSelected = mCurrentTileset == rowItem;
479 
480  mTilesetsTableWidget->blockSignals( true );
481  mTilesetsTableWidget->clearSelection();
482  if ( !wasSelected )
483  {
484  QgsDebugMsg( QStringLiteral( "selecting current row %1" ).arg( mTilesetsTableWidget->currentRow() ) );
485  mTilesetsTableWidget->selectRow( mTilesetsTableWidget->currentRow() );
486  mCurrentTileset = rowItem;
487  }
488  else
489  {
490  mCurrentTileset = nullptr;
491  }
492  mTilesetsTableWidget->blockSignals( false );
493 
494  updateButtons();
495 }
496 
497 
498 
500 {
501  return mConnName;
502 }
503 
505 {
506  return mConnectionInfo;
507 }
508 
510 {
511  return selectedLayersFormats().value( mFormatComboBox->currentIndex() );
512 }
513 
514 QNetworkRequest::CacheLoadControl QgsOWSSourceSelect::selectedCacheLoadControl()
515 {
516  int cache = mCacheComboBox->currentData().toInt();
517  return static_cast<QNetworkRequest::CacheLoadControl>( cache );
518 }
519 
521 {
522  return mSelectedCRS;
523 }
524 
526 {
527  return mTimeComboBox->currentText();
528 }
529 
531 {
532  QString toSelect = QgsOwsConnection::selectedConnection( mService );
533 
534  mConnectionsComboBox->setCurrentIndex( mConnectionsComboBox->findText( toSelect ) );
535 
536  if ( mConnectionsComboBox->currentIndex() < 0 )
537  {
538  if ( toSelect.isNull() )
539  mConnectionsComboBox->setCurrentIndex( 0 );
540  else
541  mConnectionsComboBox->setCurrentIndex( mConnectionsComboBox->count() - 1 );
542  }
543 
544  if ( mConnectionsComboBox->count() == 0 )
545  {
546  // No connections - disable various buttons
547  mConnectButton->setEnabled( false );
548  mEditButton->setEnabled( false );
549  mDeleteButton->setEnabled( false );
550  mSaveButton->setEnabled( false );
551  }
552  else
553  {
554  // Connections - enable various buttons
555  mConnectButton->setEnabled( true );
556  mEditButton->setEnabled( true );
557  mDeleteButton->setEnabled( true );
558  mSaveButton->setEnabled( true );
559  }
560 
561  QgsOwsConnection::setSelectedConnection( mService, mConnectionsComboBox->currentText() );
562 }
563 
564 void QgsOWSSourceSelect::showStatusMessage( QString const &message )
565 {
566  mStatusLabel->setText( message );
567 
568  // update the display of this widget
569  update();
570 }
571 
572 
573 void QgsOWSSourceSelect::showError( QString const &title, QString const &format, QString const &error )
574 {
575  QgsMessageViewer *mv = new QgsMessageViewer( this );
576  mv->setWindowTitle( title );
577 
578  if ( format == QLatin1String( "text/html" ) )
579  {
580  mv->setMessageAsHtml( error );
581  }
582  else
583  {
584  mv->setMessageAsPlainText( tr( "Could not understand the response:\n%1" ).arg( error ) );
585  }
586  mv->showMessage( true ); // Is deleted when closed
587 }
588 
589 void QgsOWSSourceSelect::mConnectionsComboBox_activated( int )
590 {
591  // Remember which server was selected.
592  QgsOwsConnection::setSelectedConnection( mService, mConnectionsComboBox->currentText() );
593 }
594 
595 void QgsOWSSourceSelect::mAddDefaultButton_clicked()
596 {
598 }
599 
600 QString QgsOWSSourceSelect::descriptionForAuthId( const QString &authId )
601 {
602  if ( mCrsNames.contains( authId ) )
603  return mCrsNames[ authId ];
604 
606  mCrsNames.insert( authId, qgisSrs.description() );
607  return qgisSrs.description();
608 }
609 
611 {
612  QMap<QString, QString> exampleServers;
613  exampleServers[QStringLiteral( "DM Solutions GMap" )] = QStringLiteral( "http://www2.dmsolutions.ca/cgi-bin/mswms_gmap" );
614  exampleServers[QStringLiteral( "Lizardtech server" )] = QStringLiteral( "http://wms.lizardtech.com/lizardtech/iserv/ows" );
615  // Nice to have the qgis users map, but I'm not sure of the URL at the moment.
616  // exampleServers["Qgis users map"] = "http://qgis.org/wms.cgi";
617 
618  QgsSettings settings;
619  settings.beginGroup( "/qgis/connections-" + mService.toLower() );
620  QMap<QString, QString>::const_iterator i = exampleServers.constBegin();
621  for ( ; i != exampleServers.constEnd(); ++i )
622  {
623  // Only do a server if it's name doesn't already exist.
624  QStringList keys = settings.childGroups();
625  if ( !keys.contains( i.key() ) )
626  {
627  QString path = i.key();
628  settings.setValue( path + "/url", i.value() );
629  }
630  }
631  settings.endGroup();
633 
634  QMessageBox::information( this, tr( "Add WMS Servers" ), "<p>" + tr( "Several WMS servers have "
635  "been added to the server list. Note that if "
636  "you access the Internet via a web proxy, you will "
637  "need to set the proxy settings in the QGIS options dialog." ) + "</p>" );
638 }
639 
640 void QgsOWSSourceSelect::addWmsListRow( const QDomElement &item, int row )
641 {
642  QDomElement title = item.firstChildElement( QStringLiteral( "title" ) );
643  addWmsListItem( title, row, 0 );
644  QDomElement description = item.firstChildElement( QStringLiteral( "description" ) );
645  addWmsListItem( description, row, 1 );
646  QDomElement link = item.firstChildElement( QStringLiteral( "link" ) );
647  addWmsListItem( link, row, 2 );
648 }
649 
650 void QgsOWSSourceSelect::addWmsListItem( const QDomElement &el, int row, int column )
651 {
652  if ( !el.isNull() )
653  {
654  QTableWidgetItem *tableItem = new QTableWidgetItem( el.text() );
655  // TODO: add linebreaks to long tooltips?
656  tableItem->setToolTip( el.text() );
657  mSearchTableWidget->setItem( row, column, tableItem );
658  }
659 }
660 
661 void QgsOWSSourceSelect::mSearchButton_clicked()
662 {
663  // clear results
664  mSearchTableWidget->clearContents();
665  mSearchTableWidget->setRowCount( 0 );
666 
667  // disable Add WMS button
668  mSearchAddButton->setEnabled( false );
669 
670  QApplication::setOverrideCursor( Qt::WaitCursor );
671 
672  QgsSettings settings;
673  // geopole.org (geopole.ch) 25.4.2012 : 503 Service Unavailable, archive: Recently added 20 Jul 2011
674  QString mySearchUrl = settings.value( QStringLiteral( "qgis/WMSSearchUrl" ), "http://geopole.org/wms/search?search=%1&type=rss" ).toString();
675  QUrl url( mySearchUrl.arg( mSearchTermLineEdit->text() ) );
676  QgsDebugMsg( url.toString() );
677 
678  QNetworkReply *r = QgsNetworkAccessManager::instance()->get( QNetworkRequest( url ) );
679  connect( r, &QNetworkReply::finished, this, &QgsOWSSourceSelect::searchFinished );
680 }
681 
682 void QgsOWSSourceSelect::searchFinished()
683 {
684  QApplication::restoreOverrideCursor();
685 
686  QNetworkReply *r = qobject_cast<QNetworkReply *>( sender() );
687  if ( !r )
688  return;
689 
690  if ( r->error() == QNetworkReply::NoError )
691  {
692  // parse results
693  QDomDocument doc( QStringLiteral( "RSS" ) );
694  QByteArray res = r->readAll();
695  QString error;
696  int line, column;
697  if ( doc.setContent( res, &error, &line, &column ) )
698  {
699  QDomNodeList list = doc.elementsByTagName( QStringLiteral( "item" ) );
700  mSearchTableWidget->setRowCount( list.size() );
701  for ( int i = 0; i < list.size(); i++ )
702  {
703  if ( list.item( i ).isElement() )
704  {
705  QDomElement item = list.item( i ).toElement();
706  addWmsListRow( item, i );
707  }
708  }
709 
710  mSearchTableWidget->resizeColumnsToContents();
711  }
712  else
713  {
714  QgsDebugMsg( QStringLiteral( "setContent failed" ) );
715  showStatusMessage( tr( "parse error at row %1, column %2: %3" ).arg( line ).arg( column ).arg( error ) );
716  }
717  }
718  else
719  {
720  showStatusMessage( tr( "network error: %1" ).arg( r->error() ) );
721  }
722 
723  r->deleteLater();
724 }
725 
726 void QgsOWSSourceSelect::mSearchTableWidget_itemSelectionChanged()
727 {
728  mSearchAddButton->setEnabled( mSearchTableWidget->currentRow() != -1 );
729 }
730 
731 void QgsOWSSourceSelect::mLayerUpButton_clicked()
732 {
733  QList<QTreeWidgetItem *> selectionList = mLayerOrderTreeWidget->selectedItems();
734  if ( selectionList.empty() )
735  {
736  return;
737  }
738  int selectedIndex = mLayerOrderTreeWidget->indexOfTopLevelItem( selectionList[0] );
739  if ( selectedIndex < 1 )
740  {
741  return; //item not existing or already on top
742  }
743 
744  QTreeWidgetItem *selectedItem = mLayerOrderTreeWidget->takeTopLevelItem( selectedIndex );
745  mLayerOrderTreeWidget->insertTopLevelItem( selectedIndex - 1, selectedItem );
746  mLayerOrderTreeWidget->clearSelection();
747  selectedItem->setSelected( true );
748 }
749 
750 void QgsOWSSourceSelect::mLayerDownButton_clicked()
751 {
752  QList<QTreeWidgetItem *> selectionList = mLayerOrderTreeWidget->selectedItems();
753  if ( selectionList.empty() )
754  {
755  return;
756  }
757  int selectedIndex = mLayerOrderTreeWidget->indexOfTopLevelItem( selectionList[0] );
758  if ( selectedIndex < 0 || selectedIndex > mLayerOrderTreeWidget->topLevelItemCount() - 2 )
759  {
760  return; //item not existing or already at bottom
761  }
762 
763  QTreeWidgetItem *selectedItem = mLayerOrderTreeWidget->takeTopLevelItem( selectedIndex );
764  mLayerOrderTreeWidget->insertTopLevelItem( selectedIndex + 1, selectedItem );
765  mLayerOrderTreeWidget->clearSelection();
766  selectedItem->setSelected( true );
767 }
768 
769 QList<QgsOWSSourceSelect::SupportedFormat> QgsOWSSourceSelect::providerFormats()
770 {
771  return QList<SupportedFormat>();
772 }
773 
775 {
776  return QStringList();
777 }
778 
780 {
781  return QStringList();
782 }
783 
785 {
786  return QStringList();
787 }
788 
789 void QgsOWSSourceSelect::updateButtons()
790 {
791 }
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
QgsCoordinateReferenceSystem crs() const
Returns the CRS currently selected in the widget.
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)
#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.
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
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
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)
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)
QString uri(bool expandAuthConfig=true) const
Returns complete uri.
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)
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.
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.
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
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.
QgsProviderRegistry::WidgetMode widgetMode() const
Returns the widget mode.
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:411
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...
QString authid() const
Returns the authority identifier for the CRS.
void refresh() override
Triggered when the provider&#39;s connections need to be refreshed.
QString selectedTime()
Returns currently selected time.
QStringList childGroups() const
Returns a list of all key top-level groups that contain keys that can be read using the QSettings obj...
void addWmsListRow(const QDomElement &item, int row)
void clearFormats()
Clear previously set formats.
QString mService
Service name.
QString description() const
Returns the descriptive name of the CRS, e.g., "WGS 84" or "GDA 94 / Vicgrid94".
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.
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 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.