Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show only available CRS in WMS layer selection widget #50572

Merged
merged 2 commits into from
Oct 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions python/gui/auto_generated/qgsprojectionselectionwidget.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,13 @@ Returns the title for the CRS selector dialog window.
.. seealso:: :py:func:`setDialogTitle`

.. versionadded:: 3.24
%End

void setFilter( const QList< QgsCoordinateReferenceSystem > &crses );
%Docstring
Sets a filtered list of CRSes to show in the widget.

.. versionadded:: 3.28
%End

signals:
Expand Down
38 changes: 34 additions & 4 deletions src/gui/qgsprojectionselectionwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,9 @@ QgsProjectionSelectionWidget::QgsProjectionSelectionWidget( QWidget *parent )
} );
}

QgsCoordinateReferenceSystem QgsProjectionSelectionWidget::crs() const
QgsCoordinateReferenceSystem QgsProjectionSelectionWidget::crsAtIndex( int index ) const
{
switch ( static_cast< CrsOption >( mCrsComboBox->currentData().toInt() ) )
switch ( static_cast< CrsOption >( mCrsComboBox->itemData( index ).toInt() ) )
{
case QgsProjectionSelectionWidget::LayerCrs:
return mLayerCrs;
Expand All @@ -108,7 +108,7 @@ QgsCoordinateReferenceSystem QgsProjectionSelectionWidget::crs() const
return mCrs;
case QgsProjectionSelectionWidget::RecentCrs:
{
const long srsid = mCrsComboBox->currentData( Qt::UserRole + 1 ).toLongLong();
const long srsid = mCrsComboBox->itemData( index, Qt::UserRole + 1 ).toLongLong();
const QgsCoordinateReferenceSystem crs = QgsCoordinateReferenceSystem::fromSrsId( srsid );
return crs;
}
Expand All @@ -118,6 +118,11 @@ QgsCoordinateReferenceSystem QgsProjectionSelectionWidget::crs() const
return mCrs;
}

QgsCoordinateReferenceSystem QgsProjectionSelectionWidget::crs() const
{
return crsAtIndex( mCrsComboBox->currentIndex() );
}

void QgsProjectionSelectionWidget::setOptionVisible( const QgsProjectionSelectionWidget::CrsOption option, const bool visible )
{
const int optionIndex = mCrsComboBox->findData( option );
Expand Down Expand Up @@ -200,9 +205,19 @@ bool QgsProjectionSelectionWidget::optionVisible( QgsProjectionSelectionWidget::
void QgsProjectionSelectionWidget::selectCrs()
{
QgsPanelWidget *panel = QgsPanelWidget::findParentPanel( this );

QSet< QString > ogcFilter;
ogcFilter.reserve( mFilter.size( ) );
for ( const QgsCoordinateReferenceSystem &crs : std::as_const( mFilter ) )
{
ogcFilter << crs.authid();
}

if ( panel && panel->dockMode() )
{
mActivePanel = new QgsCrsSelectionWidget( this );
if ( !ogcFilter.isEmpty() )
mActivePanel->setOgcWmsCrsFilter( ogcFilter );
if ( !mMessage.isEmpty() )
mActivePanel->setMessage( mMessage );
mActivePanel->setCrs( mCrs );
Expand Down Expand Up @@ -243,6 +258,8 @@ void QgsProjectionSelectionWidget::selectCrs()
QgsProjectionSelectionDialog dlg( this );
if ( !mMessage.isEmpty() )
dlg.setMessage( mMessage );
if ( !ogcFilter.isEmpty() )
dlg.setOgcWmsCrsFilter( ogcFilter );
dlg.setCrs( mCrs );
dlg.setWindowTitle( mDialogTitle );

Expand Down Expand Up @@ -348,6 +365,18 @@ QString QgsProjectionSelectionWidget::dialogTitle() const
return mDialogTitle;
}

void QgsProjectionSelectionWidget::setFilter( const QList<QgsCoordinateReferenceSystem> &crses )
{
mFilter = crses;


for ( int i = mCrsComboBox->count() - 1; i >= 0; --i )
{
if ( !mFilter.contains( crsAtIndex( i ) ) )
mCrsComboBox->removeItem( i );
}
}

void QgsProjectionSelectionWidget::setSourceEnsemble( const QString &ensemble )
{
if ( mSourceEnsemble == ensemble )
Expand Down Expand Up @@ -581,7 +610,7 @@ void QgsProjectionSelectionWidget::addRecentCrs()
continue;
}

if ( crs.isValid() )
if ( crs.isValid() && ( mFilter.isEmpty() || mFilter.contains( crs ) ) )
{
mCrsComboBox->addItem( crs.userFriendlyIdentifier(), QgsProjectionSelectionWidget::RecentCrs );
mCrsComboBox->setItemData( mCrsComboBox->count() - 1, QVariant( ( long long )srsid ), Qt::UserRole + 1 );
Expand Down Expand Up @@ -629,3 +658,4 @@ QgsMapLayer *QgsProjectionSelectionWidget::mapLayerFromMimeData( const QMimeData
}
return nullptr;
}

10 changes: 10 additions & 0 deletions src/gui/qgsprojectionselectionwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,13 @@ class GUI_EXPORT QgsProjectionSelectionWidget : public QWidget
*/
QString dialogTitle() const;

/**
* Sets a filtered list of CRSes to show in the widget.
*
* \since QGIS 3.28
*/
void setFilter( const QList< QgsCoordinateReferenceSystem > &crses );

signals:

/**
Expand Down Expand Up @@ -217,6 +224,8 @@ class GUI_EXPORT QgsProjectionSelectionWidget : public QWidget

QString mDialogTitle;

QList<QgsCoordinateReferenceSystem> mFilter;

void addNotSetOption();
void addProjectCrsOption();
void addDefaultCrsOption();
Expand All @@ -229,6 +238,7 @@ class GUI_EXPORT QgsProjectionSelectionWidget : public QWidget
void updateTooltip();

QgsMapLayer *mapLayerFromMimeData( const QMimeData *data ) const;
QgsCoordinateReferenceSystem crsAtIndex( int index ) const;

private slots:

Expand Down
9 changes: 9 additions & 0 deletions src/providers/wms/qgswmssourceselect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -872,6 +872,15 @@ void QgsWMSSourceSelect::lstLayers_itemSelectionChanged()
labelCoordRefSys->setDisabled( mCRSs.isEmpty() );
mCrsSelector->setDisabled( mCRSs.isEmpty() );

QList< QgsCoordinateReferenceSystem > crsFilter;
crsFilter.reserve( mCRSs.size() );
for ( const QString &crs : std::as_const( mCRSs ) )
{
crsFilter << QgsCoordinateReferenceSystem( crs );
}
if ( !crsFilter.isEmpty() )
mCrsSelector->setFilter( crsFilter );

if ( !layers.isEmpty() && !mCRSs.isEmpty() )
{

Expand Down
26 changes: 26 additions & 0 deletions tests/src/python/test_qgsprojectionselectionwidgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
QgsProjectionSelectionTreeWidget,
QgsProjectionSelectionDialog)
from qgis.core import QgsCoordinateReferenceSystem, QgsProject, QgsProjUtils
from qgis.PyQt.QtWidgets import QComboBox
from qgis.testing import start_app, unittest


Expand Down Expand Up @@ -114,6 +115,31 @@ def testShowingNotSetOption(self):
self.assertTrue(w.optionVisible(QgsProjectionSelectionWidget.CurrentCrs))
self.assertTrue(w.optionVisible(QgsProjectionSelectionWidget.CrsNotSet))

def testFilter(self):
w = QgsProjectionSelectionWidget()

w.setOptionVisible(QgsProjectionSelectionWidget.LayerCrs, True)
w.setLayerCrs(QgsCoordinateReferenceSystem('EPSG:3111'))
w.setCrs(QgsCoordinateReferenceSystem('EPSG:4326'))
w.setOptionVisible(QgsProjectionSelectionWidget.CurrentCrs, True)
QgsProject.instance().setCrs(QgsCoordinateReferenceSystem('EPSG:3113'))
w.setOptionVisible(QgsProjectionSelectionWidget.ProjectCrs, True)

self.assertIsInstance(w.children()[0], QComboBox)
cb = w.children()[0]
self.assertEqual(cb.count(), 4)
self.assertEqual(cb.itemText(0), 'EPSG:4326 - WGS 84')
self.assertEqual(cb.itemText(1), 'Default CRS: EPSG:4326 - WGS 84')
self.assertEqual(cb.itemText(2), 'Layer CRS: EPSG:3111 - GDA94 / Vicgrid')
self.assertEqual(cb.itemText(3), 'EPSG:3111 - GDA94 / Vicgrid')

w.setFilter([QgsCoordinateReferenceSystem('EPSG:3111')])
self.assertEqual(cb.count(), 2)
self.assertEqual(cb.itemText(0), 'Layer CRS: EPSG:3111 - GDA94 / Vicgrid')
self.assertEqual(cb.itemText(1), 'EPSG:3111 - GDA94 / Vicgrid')

QgsProject.instance().setCrs(QgsCoordinateReferenceSystem())

def testSignal(self):
w = QgsProjectionSelectionWidget()
w.show()
Expand Down