QGIS API Documentation  2.2.0-Valmiera
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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
24 #include "qgscontexthelp.h"
26 #include "qgsdatasourceuri.h"
28 #include "qgslogger.h"
30 #include "qgsmessageviewer.h"
31 #include "qgsnewhttpconnection.h"
33 #include "qgsproject.h"
34 #include "qgsproviderregistry.h"
35 #include "qgsowsconnection.h"
36 #include "qgsdataprovider.h"
37 #include "qgsowssourceselect.h"
39 
40 #include <QButtonGroup>
41 #include <QFileDialog>
42 #include <QRadioButton>
43 #include <QDomDocument>
44 #include <QHeaderView>
45 #include <QImageReader>
46 #include <QInputDialog>
47 #include <QMap>
48 #include <QMessageBox>
49 #include <QPicture>
50 #include <QSettings>
51 #include <QUrl>
52 #include <QValidator>
53 
54 #include <QNetworkRequest>
55 #include <QNetworkReply>
56 
57 QgsOWSSourceSelect::QgsOWSSourceSelect( QString service, QWidget * parent, Qt::WFlags fl, bool managerMode, bool embeddedMode )
58  : QDialog( parent, fl )
59  , mService( service )
60  , mManagerMode( managerMode )
61  , mEmbeddedMode( embeddedMode )
62  , mCurrentTileset( 0 )
63 {
64  setupUi( this );
65 
66  if ( mEmbeddedMode )
67  {
68  mDialogButtonBox->button( QDialogButtonBox::Close )->hide();
69  }
70 
71  setWindowTitle( tr( "Add Layer(s) from a %1 Server" ).arg( service ) );
72 
73  mAddButton = mDialogButtonBox->button( QDialogButtonBox::Apply );
74  mAddButton->setText( tr( "&Add" ) );
75  mAddButton->setToolTip( tr( "Add selected layers to map" ) );
76  mAddButton->setEnabled( false );
77 
78  clearCRS();
79 
80  mTileWidthLineEdit->setValidator( new QIntValidator( 0, 9999, this ) );
81  mTileHeightLineEdit->setValidator( new QIntValidator( 0, 9999, this ) );
82  mFeatureCountLineEdit->setValidator( new QIntValidator( 0, 9999, this ) );
83 
84  mCacheComboBox->addItem( tr( "Always cache" ), QNetworkRequest::AlwaysCache );
85  mCacheComboBox->addItem( tr( "Prefer cache" ), QNetworkRequest::PreferCache );
86  mCacheComboBox->addItem( tr( "Prefer network" ), QNetworkRequest::PreferNetwork );
87  mCacheComboBox->addItem( tr( "Always network" ), QNetworkRequest::AlwaysNetwork );
88 
89  if ( !mManagerMode )
90  {
91  connect( mAddButton, SIGNAL( clicked() ), this, SLOT( addClicked() ) );
92  //set the current project CRS if available
93  long currentCRS = QgsProject::instance()->readNumEntry( "SpatialRefSys", "/ProjectCRSID", -1 );
94  if ( currentCRS != -1 )
95  {
96  //convert CRS id to epsg
98  if ( currentRefSys.isValid() )
99  {
100  mSelectedCRS = currentRefSys.authid();
101  }
102  }
103  }
104  else
105  {
106  mTabWidget->removeTab( mTabWidget->indexOf( mLayerOrderTab ) );
107  mTabWidget->removeTab( mTabWidget->indexOf( mTilesetsTab ) );
108  mTimeWidget->hide();
109  mFormatWidget->hide();
110  mCRSWidget->hide();
111  mAddButton->hide();
112  mCacheWidget->hide();
113  }
114 
115  // set up the WMS connections we already know about
117 
118  QSettings settings;
119  QgsDebugMsg( "restoring geometry" );
120  restoreGeometry( settings.value( "/Windows/WMSSourceSelect/geometry" ).toByteArray() );
121 }
122 
124 {
125  QSettings settings;
126  QgsDebugMsg( "saving geometry" );
127  settings.setValue( "/Windows/WMSSourceSelect/geometry", saveGeometry() );
128 }
129 
131 {
132  mFormatComboBox->clear();
133  mFormatComboBox->setEnabled( false );
134 }
135 
137 {
138  QgsDebugMsg( "entered" );
139 
140  // A server may offer more similar formats, which are mapped
141  // to the same GDAL format, e.g. GeoTIFF and TIFF
142  // -> recreate always buttons for all available formats, enable supported
143 
144  clearFormats();
145 
146  if ( mProviderFormats.size() == 0 )
147  {
149  for ( int i = 0; i < mProviderFormats.size(); i++ )
150  {
151  // GDAL mime types may be image/tiff, image/png, ...
152  mMimeLabelMap.insert( mProviderFormats[i].format, mProviderFormats[i].label );
153  }
154  }
155 
156  // selectedLayersFormats may come in various forms:
157  // image/tiff, GTiff, GeoTIFF, TIFF, geotiff_int16, geotiff_rgb,
158  // PNG, GTOPO30, ARCGRID, IMAGEMOSAIC
159  // and even any string defined in server configuration, for example the
160  // value used in UMN Mapserver for OUTPUTFORMAT->NAME is used in
161  // WCS 1.0.0 SupportedFormats/Format
162 
163  // TODO: It is impossible to cover all possible formats comming from server
164  // -> enabled all formats, GDAL may be able to open them
165 
166  QMap<QString, QString> formatsMap;
167  formatsMap.insert( "geotiff", "tiff" );
168  formatsMap.insert( "gtiff", "tiff" );
169  formatsMap.insert( "tiff", "tiff" );
170  formatsMap.insert( "tif", "tiff" );
171  formatsMap.insert( "gif", "gif" );
172  formatsMap.insert( "jpeg", "jpeg" );
173  formatsMap.insert( "jpg", "jpeg" );
174  formatsMap.insert( "png", "png" );
175 
176  int preferred = -1;
177  QStringList layersFormats = selectedLayersFormats();
178  for ( int i = 0; i < layersFormats.size(); i++ )
179  {
180  QString format = layersFormats.value( i );
181  QgsDebugMsg( "server format = " + format );
182  QString simpleFormat = format.toLower().replace( "image/", "" ).replace( QRegExp( "_.*" ), "" );
183  QgsDebugMsg( "server simpleFormat = " + simpleFormat );
184  QString mimeFormat = "image/" + formatsMap.value( simpleFormat );
185  QgsDebugMsg( "server mimeFormat = " + mimeFormat );
186 
187  QString label = format;
188 
189  if ( mMimeLabelMap.contains( mimeFormat ) )
190  {
191  if ( format != mMimeLabelMap.value( mimeFormat ) )
192  {
193  // Append name of GDAL driver
194  label += " / " + mMimeLabelMap.value( mimeFormat );
195  }
196 
197  if ( simpleFormat.contains( "tif" ) ) // prefer *tif*
198  {
199  if ( preferred < 0 || simpleFormat.startsWith( "g" ) ) // prefer geotiff
200  {
201  preferred = i;
202  }
203  }
204  }
205  else
206  {
207  // We cannot always say that the format is not supported by GDAL because
208  // server can use strange names, but format itself is supported
209  QgsDebugMsg( QString( "format %1 unknown" ).arg( format ) );
210  }
211 
212  mFormatComboBox->insertItem( i, label );
213  }
214  // Set preferred
215  // TODO: all enabled for now, see above
216  preferred = preferred >= 0 ? preferred : 0;
217  mFormatComboBox->setCurrentIndex( preferred );
218 
219  mFormatComboBox->setEnabled( true );
220 }
221 
223 {
224  QgsDebugMsg( "entered" );
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 }
244 {
245  QgsNewHttpConnection *nc = new QgsNewHttpConnection( this, "/Qgis/connections-" + mService.toLower() + "/" );
246 
247  if ( nc->exec() )
248  {
250  emit connectionsChanged();
251  }
252 
253  delete nc;
254 }
255 
257 {
258  QgsNewHttpConnection *nc = new QgsNewHttpConnection( this, "/Qgis/connections-" + mService.toLower() + "/", mConnectionsComboBox->currentText() );
259 
260  if ( nc->exec() )
261  {
263  emit connectionsChanged();
264  }
265 
266  delete nc;
267 }
268 
270 {
271  QString msg = tr( "Are you sure you want to remove the %1 connection and all associated settings?" )
272  .arg( mConnectionsComboBox->currentText() );
273  QMessageBox::StandardButton result = QMessageBox::information( this, tr( "Confirm Delete" ), msg, QMessageBox::Ok | QMessageBox::Cancel );
274  if ( result == QMessageBox::Ok )
275  {
276  QgsOWSConnection::deleteConnection( mService, mConnectionsComboBox->currentText() );
277  mConnectionsComboBox->removeItem( mConnectionsComboBox->currentIndex() ); // populateConnectionList();
279  emit connectionsChanged();
280  }
281 }
282 
284 {
286  dlg.exec();
287 }
288 
290 {
291  QString fileName = QFileDialog::getOpenFileName( this, tr( "Load connections" ), ".",
292  tr( "XML files (*.xml *XML)" ) );
293  if ( fileName.isEmpty() )
294  {
295  return;
296  }
297 
299  dlg.exec();
301  emit connectionsChanged();
302 }
303 
305  int id,
306  const QStringList &names,
307  QMap<int, QgsNumericSortTreeWidgetItem *> &items,
308  int &layerAndStyleCount,
309  const QMap<int, int> &layerParents,
310  const QMap<int, QStringList> &layerParentNames )
311 {
312  QgsDebugMsg( QString( "id = %1 layerAndStyleCount = %2 names = %3 " ).arg( id ).arg( layerAndStyleCount ).arg( names.join( "," ) ) );
313  if ( items.contains( id ) )
314  return items[id];
315 
316 
318  if ( layerParents.contains( id ) )
319  {
320  // it has parent -> create first its parent
321  int parent = layerParents[ id ];
322  item = new QgsNumericSortTreeWidgetItem( createItem( parent, layerParentNames[ parent ], items, layerAndStyleCount, layerParents, layerParentNames ) );
323  }
324  else
325  item = new QgsNumericSortTreeWidgetItem( mLayersTreeWidget );
326 
327  item->setText( 0, QString::number( ++layerAndStyleCount ) );
328  item->setText( 1, names[0].simplified() );
329  item->setText( 2, names[1].simplified() );
330  item->setText( 3, names[2].simplified() );
331  item->setToolTip( 3, "<font color=black>" + names[2].simplified() + "</font>" );
332 
333  items[ id ] = item;
334 
335  return item;
336 }
337 
339 {
340 }
341 
343 {
344  QgsDebugMsg( "entered" );
345 
346  mLayersTreeWidget->clear();
347  clearFormats();
348  clearTimes();
349  clearCRS();
350 
351  mConnName = mConnectionsComboBox->currentText();
352 
353  QgsOWSConnection connection( mService, mConnectionsComboBox->currentText() );
354  //QgsDataProvider *theProvider = connection.provider( );
355  mConnectionInfo = connection.connectionInfo();
356  mUri = connection.uri();
357 
358  QApplication::setOverrideCursor( Qt::WaitCursor );
359 
360  QgsDebugMsg( "call populateLayerList" );
362 
363  QApplication::restoreOverrideCursor();
364 }
365 
367 {
368  QgsDebugMsg( "entered" );
369 }
370 
371 void QgsOWSSourceSelect::enableLayersForCrs( QTreeWidgetItem * )
372 {
373 }
374 
376 {
377  QStringList layers;
378  foreach ( QTreeWidgetItem *item, mLayersTreeWidget->selectedItems() )
379  {
380  QString layer = item->data( 0, Qt::UserRole + 0 ).toString();
381  if ( !layer.isEmpty() )
382  layers << layer;
383  }
384 
386  mySelector->setMessage();
388 
389  QString myDefaultCrs = QgsProject::instance()->readEntry( "SpatialRefSys", "/ProjectCrs", GEO_EPSG_CRS_AUTHID );
390  QgsCoordinateReferenceSystem defaultCRS;
391  if ( defaultCRS.createFromOgcWmsCrs( myDefaultCrs ) )
392  {
393  mySelector->setSelectedCrsId( defaultCRS.srsid() );
394  }
395 
396  if ( !mySelector->exec() )
397  return;
398 
399  mSelectedCRS = mySelector->selectedAuthId();
400  delete mySelector;
401 
402  mSelectedCRSLabel->setText( descriptionForAuthId( mSelectedCRS ) );
403 
404  for ( int i = 0; i < mLayersTreeWidget->topLevelItemCount(); i++ )
405  {
406  enableLayersForCrs( mLayersTreeWidget->topLevelItem( i ) );
407  }
408 
409  updateButtons();
410 }
411 
413 {
414 }
415 
417 {
418  QgsDebugMsg( "Entered" );
419  clearCRS();
421  mCRSLabel->setText( tr( "Coordinate Reference System (%n available)", "crs count", mSelectedLayersCRSs.count() ) + ":" );
422 
423  mChangeCRSButton->setDisabled( mSelectedLayersCRSs.isEmpty() );
424 
425  if ( !mSelectedLayersCRSs.isEmpty() )
426  {
427  // check whether current CRS is supported
428  // if not, use one of the available CRS
429  QString defaultCRS;
430  QSet<QString>::const_iterator it = mSelectedLayersCRSs.begin();
431  for ( ; it != mSelectedLayersCRSs.end(); ++it )
432  {
433  if ( it->compare( mSelectedCRS, Qt::CaseInsensitive ) == 0 )
434  break;
435 
436  // save first CRS in case the current CRS is not available
437  if ( it == mSelectedLayersCRSs.begin() )
438  defaultCRS = *it;
439 
440  // prefer value of DEFAULT_GEO_EPSG_CRS_ID if available
441  if ( *it == GEO_EPSG_CRS_AUTHID )
442  defaultCRS = *it;
443  }
444 
445  if ( it == mSelectedLayersCRSs.end() )
446  {
447  // not found
448  mSelectedCRS = defaultCRS;
449  }
450  mSelectedCRSLabel->setText( descriptionForAuthId( mSelectedCRS ) );
451  mChangeCRSButton->setEnabled( true );
452  }
453  QgsDebugMsg( "mSelectedCRS = " + mSelectedCRS );
454 }
455 
457 {
458  mCRSLabel->setText( tr( "Coordinate Reference System" ) + ":" );
459  mSelectedCRS = "";
460  mSelectedCRSLabel->setText( "" );
461  mChangeCRSButton->setEnabled( false );
462 }
463 
465 {
466  Q_UNUSED( item );
467 
468  QTableWidgetItem *rowItem = mTilesetsTableWidget->item( mTilesetsTableWidget->currentRow(), 0 );
469  bool wasSelected = mCurrentTileset == rowItem;
470 
471  mTilesetsTableWidget->blockSignals( true );
472  mTilesetsTableWidget->clearSelection();
473  if ( !wasSelected )
474  {
475  QgsDebugMsg( QString( "selecting current row %1" ).arg( mTilesetsTableWidget->currentRow() ) );
476  mTilesetsTableWidget->selectRow( mTilesetsTableWidget->currentRow() );
477  mCurrentTileset = rowItem;
478  }
479  else
480  {
481  mCurrentTileset = 0;
482  }
483  mTilesetsTableWidget->blockSignals( false );
484 
485  updateButtons();
486 }
487 
488 
489 
491 {
492  return mConnName;
493 }
494 
496 {
497  return mConnectionInfo;
498 }
499 
501 {
502  return selectedLayersFormats().value( mFormatComboBox->currentIndex() );
503 }
504 
505 QNetworkRequest::CacheLoadControl QgsOWSSourceSelect::selectedCacheLoadControl()
506 {
507  int cache = mCacheComboBox->itemData( mCacheComboBox->currentIndex() ).toInt();
508  return static_cast<QNetworkRequest::CacheLoadControl>( cache );
509 }
510 
512 {
513  return mSelectedCRS;
514 }
515 
517 {
518  return mTimeComboBox->currentText();
519 }
520 
522 {
523  QString toSelect = QgsOWSConnection::selectedConnection( mService );
524 
525  mConnectionsComboBox->setCurrentIndex( mConnectionsComboBox->findText( toSelect ) );
526 
527  if ( mConnectionsComboBox->currentIndex() < 0 )
528  {
529  if ( toSelect.isNull() )
530  mConnectionsComboBox->setCurrentIndex( 0 );
531  else
532  mConnectionsComboBox->setCurrentIndex( mConnectionsComboBox->count() - 1 );
533  }
534 
535  if ( mConnectionsComboBox->count() == 0 )
536  {
537  // No connections - disable various buttons
538  mConnectButton->setEnabled( false );
539  mEditButton->setEnabled( false );
540  mDeleteButton->setEnabled( false );
541  mSaveButton->setEnabled( false );
542  }
543  else
544  {
545  // Connections - enable various buttons
546  mConnectButton->setEnabled( true );
547  mEditButton->setEnabled( true );
548  mDeleteButton->setEnabled( true );
549  mSaveButton->setEnabled( true );
550  }
551 
552  QgsOWSConnection::setSelectedConnection( mService, mConnectionsComboBox->currentText() );
553 }
554 
555 void QgsOWSSourceSelect::showStatusMessage( QString const &theMessage )
556 {
557  mStatusLabel->setText( theMessage );
558 
559  // update the display of this widget
560  update();
561 }
562 
563 
564 void QgsOWSSourceSelect::showError( QString const &theTitle, QString const &theFormat, QString const &theError )
565 {
566  QgsMessageViewer * mv = new QgsMessageViewer( this );
567  mv->setWindowTitle( theTitle );
568 
569  if ( theFormat == "text/html" )
570  {
571  mv->setMessageAsHtml( theError );
572  }
573  else
574  {
575  mv->setMessageAsPlainText( tr( "Could not understand the response:\n%1" ).arg( theError ) );
576  }
577  mv->showMessage( true ); // Is deleted when closed
578 }
579 
581 {
582  // Remember which server was selected.
583  QgsOWSConnection::setSelectedConnection( mService, mConnectionsComboBox->currentText() );
584 }
585 
587 {
589 }
590 
592 {
593  if ( mCrsNames.contains( authId ) )
594  return mCrsNames[ authId ];
595 
597  qgisSrs.createFromOgcWmsCrs( authId );
598  mCrsNames.insert( authId, qgisSrs.description() );
599  return qgisSrs.description();
600 }
601 
603 {
604  QMap<QString, QString> exampleServers;
605  exampleServers["DM Solutions GMap"] = "http://www2.dmsolutions.ca/cgi-bin/mswms_gmap";
606  exampleServers["Lizardtech server"] = "http://wms.lizardtech.com/lizardtech/iserv/ows";
607  // Nice to have the qgis users map, but I'm not sure of the URL at the moment.
608  // exampleServers["Qgis users map"] = "http://qgis.org/wms.cgi";
609 
610  QSettings settings;
611  settings.beginGroup( "/Qgis/connections-" + mService.toLower() );
612  QMap<QString, QString>::const_iterator i = exampleServers.constBegin();
613  for ( ; i != exampleServers.constEnd(); ++i )
614  {
615  // Only do a server if it's name doesn't already exist.
616  QStringList keys = settings.childGroups();
617  if ( !keys.contains( i.key() ) )
618  {
619  QString path = i.key();
620  settings.setValue( path + "/url", i.value() );
621  }
622  }
623  settings.endGroup();
625 
626  QMessageBox::information( this, tr( "WMS proxies" ), "<p>" + tr( "Several WMS servers have "
627  "been added to the server list. Note that if "
628  "you access the internet via a web proxy, you will "
629  "need to set the proxy settings in the QGIS options dialog." ) + "</p>" );
630 }
631 
632 void QgsOWSSourceSelect::addWMSListRow( const QDomElement& item, int row )
633 {
634  QDomElement title = item.firstChildElement( "title" );
635  addWMSListItem( title, row, 0 );
636  QDomElement description = item.firstChildElement( "description" );
637  addWMSListItem( description, row, 1 );
638  QDomElement link = item.firstChildElement( "link" );
639  addWMSListItem( link, row, 2 );
640 }
641 
642 void QgsOWSSourceSelect::addWMSListItem( const QDomElement& el, int row, int column )
643 {
644  if ( !el.isNull() )
645  {
646  QTableWidgetItem* tableItem = new QTableWidgetItem( el.text() );
647  // TODO: add linebreaks to long tooltips?
648  tableItem->setToolTip( el.text() );
649  mSearchTableWidget->setItem( row, column, tableItem );
650  }
651 }
652 
654 {
655  // clear results
656  mSearchTableWidget->clearContents();
657  mSearchTableWidget->setRowCount( 0 );
658 
659  // disable Add WMS button
660  mSearchAddButton->setEnabled( false );
661 
662  QApplication::setOverrideCursor( Qt::WaitCursor );
663 
664  QSettings settings;
665  // geopole.org (geopole.ch) 25.4.2012 : 503 Service Unavailable, archive: Recently added 20 Jul 2011
666  QString mySearchUrl = settings.value( "/qgis/WMSSearchUrl", "http://geopole.org/wms/search?search=%1&type=rss" ).toString();
667  QUrl url( mySearchUrl.arg( mSearchTermLineEdit->text() ) );
668  QgsDebugMsg( url.toString() );
669 
670  QNetworkReply *r = QgsNetworkAccessManager::instance()->get( QNetworkRequest( url ) );
671  connect( r, SIGNAL( finished() ), SLOT( searchFinished() ) );
672 }
673 
675 {
676  QApplication::restoreOverrideCursor();
677 
678  QNetworkReply *r = qobject_cast<QNetworkReply *>( sender() );
679  if ( !r )
680  return;
681 
682  if ( r->error() == QNetworkReply::NoError )
683  {
684  // parse results
685  QDomDocument doc( "RSS" );
686  QByteArray res = r->readAll();
687  QString error;
688  int line, column;
689  if ( doc.setContent( res, &error, &line, &column ) )
690  {
691  QDomNodeList list = doc.elementsByTagName( "item" );
692  mSearchTableWidget->setRowCount( list.size() );
693  for ( int i = 0; i < list.size(); i++ )
694  {
695  if ( list.item( i ).isElement() )
696  {
697  QDomElement item = list.item( i ).toElement();
698  addWMSListRow( item, i );
699  }
700  }
701 
702  mSearchTableWidget->resizeColumnsToContents();
703  }
704  else
705  {
706  QgsDebugMsg( "setContent failed" );
707  showStatusMessage( tr( "parse error at row %1, column %2: %3" ).arg( line ).arg( column ).arg( error ) );
708  }
709  }
710  else
711  {
712  showStatusMessage( tr( "network error: %1" ).arg( r->error() ) );
713  }
714 
715  r->deleteLater();
716 }
717 
719 {
720  mSearchAddButton->setEnabled( mSearchTableWidget->currentRow() != -1 );
721 }
722 
724 {
725  QList<QTreeWidgetItem *> selectionList = mLayerOrderTreeWidget->selectedItems();
726  if ( selectionList.size() < 1 )
727  {
728  return;
729  }
730  int selectedIndex = mLayerOrderTreeWidget->indexOfTopLevelItem( selectionList[0] );
731  if ( selectedIndex < 1 )
732  {
733  return; //item not existing or already on top
734  }
735 
736  QTreeWidgetItem* selectedItem = mLayerOrderTreeWidget->takeTopLevelItem( selectedIndex );
737  mLayerOrderTreeWidget->insertTopLevelItem( selectedIndex - 1, selectedItem );
738  mLayerOrderTreeWidget->clearSelection();
739  selectedItem->setSelected( true );
740 }
741 
743 {
744  QList<QTreeWidgetItem *> selectionList = mLayerOrderTreeWidget->selectedItems();
745  if ( selectionList.size() < 1 )
746  {
747  return;
748  }
749  int selectedIndex = mLayerOrderTreeWidget->indexOfTopLevelItem( selectionList[0] );
750  if ( selectedIndex < 0 || selectedIndex > mLayerOrderTreeWidget->topLevelItemCount() - 2 )
751  {
752  return; //item not existing or already at bottom
753  }
754 
755  QTreeWidgetItem* selectedItem = mLayerOrderTreeWidget->takeTopLevelItem( selectedIndex );
756  mLayerOrderTreeWidget->insertTopLevelItem( selectedIndex + 1, selectedItem );
757  mLayerOrderTreeWidget->clearSelection();
758  selectedItem->setSelected( true );
759 }
760 
761 QList<QgsOWSSourceSelect::SupportedFormat> QgsOWSSourceSelect::providerFormats()
762 {
763  return QList<SupportedFormat>();
764 }
765 
767 {
768  return QStringList();
769 }
770 
772 {
773  return QStringList();
774 }
775 
777 {
778  return QStringList();
779 }
780 
782 {
783 }