Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #35764 from alexbruy/ds-manager
Add XYZ tiles to Datasource manager dialog and Layers menu
  • Loading branch information
alexbruy committed Apr 15, 2020
2 parents d746b51 + 261553d commit 76872fb
Show file tree
Hide file tree
Showing 18 changed files with 415 additions and 5 deletions.
2 changes: 2 additions & 0 deletions images/images.qrc
Expand Up @@ -230,6 +230,7 @@
<file>themes/default/mActionAddWcsLayer.svg</file>
<file>themes/default/mActionAddWfsLayer.svg</file>
<file>themes/default/mActionAddWmsLayer.svg</file>
<file>themes/default/mActionAddXyzLayer.svg</file>
<file>themes/default/mActionAddGeonodeLayer.svg</file>
<file>themes/default/mActionAddDelimitedTextLayer.svg</file>
<file>themes/default/mActionAddVirtualLayer.svg</file>
Expand Down Expand Up @@ -524,6 +525,7 @@
<file>themes/default/mIconWcs.svg</file>
<file>themes/default/mIconWfs.svg</file>
<file>themes/default/mIconWms.svg</file>
<file>themes/default/mIconXyz.svg</file>
<file>themes/default/mIconZip.svg</file>
<file>themes/default/mIconZoom.svg</file>
<file>themes/default/mItemBookmark.svg</file>
Expand Down
1 change: 1 addition & 0 deletions images/themes/default/mActionAddXyzLayer.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions images/themes/default/mIconXyz.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions python/gui/auto_generated/qgisinterface.sip.in
Expand Up @@ -539,6 +539,13 @@ Returns the native draw action.
virtual QAction *actionAddRasterLayer() = 0;
virtual QAction *actionAddPgLayer() = 0;
virtual QAction *actionAddWmsLayer() = 0;

virtual QAction *actionAddXyzLayer() = 0;
%Docstring
Returns the native Add XYZ layer action.

.. versionadded:: 3.14
%End
virtual QAction *actionAddAfsLayer() = 0;
%Docstring
Returns the native Add ArcGIS FeatureServer action.
Expand Down
2 changes: 2 additions & 0 deletions src/app/qgisapp.cpp
Expand Up @@ -2661,6 +2661,7 @@ void QgisApp::createActions()
connect( mActionAddDb2Layer, &QAction::triggered, this, [ = ] { dataSourceManager( QStringLiteral( "DB2" ) ); } );
connect( mActionAddOracleLayer, &QAction::triggered, this, [ = ] { dataSourceManager( QStringLiteral( "oracle" ) ); } );
connect( mActionAddWmsLayer, &QAction::triggered, this, [ = ] { dataSourceManager( QStringLiteral( "wms" ) ); } );
connect( mActionAddXyzLayer, &QAction::triggered, this, [ = ] { dataSourceManager( QStringLiteral( "xyz" ) ); } );
connect( mActionAddWcsLayer, &QAction::triggered, this, [ = ] { dataSourceManager( QStringLiteral( "wcs" ) ); } );
connect( mActionAddWfsLayer, &QAction::triggered, this, [ = ] { dataSourceManager( QStringLiteral( "WFS" ) ); } );
connect( mActionAddAfsLayer, &QAction::triggered, this, [ = ] { dataSourceManager( QStringLiteral( "arcgisfeatureserver" ) ); } );
Expand Down Expand Up @@ -3969,6 +3970,7 @@ void QgisApp::setTheme( const QString &themeName )
mActionNewBookmark->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionNewBookmark.svg" ) ) );
mActionCustomProjection->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionCustomProjection.svg" ) ) );
mActionAddWmsLayer->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddWmsLayer.svg" ) ) );
mActionAddXyzLayer->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddXyzLayer.svg" ) ) );
mActionAddWcsLayer->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddWcsLayer.svg" ) ) );
mActionAddWfsLayer->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddWfsLayer.svg" ) ) );
mActionAddAfsLayer->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddAfsLayer.svg" ) ) );
Expand Down
1 change: 1 addition & 0 deletions src/app/qgisapp.h
Expand Up @@ -517,6 +517,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
QAction *actionAddPgLayer() { return mActionAddPgLayer; }
QAction *actionAddSpatiaLiteLayer() { return mActionAddSpatiaLiteLayer; }
QAction *actionAddWmsLayer() { return mActionAddWmsLayer; }
QAction *actionAddXyzLayer() { return mActionAddXyzLayer; }
QAction *actionAddWcsLayer() { return mActionAddWcsLayer; }
QAction *actionAddWfsLayer() { return mActionAddWfsLayer; }
QAction *actionAddAfsLayer() { return mActionAddAfsLayer; }
Expand Down
1 change: 1 addition & 0 deletions src/app/qgisappinterface.cpp
Expand Up @@ -679,6 +679,7 @@ QAction *QgisAppInterface::actionAddOgrLayer() { return qgis->actionAddOgrLayer(
QAction *QgisAppInterface::actionAddRasterLayer() { return qgis->actionAddRasterLayer(); }
QAction *QgisAppInterface::actionAddPgLayer() { return qgis->actionAddPgLayer(); }
QAction *QgisAppInterface::actionAddWmsLayer() { return qgis->actionAddWmsLayer(); }
QAction *QgisAppInterface::actionAddXyzLayer() { return qgis->actionAddXyzLayer(); }
QAction *QgisAppInterface::actionAddAfsLayer() { return qgis->actionAddAfsLayer(); }
QAction *QgisAppInterface::actionAddAmsLayer() { return qgis->actionAddAmsLayer(); }
QAction *QgisAppInterface::actionCopyLayerStyle() { return qgis->actionCopyLayerStyle(); }
Expand Down
1 change: 1 addition & 0 deletions src/app/qgisappinterface.h
Expand Up @@ -233,6 +233,7 @@ class APP_EXPORT QgisAppInterface : public QgisInterface
QAction *actionAddRasterLayer() override;
QAction *actionAddPgLayer() override;
QAction *actionAddWmsLayer() override;
QAction *actionAddXyzLayer() override;
QAction *actionAddAfsLayer() override;
QAction *actionAddAmsLayer() override;
QAction *actionCopyLayerStyle() override;
Expand Down
6 changes: 6 additions & 0 deletions src/gui/qgisinterface.h
Expand Up @@ -479,6 +479,12 @@ class GUI_EXPORT QgisInterface : public QObject
virtual QAction *actionAddRasterLayer() = 0;
virtual QAction *actionAddPgLayer() = 0;
virtual QAction *actionAddWmsLayer() = 0;

/**
* Returns the native Add XYZ layer action.
* \since QGIS 3.14
*/
virtual QAction *actionAddXyzLayer() = 0;
//! Returns the native Add ArcGIS FeatureServer action.
virtual QAction *actionAddAfsLayer() = 0;
//! Returns the native Add ArcGIS MapServer action.
Expand Down
1 change: 1 addition & 0 deletions src/providers/wms/CMakeLists.txt
Expand Up @@ -14,6 +14,7 @@ IF (WITH_GUI)
qgstilescalewidget.cpp
qgswmtsdimensions.cpp
qgsxyzconnectiondialog.cpp
qgsxyzsourceselect.cpp
)
ENDIF ()

Expand Down
3 changes: 2 additions & 1 deletion src/providers/wms/qgswmsdataitems.cpp
Expand Up @@ -576,7 +576,7 @@ QgsXyzTileRootItem::QgsXyzTileRootItem( QgsDataItem *parent, QString name, QStri
: QgsDataCollectionItem( parent, name, path, QStringLiteral( "WMS" ) )
{
mCapabilities |= Fast;
mIconName = QStringLiteral( "mIconWms.svg" );
mIconName = QStringLiteral( "mIconXyz.svg" );
populate();
}

Expand All @@ -600,6 +600,7 @@ QVector<QgsDataItem *> QgsXyzTileRootItem::createChildren()
QgsXyzLayerItem::QgsXyzLayerItem( QgsDataItem *parent, QString name, QString path, const QString &encodedUri )
: QgsLayerItem( parent, name, path, encodedUri, QgsLayerItem::Raster, QStringLiteral( "wms" ) )
{
mIconName = QStringLiteral( "mIconXyz.svg" );
setState( Populated );
}

Expand Down
17 changes: 16 additions & 1 deletion src/providers/wms/qgswmsprovidergui.cpp
Expand Up @@ -16,6 +16,7 @@
#include "qgswmsprovidergui.h"
#include "qgswmsprovider.h"
#include "qgswmssourceselect.h"
#include "qgsxyzsourceselect.h"
#include "qgssourceselectprovider.h"
#include "qgstilescalewidget.h"
#include "qgsproviderguimetadata.h"
Expand All @@ -37,6 +38,20 @@ class QgsWmsSourceSelectProvider : public QgsSourceSelectProvider
}
};

class QgsXyzSourceSelectProvider : public QgsSourceSelectProvider
{
public:

QString providerKey() const override { return QStringLiteral( "xyz" ); }
QString text() const override { return QStringLiteral( "XYZ" ); } // untranslatable string as acronym for this particular case. Use QObject::tr() otherwise
int ordering() const override { return QgsSourceSelectProvider::OrderRemoteProvider + 11; }
QIcon icon() const override { return QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddXyzLayer.svg" ) ); }
QgsAbstractDataSourceWidget *createDataSourceWidget( QWidget *parent = nullptr, Qt::WindowFlags fl = Qt::Widget, QgsProviderRegistry::WidgetMode widgetMode = QgsProviderRegistry::WidgetMode::Embedded ) const override
{
return new QgsXyzSourceSelect( parent, fl, widgetMode );
}
};

QgsWmsProviderGuiMetadata::QgsWmsProviderGuiMetadata()
: QgsProviderGuiMetadata( QgsWmsProvider::WMS_KEY )
{
Expand All @@ -45,7 +60,7 @@ QgsWmsProviderGuiMetadata::QgsWmsProviderGuiMetadata()
QList<QgsSourceSelectProvider *> QgsWmsProviderGuiMetadata::sourceSelectProviders()
{
QList<QgsSourceSelectProvider *> providers;
providers << new QgsWmsSourceSelectProvider;
providers << new QgsWmsSourceSelectProvider << new QgsXyzSourceSelectProvider;
return providers;
}

Expand Down
13 changes: 12 additions & 1 deletion src/providers/wms/qgsxyzconnection.cpp
Expand Up @@ -66,6 +66,18 @@ QStringList QgsXyzConnectionUtils::connectionList()
return connList;
}

QString QgsXyzConnectionUtils::selectedConnection()
{
QgsSettings settings;
return settings.value( QStringLiteral( "qgis/connections-xyz/selected" ) ).toString();
}

void QgsXyzConnectionUtils::setSelectedConnection( const QString &name )
{
QgsSettings settings;
return settings.setValue( QStringLiteral( "qgis/connections-xyz/selected" ), name );
}

QgsXyzConnection QgsXyzConnectionUtils::connection( const QString &name )
{
QgsSettings settings;
Expand Down Expand Up @@ -128,5 +140,4 @@ void QgsXyzConnectionUtils::addConnection( const QgsXyzConnection &conn )
{
settings.setValue( QStringLiteral( "hidden" ), false );
}

}
6 changes: 6 additions & 0 deletions src/providers/wms/qgsxyzconnection.h
Expand Up @@ -46,6 +46,12 @@ class QgsXyzConnectionUtils
//! Returns list of existing connections, unless the hidden ones
static QStringList connectionList();

//! Returns last used connection
static QString selectedConnection();

//! Saves name of the last used connection
static void setSelectedConnection( const QString &connName );

//! Returns connection details
static QgsXyzConnection connection( const QString &name );

Expand Down
145 changes: 145 additions & 0 deletions src/providers/wms/qgsxyzsourceselect.cpp
@@ -0,0 +1,145 @@
/***************************************************************************
qgsxyzsourceselect.cpp
---------------------------------
begin : April 2020
copyright : (C) 2020 by Alexander Bruy
email : alexander dot bruy at gmail dot com
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgshelp.h"
#include "qgsgui.h"
#include "qgsmanageconnectionsdialog.h"
#include "qgsxyzsourceselect.h"
#include "qgsxyzconnection.h"
#include "qgsxyzconnectiondialog.h"

#include <QFileDialog>
#include <QMessageBox>

QgsXyzSourceSelect::QgsXyzSourceSelect( QWidget *parent, Qt::WindowFlags fl, QgsProviderRegistry::WidgetMode theWidgetMode )
: QgsAbstractDataSourceWidget( parent, fl, theWidgetMode )
{
setupUi( this );
QgsGui::enableAutoGeometryRestore( this );

connect( btnNew, &QPushButton::clicked, this, &QgsXyzSourceSelect::btnNew_clicked );
connect( btnEdit, &QPushButton::clicked, this, &QgsXyzSourceSelect::btnEdit_clicked );
connect( btnDelete, &QPushButton::clicked, this, &QgsXyzSourceSelect::btnDelete_clicked );
connect( btnSave, &QPushButton::clicked, this, &QgsXyzSourceSelect::btnSave_clicked );
connect( btnLoad, &QPushButton::clicked, this, &QgsXyzSourceSelect::btnLoad_clicked );
connect( cmbConnections, &QComboBox::currentTextChanged, this, &QgsXyzSourceSelect::cmbConnections_currentTextChanged );
connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsXyzSourceSelect::showHelp );
setupButtons( buttonBox );
populateConnectionList();
}

void QgsXyzSourceSelect::btnNew_clicked()
{
QgsXyzConnectionDialog nc( this );
if ( nc.exec() )
{
QgsXyzConnectionUtils::addConnection( nc.connection() );
populateConnectionList();
emit connectionsChanged();
}
}

void QgsXyzSourceSelect::btnEdit_clicked()
{
QgsXyzConnectionDialog nc( this );
nc.setConnection( QgsXyzConnectionUtils::connection( cmbConnections->currentText() ) );
if ( nc.exec() )
{
QgsXyzConnectionUtils::addConnection( nc.connection() );
populateConnectionList();
emit connectionsChanged();
}
}

void QgsXyzSourceSelect::btnDelete_clicked()
{
QString msg = tr( "Are you sure you want to remove the %1 connection and all associated settings?" )
.arg( cmbConnections->currentText() );
if ( QMessageBox::Yes != QMessageBox::question( this, tr( "Confirm Delete" ), msg, QMessageBox::Yes | QMessageBox::No ) )
return;

QgsXyzConnectionUtils::deleteConnection( cmbConnections->currentText() );

populateConnectionList();
emit connectionsChanged();
}

void QgsXyzSourceSelect::btnSave_clicked()
{
QgsManageConnectionsDialog dlg( this, QgsManageConnectionsDialog::Export, QgsManageConnectionsDialog::XyzTiles );
dlg.exec();
}

void QgsXyzSourceSelect::btnLoad_clicked()
{
QString fileName = QFileDialog::getOpenFileName( this, tr( "Load Connections" ), QDir::homePath(),
tr( "XML files (*.xml *.XML)" ) );
if ( fileName.isEmpty() )
{
return;
}

QgsManageConnectionsDialog dlg( this, QgsManageConnectionsDialog::Import, QgsManageConnectionsDialog::XyzTiles, fileName );
dlg.exec();
populateConnectionList();
}

void QgsXyzSourceSelect::addButtonClicked()
{
emit addRasterLayer( QgsXyzConnectionUtils::connection( cmbConnections->currentText() ).encodedUri(), cmbConnections->currentText(), QStringLiteral( "wms" ) );
}

void QgsXyzSourceSelect::populateConnectionList()
{
cmbConnections->blockSignals( true );
cmbConnections->clear();
cmbConnections->addItems( QgsXyzConnectionUtils::connectionList() );
cmbConnections->blockSignals( false );

setConnectionListPosition();

btnEdit->setDisabled( cmbConnections->count() == 0 );
btnDelete->setDisabled( cmbConnections->count() == 0 );
cmbConnections->setDisabled( cmbConnections->count() == 0 );
}

void QgsXyzSourceSelect::setConnectionListPosition()
{
QString toSelect = QgsXyzConnectionUtils::selectedConnection();

cmbConnections->setCurrentIndex( cmbConnections->findText( toSelect ) );

if ( cmbConnections->currentIndex() < 0 )
{
if ( toSelect.isNull() )
cmbConnections->setCurrentIndex( 0 );
else
cmbConnections->setCurrentIndex( cmbConnections->count() - 1 );
}
emit enableButtons( !cmbConnections->currentText().isEmpty() );
}

void QgsXyzSourceSelect::cmbConnections_currentTextChanged( const QString &text )
{
QgsXyzConnectionUtils::setSelectedConnection( text );
emit enableButtons( !text.isEmpty() );
}

void QgsXyzSourceSelect::showHelp()
{
QgsHelp::openHelp( QStringLiteral( "managing_data_source/opening_data.html#using-xyz-tile-services" ) );
}

0 comments on commit 76872fb

Please sign in to comment.