From ec49341f85f9359682aee578d40f90a06a7cfb71 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Wed, 16 Nov 2016 12:13:09 +1000 Subject: [PATCH] Allow showing CRS in QgsMapLayerComboBox --- python/core/qgsmaplayermodel.sip | 22 ++++++++++++++---- python/gui/qgsmaplayercombobox.sip | 14 ++++++++++++ src/core/qgsmaplayermodel.cpp | 25 ++++++++++++++++++-- src/core/qgsmaplayermodel.h | 28 +++++++++++++++++++---- src/gui/qgsmaplayercombobox.cpp | 10 ++++++++ src/gui/qgsmaplayercombobox.h | 16 +++++++++++++ tests/src/python/test_qgsmaplayermodel.py | 22 +++++++++++++++++- 7 files changed, 126 insertions(+), 11 deletions(-) diff --git a/python/core/qgsmaplayermodel.sip b/python/core/qgsmaplayermodel.sip index 655d7b18ac8..d746c37be4f 100644 --- a/python/core/qgsmaplayermodel.sip +++ b/python/core/qgsmaplayermodel.sip @@ -54,6 +54,20 @@ class QgsMapLayerModel : QAbstractItemModel */ bool allowEmptyLayer() const; + /** + * Sets whether the CRS of layers is also included in the model's display role. + * @see showCrs() + * @note added in QGIS 3.0 + */ + void setShowCrs( bool showCrs ); + + /** + * Returns true if the model includes layer's CRS in the display role. + * @see setShowCrs() + * @note added in QGIS 3.0 + */ + bool showCrs() const; + /** * @brief layersChecked returns the list of layers which are checked (or unchecked) */ @@ -75,15 +89,15 @@ class QgsMapLayerModel : QAbstractItemModel public: QModelIndex index( int row, int column, const QModelIndex &parent = QModelIndex() ) const; QModelIndex parent( const QModelIndex &child ) const; - int rowCount( const QModelIndex &parent ) const; - int columnCount( const QModelIndex &parent ) const; - QVariant data( const QModelIndex &index, int role ) const; + int rowCount( const QModelIndex &parent = QModelIndex() ) const; + int columnCount( const QModelIndex &parent = QModelIndex() ) const; + QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const; /** * Returns strings for all roles supported by this model. */ QHash roleNames() const; - bool setData( const QModelIndex &index, const QVariant &value, int role ); + bool setData( const QModelIndex &index, const QVariant &value, int role = Qt::DisplayRole ); Qt::ItemFlags flags( const QModelIndex &index ) const; }; diff --git a/python/gui/qgsmaplayercombobox.sip b/python/gui/qgsmaplayercombobox.sip index 4127bc084f2..fbef794a780 100644 --- a/python/gui/qgsmaplayercombobox.sip +++ b/python/gui/qgsmaplayercombobox.sip @@ -42,6 +42,20 @@ class QgsMapLayerComboBox : QComboBox */ bool allowEmptyLayer() const; + /** + * Sets whether the CRS of layers is also included in the combo box text. + * @see showCrs() + * @note added in QGIS 3.0 + */ + void setShowCrs( bool showCrs ); + + /** + * Returns true if the combo box shows the layer's CRS. + * @see setShowCrs() + * @note added in QGIS 3.0 + */ + bool showCrs() const; + /** Returns the current layer selected in the combo box. * @see layer */ diff --git a/src/core/qgsmaplayermodel.cpp b/src/core/qgsmaplayermodel.cpp index 97129f720a7..a244b86672a 100644 --- a/src/core/qgsmaplayermodel.cpp +++ b/src/core/qgsmaplayermodel.cpp @@ -27,6 +27,7 @@ QgsMapLayerModel::QgsMapLayerModel( const QList& layers, QObject , mLayersChecked( QMap() ) , mItemCheckable( false ) , mAllowEmpty( false ) + , mShowCrs( false ) { connect( QgsMapLayerRegistry::instance(), SIGNAL( layersWillBeRemoved( QStringList ) ), this, SLOT( removeLayers( QStringList ) ) ); addLayers( layers ); @@ -37,6 +38,7 @@ QgsMapLayerModel::QgsMapLayerModel( QObject *parent ) , mLayersChecked( QMap() ) , mItemCheckable( false ) , mAllowEmpty( false ) + , mShowCrs( false ) { connect( QgsMapLayerRegistry::instance(), SIGNAL( layersAdded( QList ) ), this, SLOT( addLayers( QList ) ) ); connect( QgsMapLayerRegistry::instance(), SIGNAL( layersWillBeRemoved( QStringList ) ), this, SLOT( removeLayers( QStringList ) ) ); @@ -54,7 +56,7 @@ void QgsMapLayerModel::checkAll( Qt::CheckState checkState ) { mLayersChecked[key] = checkState; } - emit dataChanged( index( 0, 0 ), index( mLayers.length() - 1, 0 ) ); + emit dataChanged( index( 0, 0 ), index( rowCount() - 1, 0 ) ); } void QgsMapLayerModel::setAllowEmptyLayer( bool allowEmpty ) @@ -76,6 +78,15 @@ void QgsMapLayerModel::setAllowEmptyLayer( bool allowEmpty ) } } +void QgsMapLayerModel::setShowCrs( bool showCrs ) +{ + if ( mShowCrs == showCrs ) + return; + + mShowCrs = showCrs; + emit dataChanged( index( 0, 0 ), index( rowCount() - 1, 0 ), QVector() << Qt::DisplayRole ); +} + QList QgsMapLayerModel::layersChecked( Qt::CheckState checkState ) { QList layers; @@ -183,7 +194,17 @@ QVariant QgsMapLayerModel::data( const QModelIndex &index, int role ) const return QVariant(); QgsMapLayer* layer = static_cast( index.internalPointer() ); - return layer ? layer->name() : QVariant(); + if ( !layer ) + return QVariant(); + + if ( !mShowCrs ) + { + return layer->name(); + } + else + { + return tr( "%1 [%2]" ).arg( layer->name(), layer->crs().authid() ); + } } if ( role == LayerIdRole ) diff --git a/src/core/qgsmaplayermodel.h b/src/core/qgsmaplayermodel.h index 75ad02f6f07..0f1ac065625 100644 --- a/src/core/qgsmaplayermodel.h +++ b/src/core/qgsmaplayermodel.h @@ -32,6 +32,11 @@ class QgsMapLayer; class CORE_EXPORT QgsMapLayerModel : public QAbstractItemModel { Q_OBJECT + + Q_PROPERTY( bool allowEmptyLayer READ allowEmptyLayer WRITE setAllowEmptyLayer ) + Q_PROPERTY( bool showCrs READ showCrs WRITE setShowCrs ) + Q_PROPERTY( bool itemsCheckable READ itemsCheckable WRITE setItemsCheckable ) + public: //! Item data roles @@ -76,6 +81,20 @@ class CORE_EXPORT QgsMapLayerModel : public QAbstractItemModel */ bool allowEmptyLayer() const { return mAllowEmpty; } + /** + * Sets whether the CRS of layers is also included in the model's display role. + * @see showCrs() + * @note added in QGIS 3.0 + */ + void setShowCrs( bool showCrs ); + + /** + * Returns true if the model includes layer's CRS in the display role. + * @see setShowCrs() + * @note added in QGIS 3.0 + */ + bool showCrs() const { return mShowCrs; } + /** * @brief layersChecked returns the list of layers which are checked (or unchecked) */ @@ -101,9 +120,9 @@ class CORE_EXPORT QgsMapLayerModel : public QAbstractItemModel public: QModelIndex index( int row, int column, const QModelIndex &parent = QModelIndex() ) const override; QModelIndex parent( const QModelIndex &child ) const override; - int rowCount( const QModelIndex &parent ) const override; - int columnCount( const QModelIndex &parent ) const override; - QVariant data( const QModelIndex &index, int role ) const override; + int rowCount( const QModelIndex &parent = QModelIndex() ) const override; + int columnCount( const QModelIndex &parent = QModelIndex() ) const override; + QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const override; /** * Returns strings for all roles supported by this model. @@ -112,12 +131,13 @@ class CORE_EXPORT QgsMapLayerModel : public QAbstractItemModel */ QHash roleNames() const override; - bool setData( const QModelIndex &index, const QVariant &value, int role ) override; + bool setData( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole ) override; Qt::ItemFlags flags( const QModelIndex &index ) const override; private: bool mAllowEmpty; + bool mShowCrs; }; #endif // QGSMAPLAYERMODEL_H diff --git a/src/gui/qgsmaplayercombobox.cpp b/src/gui/qgsmaplayercombobox.cpp index c8187a68db9..932b13d2c41 100644 --- a/src/gui/qgsmaplayercombobox.cpp +++ b/src/gui/qgsmaplayercombobox.cpp @@ -38,6 +38,16 @@ bool QgsMapLayerComboBox::allowEmptyLayer() const return mProxyModel->sourceLayerModel()->allowEmptyLayer(); } +void QgsMapLayerComboBox::setShowCrs( bool showCrs ) +{ + mProxyModel->sourceLayerModel()->setShowCrs( showCrs ); +} + +bool QgsMapLayerComboBox::showCrs() const +{ + return mProxyModel->sourceLayerModel()->showCrs(); +} + void QgsMapLayerComboBox::setLayer( QgsMapLayer *layer ) { if ( !layer ) diff --git a/src/gui/qgsmaplayercombobox.h b/src/gui/qgsmaplayercombobox.h index bf4b8320ab4..2355520ea81 100644 --- a/src/gui/qgsmaplayercombobox.h +++ b/src/gui/qgsmaplayercombobox.h @@ -32,6 +32,8 @@ class GUI_EXPORT QgsMapLayerComboBox : public QComboBox Q_OBJECT Q_FLAGS( QgsMapLayerProxyModel::Filters ) Q_PROPERTY( QgsMapLayerProxyModel::Filters filters READ filters WRITE setFilters ) + Q_PROPERTY( bool allowEmptyLayer READ allowEmptyLayer WRITE setAllowEmptyLayer ) + Q_PROPERTY( bool showCrs READ showCrs WRITE setShowCrs ) public: @@ -67,6 +69,20 @@ class GUI_EXPORT QgsMapLayerComboBox : public QComboBox */ bool allowEmptyLayer() const; + /** + * Sets whether the CRS of layers is also included in the combo box text. + * @see showCrs() + * @note added in QGIS 3.0 + */ + void setShowCrs( bool showCrs ); + + /** + * Returns true if the combo box shows the layer's CRS. + * @see setShowCrs() + * @note added in QGIS 3.0 + */ + bool showCrs() const; + /** Returns the current layer selected in the combo box. * @see layer */ diff --git a/tests/src/python/test_qgsmaplayermodel.py b/tests/src/python/test_qgsmaplayermodel.py index e6e4b7cf69a..cdc5b74c171 100644 --- a/tests/src/python/test_qgsmaplayermodel.py +++ b/tests/src/python/test_qgsmaplayermodel.py @@ -23,7 +23,7 @@ start_app() def create_layer(name): - layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer", + layer = QgsVectorLayer("Point?crs=EPSG:3111&field=fldtxt:string&field=fldint:integer", name, "memory") return layer @@ -44,6 +44,11 @@ class TestQgsMapLayerModel(unittest.TestCase): m.setAllowEmptyLayer(False) self.assertFalse(m.allowEmptyLayer()) + m.setShowCrs(True) + self.assertTrue(m.showCrs()) + m.setShowCrs(False) + self.assertFalse(m.showCrs()) + def testAddingRemovingLayers(self): # test model handles layer addition and removal m = QgsMapLayerModel() @@ -146,6 +151,21 @@ class TestQgsMapLayerModel(unittest.TestCase): QgsMapLayerRegistry.instance().removeMapLayers([l1.id(), l2.id()]) + def testDisplayRoleShowCrs(self): + l1 = create_layer('l1') + l2 = create_layer('l2') + QgsMapLayerRegistry.instance().addMapLayers([l1, l2]) + m = QgsMapLayerModel() + m.setShowCrs(True) + self.assertEqual(m.data(m.index(0, 0), Qt.DisplayRole), 'l1 [EPSG:3111]') + self.assertEqual(m.data(m.index(1, 0), Qt.DisplayRole), 'l2 [EPSG:3111]') + m.setAllowEmptyLayer(True) + self.assertFalse(m.data(m.index(0, 0), Qt.DisplayRole)) + self.assertEqual(m.data(m.index(1, 0), Qt.DisplayRole), 'l1 [EPSG:3111]') + self.assertEqual(m.data(m.index(2, 0), Qt.DisplayRole), 'l2 [EPSG:3111]') + + QgsMapLayerRegistry.instance().removeMapLayers([l1.id(), l2.id()]) + def testLayerIdRole(self): l1 = create_layer('l1') l2 = create_layer('l2')