Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Allow a "no projection" option in projection selection widget/dialog
This option allows users to select "no projection", when
there's no suitable projection to select...
  • Loading branch information
nyalldawson committed Mar 1, 2017
1 parent 9dd71b8 commit 3c7c65e
Show file tree
Hide file tree
Showing 8 changed files with 149 additions and 6 deletions.
4 changes: 4 additions & 0 deletions python/gui/qgsprojectionselectiondialog.sip
Expand Up @@ -18,6 +18,10 @@ class QgsProjectionSelectionDialog : QDialog //, private Ui::QgsGenericProjectio

void setMessage( const QString& message );

void setShowNoProjection( bool show );

bool showNoProjection() const;

public slots:


Expand Down
8 changes: 7 additions & 1 deletion python/gui/qgsprojectionselectiontreewidget.sip
Expand Up @@ -5,12 +5,18 @@ class QgsProjectionSelectionTreeWidget : QWidget
%End

public:
QgsProjectionSelectionTreeWidget( QWidget* parent /TransferThis/ );
QgsProjectionSelectionTreeWidget( QWidget* parent /TransferThis/ = 0 );

~QgsProjectionSelectionTreeWidget();

QgsCoordinateReferenceSystem crs() const;

void setShowNoProjection( bool show );

bool showNoProjection() const;

bool hasValidSelection() const;

public slots:

void setCrs( const QgsCoordinateReferenceSystem& crs );
Expand Down
10 changes: 10 additions & 0 deletions src/gui/qgsprojectionselectiondialog.cpp
Expand Up @@ -59,6 +59,16 @@ void QgsProjectionSelectionDialog::setMessage( const QString& message )
textEdit->show();
}

void QgsProjectionSelectionDialog::setShowNoProjection( bool show )
{
projectionSelector->setShowNoProjection( show );
}

bool QgsProjectionSelectionDialog::showNoProjection() const
{
return projectionSelector->showNoProjection();
}

QgsProjectionSelectionDialog::~QgsProjectionSelectionDialog()
{
QSettings settings;
Expand Down
16 changes: 16 additions & 0 deletions src/gui/qgsprojectionselectiondialog.h
Expand Up @@ -76,6 +76,22 @@ class GUI_EXPORT QgsProjectionSelectionDialog : public QDialog, private Ui::QgsG
*/
void setMessage( const QString& message );

/**
* Sets whether a "no/invalid" projection option should be shown. If this
* option is selected, calling crs() will return an invalid QgsCoordinateReferenceSystem.
* @see showNoProjection()
* @note added in QGIS 3.0
*/
void setShowNoProjection( bool show );

/**
* Returns whether the "no/invalid" projection option is shown. If this
* option is selected, calling crs() will return an invalid QgsCoordinateReferenceSystem.
* @note added in QGIS 3.0
* @see setShowNoProjection()
*/
bool showNoProjection() const;

public slots:

/**
Expand Down
34 changes: 33 additions & 1 deletion src/gui/qgsprojectionselectiontreewidget.cpp
Expand Up @@ -64,6 +64,9 @@ QgsProjectionSelectionTreeWidget::QgsProjectionSelectionTreeWidget( QWidget* par
lstRecent->setColumnHidden( QgisCrsIdColumn, true );

mRecentProjections = QgsCoordinateReferenceSystem::recentProjections();

mNoProjItem = new QTreeWidgetItem( lstCoordinateSystems, QStringList( tr( "No projection" ) ) );
mNoProjItem->setHidden( true );
}

QgsProjectionSelectionTreeWidget::~QgsProjectionSelectionTreeWidget()
Expand Down Expand Up @@ -268,7 +271,14 @@ QString QgsProjectionSelectionTreeWidget::selectedName()

void QgsProjectionSelectionTreeWidget::setCrs( const QgsCoordinateReferenceSystem& crs )
{
applySelection( AuthidColumn, crs.authid() );
if ( !crs.isValid() )
{
lstCoordinateSystems->setCurrentItem( mNoProjItem );
}
else
{
applySelection( AuthidColumn, crs.authid() );
}
}

// Returns the whole proj4 string for the selected projection node
Expand Down Expand Up @@ -414,13 +424,35 @@ QString QgsProjectionSelectionTreeWidget::getSelectedExpression( const QString&

QgsCoordinateReferenceSystem QgsProjectionSelectionTreeWidget::crs() const
{
if ( lstCoordinateSystems->currentItem() == mNoProjItem )
return QgsCoordinateReferenceSystem();

int srid = getSelectedExpression( QStringLiteral( "srs_id" ) ).toLong();
if ( srid >= USER_CRS_START_ID )
return QgsCoordinateReferenceSystem::fromOgcWmsCrs( QString( "USER:%1" ).arg( srid ) );
else
return QgsCoordinateReferenceSystem::fromOgcWmsCrs( getSelectedExpression( QStringLiteral( "upper(auth_name||':'||auth_id)" ) ) );
}

void QgsProjectionSelectionTreeWidget::setShowNoProjection( bool show )
{
mNoProjItem->setHidden( !show );
}

bool QgsProjectionSelectionTreeWidget::showNoProjection() const
{
return !mNoProjItem->isHidden();
}

bool QgsProjectionSelectionTreeWidget::hasValidSelection() const
{
QTreeWidgetItem* item = lstCoordinateSystems->currentItem();
if ( item == mNoProjItem )
return true;
else
return item && !item->text( QgisCrsIdColumn ).isEmpty();
}

long QgsProjectionSelectionTreeWidget::selectedCrsId()
{
QTreeWidgetItem* item = lstCoordinateSystems->currentItem();
Expand Down
26 changes: 26 additions & 0 deletions src/gui/qgsprojectionselectiontreewidget.h
Expand Up @@ -56,6 +56,30 @@ class GUI_EXPORT QgsProjectionSelectionTreeWidget : public QWidget, private Ui::
*/
QgsCoordinateReferenceSystem crs() const;

/**
* Sets whether a "no/invalid" projection option should be shown. If this
* option is selected, calling crs() will return an invalid QgsCoordinateReferenceSystem.
* @see showNoProjection()
* @note added in QGIS 3.0
*/
void setShowNoProjection( bool show );

/**
* Returns whether the "no/invalid" projection option is shown. If this
* option is selected, calling crs() will return an invalid QgsCoordinateReferenceSystem.
* @note added in QGIS 3.0
* @see setShowNoProjection()
*/
bool showNoProjection() const;

/**
* Returns true if the current selection in the widget is a valid choice. Valid
* selections include any projection and also the "no/invalid projection" option
* (if setShowNoProjection() was called). Invalid selections are the group
* headers (such as "Geographic Coordinate Systems"
*/
bool hasValidSelection() const;

public slots:

/**
Expand Down Expand Up @@ -189,6 +213,8 @@ class GUI_EXPORT QgsProjectionSelectionTreeWidget : public QWidget, private Ui::
QTreeWidgetItem *mGeoList = nullptr;
//! PROJCS node
QTreeWidgetItem *mProjList = nullptr;
//! "No projection" item
QTreeWidgetItem* mNoProjItem = nullptr;

//! Users custom coordinate system file
QString mCustomCsFile;
Expand Down
2 changes: 1 addition & 1 deletion tests/src/python/CMakeLists.txt
Expand Up @@ -90,7 +90,7 @@ ADD_PYTHON_TEST(PyQgsPanelWidgetStack test_qgspanelwidgetstack.py)
ADD_PYTHON_TEST(PyQgsPoint test_qgspoint.py)
ADD_PYTHON_TEST(PyQgsPointClusterRenderer test_qgspointclusterrenderer.py)
ADD_PYTHON_TEST(PyQgsPointDisplacementRenderer test_qgspointdisplacementrenderer.py)
ADD_PYTHON_TEST(PyQgsProjectionSelectionWidget test_qgsprojectionselectionwidget.py)
ADD_PYTHON_TEST(PyQgsProjectionSelectionWidgets test_qgsprojectionselectionwidgets.py)
ADD_PYTHON_TEST(PyQgsRangeWidgets test_qgsrangewidgets.py)
ADD_PYTHON_TEST(PyQgsRasterFileWriter test_qgsrasterfilewriter.py)
ADD_PYTHON_TEST(PyQgsRasterLayer test_qgsrasterlayer.py)
Expand Down
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
"""QGIS Unit tests for QgsProjectionSelectionWidget.
"""QGIS Unit tests for various projection selection widgets.
.. note:: 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
Expand All @@ -14,14 +14,16 @@

import qgis # NOQA

from qgis.gui import QgsProjectionSelectionWidget
from qgis.gui import (QgsProjectionSelectionWidget,
QgsProjectionSelectionTreeWidget,
QgsProjectionSelectionDialog)
from qgis.core import QgsCoordinateReferenceSystem, QgsProject
from qgis.testing import start_app, unittest
from qgis.PyQt.QtGui import QColor
start_app()


class TestQgsProjectionSelectionWidget(unittest.TestCase):
class TestQgsProjectionSelectionWidgets(unittest.TestCase):

def testShowingHiding(self):
""" test showing and hiding options """
Expand Down Expand Up @@ -112,6 +114,53 @@ def testShowingNotSetOption(self):
self.assertTrue(w.optionVisible(QgsProjectionSelectionWidget.CurrentCrs))
self.assertTrue(w.optionVisible(QgsProjectionSelectionWidget.CrsNotSet))

def testTreeWidgetGettersSetters(self):
""" basic tests for QgsProjectionSelectionTreeWidget """
w = QgsProjectionSelectionTreeWidget()
w.show()
self.assertFalse(w.hasValidSelection())
w.setCrs(QgsCoordinateReferenceSystem('EPSG:3111'))
self.assertEqual(w.crs().authid(),'EPSG:3111')
self.assertTrue(w.hasValidSelection())


def testTreeWidgetNotSetOption(self):
""" test allowing no projection option for QgsProjectionSelectionTreeWidget """
w = QgsProjectionSelectionTreeWidget()
w.show()
w.setShowNoProjection(True)
self.assertTrue(w.showNoProjection())
w.setShowNoProjection(False)
self.assertFalse(w.showNoProjection())

w.setShowNoProjection(True)
# no projection should be a valid selection
w.setCrs(QgsCoordinateReferenceSystem())
self.assertTrue(w.hasValidSelection())
self.assertFalse(w.crs().isValid())

def testDialogGettersSetters(self):
""" basic tests for QgsProjectionSelectionTreeWidget """
w = QgsProjectionSelectionDialog()
w.show()
w.setCrs(QgsCoordinateReferenceSystem('EPSG:3111'))
self.assertEqual(w.crs().authid(),'EPSG:3111')

def testDialogNotSetOption(self):
""" test allowing no projection option for QgsProjectionSelectionTreeWidget """
w = QgsProjectionSelectionDialog()
w.show()
w.setShowNoProjection(True)
self.assertTrue(w.showNoProjection())
w.setShowNoProjection(False)
self.assertFalse(w.showNoProjection())

w.setShowNoProjection(True)
w.setCrs(QgsCoordinateReferenceSystem())
self.assertFalse(w.crs().isValid())




if __name__ == '__main__':
unittest.main()

0 comments on commit 3c7c65e

Please sign in to comment.