From 959f97f682027a106282f57253ce7fe87786c7ac Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Wed, 16 Nov 2016 11:53:13 +1000 Subject: [PATCH] Allow not set choice in QgsMapLayerComboBox --- python/core/qgsmaplayermodel.sip | 16 ++ python/gui/qgsmaplayercombobox.sip | 14 ++ src/core/qgsmaplayermodel.cpp | 83 ++++++- src/core/qgsmaplayermodel.h | 20 +- src/core/qgsmaplayerproxymodel.cpp | 10 + src/gui/qgsmaplayercombobox.cpp | 10 + src/gui/qgsmaplayercombobox.h | 14 ++ tests/src/python/CMakeLists.txt | 1 + tests/src/python/test_qgsmaplayermodel.py | 266 ++++++++++++++++++++++ 9 files changed, 424 insertions(+), 10 deletions(-) create mode 100644 tests/src/python/test_qgsmaplayermodel.py diff --git a/python/core/qgsmaplayermodel.sip b/python/core/qgsmaplayermodel.sip index 80565e911cb..655d7b18ac8 100644 --- a/python/core/qgsmaplayermodel.sip +++ b/python/core/qgsmaplayermodel.sip @@ -19,6 +19,7 @@ class QgsMapLayerModel : QAbstractItemModel { LayerIdRole, /*!< Stores the map layer ID */ LayerRole, /*!< Stores pointer to the map layer itself */ + IsEmptyRole, //!< True if index corresponds to the empty (not set) value }; /** @@ -38,6 +39,21 @@ class QgsMapLayerModel : QAbstractItemModel * @brief checkAll changes the checkstate for all the layers */ void checkAll( Qt::CheckState checkState ); + + /** + * Sets whether an optional empty layer ("not set") option is present in the model. + * @see allowEmptyLayer() + * @note added in QGIS 3.0 + */ + void setAllowEmptyLayer( bool allowEmpty ); + + /** + * Returns true if the model allows the empty layer ("not set") choice. + * @see setAllowEmptyLayer() + * @note added in QGIS 3.0 + */ + bool allowEmptyLayer() const; + /** * @brief layersChecked returns the list of layers which are checked (or unchecked) */ diff --git a/python/gui/qgsmaplayercombobox.sip b/python/gui/qgsmaplayercombobox.sip index dcc05dd402c..4127bc084f2 100644 --- a/python/gui/qgsmaplayercombobox.sip +++ b/python/gui/qgsmaplayercombobox.sip @@ -28,6 +28,20 @@ class QgsMapLayerComboBox : QComboBox //! returns the list of excepted layers QList exceptedLayerList() const; + /** + * Sets whether an optional empty layer ("not set") option is shown in the combo box. + * @see allowEmptyLayer() + * @note added in QGIS 3.0 + */ + void setAllowEmptyLayer( bool allowEmpty ); + + /** + * Returns true if the combo box allows the empty layer ("not set") choice. + * @see setAllowEmptyLayer() + * @note added in QGIS 3.0 + */ + bool allowEmptyLayer() 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 150350e1072..97129f720a7 100644 --- a/src/core/qgsmaplayermodel.cpp +++ b/src/core/qgsmaplayermodel.cpp @@ -26,6 +26,7 @@ QgsMapLayerModel::QgsMapLayerModel( const QList& layers, QObject : QAbstractItemModel( parent ) , mLayersChecked( QMap() ) , mItemCheckable( false ) + , mAllowEmpty( false ) { connect( QgsMapLayerRegistry::instance(), SIGNAL( layersWillBeRemoved( QStringList ) ), this, SLOT( removeLayers( QStringList ) ) ); addLayers( layers ); @@ -35,6 +36,7 @@ QgsMapLayerModel::QgsMapLayerModel( QObject *parent ) : QAbstractItemModel( parent ) , mLayersChecked( QMap() ) , mItemCheckable( false ) + , mAllowEmpty( false ) { connect( QgsMapLayerRegistry::instance(), SIGNAL( layersAdded( QList ) ), this, SLOT( addLayers( QList ) ) ); connect( QgsMapLayerRegistry::instance(), SIGNAL( layersWillBeRemoved( QStringList ) ), this, SLOT( removeLayers( QStringList ) ) ); @@ -55,6 +57,25 @@ void QgsMapLayerModel::checkAll( Qt::CheckState checkState ) emit dataChanged( index( 0, 0 ), index( mLayers.length() - 1, 0 ) ); } +void QgsMapLayerModel::setAllowEmptyLayer( bool allowEmpty ) +{ + if ( allowEmpty == mAllowEmpty ) + return; + + if ( allowEmpty ) + { + beginInsertRows( QModelIndex(), 0, 0 ); + mAllowEmpty = true; + endInsertRows(); + } + else + { + beginRemoveRows( QModelIndex(), 0, 0 ); + mAllowEmpty = false; + endRemoveRows(); + } +} + QList QgsMapLayerModel::layersChecked( Qt::CheckState checkState ) { QList layers; @@ -71,6 +92,8 @@ QList QgsMapLayerModel::layersChecked( Qt::CheckState checkState QModelIndex QgsMapLayerModel::indexFromLayer( QgsMapLayer *layer ) const { int r = mLayers.indexOf( layer ); + if ( r >= 0 && mAllowEmpty ) + r++; return index( r, 0 ); } @@ -93,7 +116,11 @@ void QgsMapLayerModel::removeLayers( const QStringList& layerIds ) void QgsMapLayerModel::addLayers( const QList& layers ) { - beginInsertRows( QModelIndex(), mLayers.count(), mLayers.count() + layers.count() - 1 ); + int offset = 0; + if ( mAllowEmpty ) + offset++; + + beginInsertRows( QModelIndex(), mLayers.count() + offset, mLayers.count() + layers.count() - 1 + offset ); Q_FOREACH ( QgsMapLayer* layer, layers ) { mLayers.append( layer ); @@ -104,9 +131,17 @@ void QgsMapLayerModel::addLayers( const QList& layers ) QModelIndex QgsMapLayerModel::index( int row, int column, const QModelIndex &parent ) const { + int offset = 0; + if ( mAllowEmpty ) + offset++; + if ( hasIndex( row, column, parent ) ) { - return createIndex( row, column, mLayers[row] ); + QgsMapLayer* layer = nullptr; + if ( row - offset >= 0 && row - offset < mLayers.count() ) + layer = mLayers.at( row - offset ); + + return createIndex( row, column, layer ); } return QModelIndex(); @@ -122,7 +157,10 @@ QModelIndex QgsMapLayerModel::parent( const QModelIndex &child ) const int QgsMapLayerModel::rowCount( const QModelIndex &parent ) const { - return parent.isValid() ? 0 : mLayers.length(); + if ( parent.isValid() ) + return 0; + + return ( mAllowEmpty ? 1 : 0 ) + mLayers.length(); } int QgsMapLayerModel::columnCount( const QModelIndex &parent ) const @@ -134,35 +172,58 @@ int QgsMapLayerModel::columnCount( const QModelIndex &parent ) const QVariant QgsMapLayerModel::data( const QModelIndex &index, int role ) const { - if ( !index.isValid() || !index.internalPointer() ) + bool isEmpty = index.row() == 0 && mAllowEmpty; + + if ( !index.isValid() ) return QVariant(); if ( role == Qt::DisplayRole ) { + if ( index.row() == 0 && mAllowEmpty ) + return QVariant(); + QgsMapLayer* layer = static_cast( index.internalPointer() ); - return layer->name(); + return layer ? layer->name() : QVariant(); } if ( role == LayerIdRole ) { + if ( isEmpty ) + return QVariant(); + QgsMapLayer* layer = static_cast( index.internalPointer() ); - return layer->id(); + return layer ? layer->id() : QVariant(); } if ( role == LayerRole ) { + if ( isEmpty ) + return QVariant(); + return QVariant::fromValue( static_cast( index.internalPointer() ) ); } + if ( role == IsEmptyRole ) + return isEmpty; + if ( role == Qt::CheckStateRole && mItemCheckable ) { + if ( isEmpty ) + return QVariant(); + QgsMapLayer* layer = static_cast( index.internalPointer() ); - return mLayersChecked[layer->id()]; + return layer ? mLayersChecked[layer->id()] : QVariant(); } if ( role == Qt::DecorationRole ) { + if ( isEmpty ) + return QVariant(); + QgsMapLayer* layer = static_cast( index.internalPointer() ); + if ( !layer ) + return QVariant(); + QgsMapLayer::LayerType type = layer->type(); if ( role == Qt::DecorationRole ) { @@ -232,8 +293,10 @@ Qt::ItemFlags QgsMapLayerModel::flags( const QModelIndex &index ) const return 0; } + bool isEmpty = index.row() == 0 && mAllowEmpty; + Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable; - if ( mItemCheckable ) + if ( mItemCheckable && !isEmpty ) { flags |= Qt::ItemIsUserCheckable; } @@ -243,7 +306,9 @@ Qt::ItemFlags QgsMapLayerModel::flags( const QModelIndex &index ) const bool QgsMapLayerModel::setData( const QModelIndex &index, const QVariant &value, int role ) { - if ( role == Qt::CheckStateRole ) + bool isEmpty = index.row() == 0 && mAllowEmpty; + + if ( role == Qt::CheckStateRole && !isEmpty ) { QgsMapLayer* layer = static_cast( index.internalPointer() ); mLayersChecked[layer->id()] = ( Qt::CheckState )value.toInt(); diff --git a/src/core/qgsmaplayermodel.h b/src/core/qgsmaplayermodel.h index 084d07f8648..75ad02f6f07 100644 --- a/src/core/qgsmaplayermodel.h +++ b/src/core/qgsmaplayermodel.h @@ -39,6 +39,7 @@ class CORE_EXPORT QgsMapLayerModel : public QAbstractItemModel { LayerIdRole = Qt::UserRole + 1, //!< Stores the map layer ID LayerRole, //!< Stores pointer to the map layer itself + IsEmptyRole, //!< True if index corresponds to the empty (not set) value }; /** @@ -61,6 +62,20 @@ class CORE_EXPORT QgsMapLayerModel : public QAbstractItemModel */ void checkAll( Qt::CheckState checkState ); + /** + * Sets whether an optional empty layer ("not set") option is present in the model. + * @see allowEmptyLayer() + * @note added in QGIS 3.0 + */ + void setAllowEmptyLayer( bool allowEmpty ); + + /** + * Returns true if the model allows the empty layer ("not set") choice. + * @see setAllowEmptyLayer() + * @note added in QGIS 3.0 + */ + bool allowEmptyLayer() const { return mAllowEmpty; } + /** * @brief layersChecked returns the list of layers which are checked (or unchecked) */ @@ -73,7 +88,6 @@ class CORE_EXPORT QgsMapLayerModel : public QAbstractItemModel */ QModelIndex indexFromLayer( QgsMapLayer* layer ) const; - protected slots: void removeLayers( const QStringList& layerIds ); void addLayers( const QList& layers ); @@ -100,6 +114,10 @@ class CORE_EXPORT QgsMapLayerModel : public QAbstractItemModel bool setData( const QModelIndex &index, const QVariant &value, int role ) override; Qt::ItemFlags flags( const QModelIndex &index ) const override; + + private: + + bool mAllowEmpty; }; #endif // QGSMAPLAYERMODEL_H diff --git a/src/core/qgsmaplayerproxymodel.cpp b/src/core/qgsmaplayerproxymodel.cpp index 4372e58560f..5404903d58b 100644 --- a/src/core/qgsmaplayerproxymodel.cpp +++ b/src/core/qgsmaplayerproxymodel.cpp @@ -77,6 +77,10 @@ bool QgsMapLayerProxyModel::filterAcceptsRow( int source_row, const QModelIndex return true; QModelIndex index = sourceModel()->index( source_row, 0, source_parent ); + + if ( sourceModel()->data( index, QgsMapLayerModel::IsEmptyRole ).toBool() ) + return true; + QgsMapLayer* layer = static_cast( index.internalPointer() ); if ( !layer ) return false; @@ -123,6 +127,12 @@ bool QgsMapLayerProxyModel::filterAcceptsRow( int source_row, const QModelIndex bool QgsMapLayerProxyModel::lessThan( const QModelIndex &left, const QModelIndex &right ) const { + // empty row is always first + if ( sourceModel()->data( left, QgsMapLayerModel::IsEmptyRole ).toBool() ) + return true; + else if ( sourceModel()->data( right, QgsMapLayerModel::IsEmptyRole ).toBool() ) + return false; + // default mode is alphabetical order QString leftStr = sourceModel()->data( left ).toString(); QString rightStr = sourceModel()->data( right ).toString(); diff --git a/src/gui/qgsmaplayercombobox.cpp b/src/gui/qgsmaplayercombobox.cpp index 9818361a2ac..c8187a68db9 100644 --- a/src/gui/qgsmaplayercombobox.cpp +++ b/src/gui/qgsmaplayercombobox.cpp @@ -28,6 +28,16 @@ QgsMapLayerComboBox::QgsMapLayerComboBox( QWidget *parent ) connect( mProxyModel, SIGNAL( rowsRemoved( QModelIndex, int, int ) ), this, SLOT( rowsChanged() ) ); } +void QgsMapLayerComboBox::setAllowEmptyLayer( bool allowEmpty ) +{ + mProxyModel->sourceLayerModel()->setAllowEmptyLayer( allowEmpty ); +} + +bool QgsMapLayerComboBox::allowEmptyLayer() const +{ + return mProxyModel->sourceLayerModel()->allowEmptyLayer(); +} + void QgsMapLayerComboBox::setLayer( QgsMapLayer *layer ) { if ( !layer ) diff --git a/src/gui/qgsmaplayercombobox.h b/src/gui/qgsmaplayercombobox.h index 40ed469a3b4..bf4b8320ab4 100644 --- a/src/gui/qgsmaplayercombobox.h +++ b/src/gui/qgsmaplayercombobox.h @@ -53,6 +53,20 @@ class GUI_EXPORT QgsMapLayerComboBox : public QComboBox //! returns the list of excepted layers QList exceptedLayerList() const {return mProxyModel->exceptedLayerList();} + /** + * Sets whether an optional empty layer ("not set") option is shown in the combo box. + * @see allowEmptyLayer() + * @note added in QGIS 3.0 + */ + void setAllowEmptyLayer( bool allowEmpty ); + + /** + * Returns true if the combo box allows the empty layer ("not set") choice. + * @see setAllowEmptyLayer() + * @note added in QGIS 3.0 + */ + bool allowEmptyLayer() const; + /** Returns the current layer selected in the combo box. * @see layer */ diff --git a/tests/src/python/CMakeLists.txt b/tests/src/python/CMakeLists.txt index 3ee40185163..249b683161f 100644 --- a/tests/src/python/CMakeLists.txt +++ b/tests/src/python/CMakeLists.txt @@ -57,6 +57,7 @@ ADD_PYTHON_TEST(PyQgsGeometryValidator test_qgsgeometryvalidator.py) ADD_PYTHON_TEST(PyQgsGraduatedSymbolRenderer test_qgsgraduatedsymbolrenderer.py) ADD_PYTHON_TEST(PyQgsInterval test_qgsinterval.py) ADD_PYTHON_TEST(PyQgsJSONUtils test_qgsjsonutils.py) +ADD_PYTHON_TEST(PyQgsMapLayerModel test_qgsmaplayermodel.py) ADD_PYTHON_TEST(PyQgsMapUnitScale test_qgsmapunitscale.py) ADD_PYTHON_TEST(PyQgsMemoryProvider test_provider_memory.py) ADD_PYTHON_TEST(PyQgsMultiEditToolButton test_qgsmultiedittoolbutton.py) diff --git a/tests/src/python/test_qgsmaplayermodel.py b/tests/src/python/test_qgsmaplayermodel.py new file mode 100644 index 00000000000..e6e4b7cf69a --- /dev/null +++ b/tests/src/python/test_qgsmaplayermodel.py @@ -0,0 +1,266 @@ +# -*- coding: utf-8 -*- +"""QGIS Unit tests for QgsMapLayerModel + +.. 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 +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. +""" +__author__ = 'Nyall Dawson' +__date__ = '16/11/2016' +__copyright__ = 'Copyright 2016, The QGIS Project' +# This will get replaced with a git SHA1 when you do a git archive +__revision__ = '$Format:%H$' + +import qgis # NOQA + +from qgis.core import QgsVectorLayer, QgsMapLayerRegistry, QgsMapLayerModel +from qgis.PyQt.QtCore import Qt, QModelIndex + +from qgis.testing import start_app, unittest + +start_app() + + +def create_layer(name): + layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer", + name, "memory") + return layer + + +class TestQgsMapLayerModel(unittest.TestCase): + + def testGettersSetters(self): + """ test model getters/setters """ + m = QgsMapLayerModel() + + m.setItemsCheckable(True) + self.assertTrue(m.itemsCheckable()) + m.setItemsCheckable(False) + self.assertFalse(m.itemsCheckable()) + + m.setAllowEmptyLayer(True) + self.assertTrue(m.allowEmptyLayer()) + m.setAllowEmptyLayer(False) + self.assertFalse(m.allowEmptyLayer()) + + def testAddingRemovingLayers(self): + # test model handles layer addition and removal + m = QgsMapLayerModel() + + self.assertEqual(m.rowCount(QModelIndex()), 0) + + l1 = create_layer('l1') + QgsMapLayerRegistry.instance().addMapLayer(l1) + self.assertEqual(m.rowCount(QModelIndex()), 1) + l2 = create_layer('l2') + QgsMapLayerRegistry.instance().addMapLayer(l2) + self.assertEqual(m.rowCount(QModelIndex()), 2) + QgsMapLayerRegistry.instance().removeMapLayer(l1) + self.assertEqual(m.rowCount(QModelIndex()), 1) + QgsMapLayerRegistry.instance().removeMapLayer(l2) + self.assertEqual(m.rowCount(QModelIndex()), 0) + + # try creating a model when layers already exist in registry + l1 = create_layer('l1') + l2 = create_layer('l2') + QgsMapLayerRegistry.instance().addMapLayers([l1, l2]) + m = QgsMapLayerModel() + self.assertEqual(m.rowCount(QModelIndex()), 2) + QgsMapLayerRegistry.instance().removeMapLayers([l1.id(), l2.id()]) + self.assertEqual(m.rowCount(QModelIndex()), 0) + + def testCheckAll(self): + l1 = create_layer('l1') + l2 = create_layer('l2') + QgsMapLayerRegistry.instance().addMapLayers([l1, l2]) + m = QgsMapLayerModel() + m.setItemsCheckable(True) + self.assertFalse(m.layersChecked()) + self.assertEqual(set(m.layersChecked(Qt.Unchecked)), set([l1, l2])) + + m.checkAll(Qt.Checked) + self.assertEqual(set(m.layersChecked()), set([l1, l2])) + self.assertFalse(set(m.layersChecked(Qt.Unchecked))) + + m.checkAll(Qt.Unchecked) + self.assertFalse(m.layersChecked()) + self.assertEqual(set(m.layersChecked(Qt.Unchecked)), set([l1, l2])) + + QgsMapLayerRegistry.instance().removeMapLayers([l1.id(), l2.id()]) + + def testAllowEmpty(self): + l1 = create_layer('l1') + l2 = create_layer('l2') + QgsMapLayerRegistry.instance().addMapLayers([l1, l2]) + m = QgsMapLayerModel() + self.assertEqual(m.rowCount(QModelIndex()), 2) + + m.setAllowEmptyLayer(True) + self.assertEqual(m.rowCount(QModelIndex()), 3) + self.assertFalse(m.data(m.index(0, 0), Qt.DisplayRole)) + m.setAllowEmptyLayer(False) + self.assertEqual(m.rowCount(QModelIndex()), 2) + self.assertTrue(m.data(m.index(0, 0), Qt.DisplayRole)) + + # add layers after allow empty is true + m.setAllowEmptyLayer(True) + l3 = create_layer('l3') + QgsMapLayerRegistry.instance().addMapLayers([l3]) + self.assertEqual(m.rowCount(QModelIndex()), 4) + self.assertFalse(m.data(m.index(0, 0), Qt.DisplayRole)) + self.assertEqual(m.data(m.index(1, 0), Qt.DisplayRole), 'l1') + self.assertEqual(m.data(m.index(2, 0), Qt.DisplayRole), 'l2') + self.assertEqual(m.data(m.index(3, 0), Qt.DisplayRole), 'l3') + + QgsMapLayerRegistry.instance().removeMapLayers([l1.id(), l2.id(), l3.id()]) + + def testIndexFromLayer(self): + l1 = create_layer('l1') + l2 = create_layer('l2') + QgsMapLayerRegistry.instance().addMapLayers([l1, l2]) + m = QgsMapLayerModel() + l3 = create_layer('l3') # not in registry + + self.assertEqual(m.indexFromLayer(l1).row(), 0) + self.assertEqual(m.indexFromLayer(l2).row(), 1) + self.assertFalse(m.indexFromLayer(l3).isValid()) + + m.setAllowEmptyLayer(True) + self.assertEqual(m.indexFromLayer(l1).row(), 1) + self.assertEqual(m.indexFromLayer(l2).row(), 2) + + QgsMapLayerRegistry.instance().removeMapLayers([l1.id(), l2.id()]) + + def testDisplayRole(self): + l1 = create_layer('l1') + l2 = create_layer('l2') + QgsMapLayerRegistry.instance().addMapLayers([l1, l2]) + m = QgsMapLayerModel() + self.assertEqual(m.data(m.index(0, 0), Qt.DisplayRole), 'l1') + self.assertEqual(m.data(m.index(1, 0), Qt.DisplayRole), 'l2') + m.setAllowEmptyLayer(True) + self.assertFalse(m.data(m.index(0, 0), Qt.DisplayRole)) + self.assertEqual(m.data(m.index(1, 0), Qt.DisplayRole), 'l1') + self.assertEqual(m.data(m.index(2, 0), Qt.DisplayRole), 'l2') + + QgsMapLayerRegistry.instance().removeMapLayers([l1.id(), l2.id()]) + + def testLayerIdRole(self): + l1 = create_layer('l1') + l2 = create_layer('l2') + QgsMapLayerRegistry.instance().addMapLayers([l1, l2]) + m = QgsMapLayerModel() + self.assertEqual(m.data(m.index(0, 0), QgsMapLayerModel.LayerIdRole), l1.id()) + self.assertEqual(m.data(m.index(1, 0), QgsMapLayerModel.LayerIdRole), l2.id()) + m.setAllowEmptyLayer(True) + self.assertFalse(m.data(m.index(0, 0), QgsMapLayerModel.LayerIdRole)) + self.assertEqual(m.data(m.index(1, 0), QgsMapLayerModel.LayerIdRole), l1.id()) + self.assertEqual(m.data(m.index(2, 0), QgsMapLayerModel.LayerIdRole), l2.id()) + + QgsMapLayerRegistry.instance().removeMapLayers([l1.id(), l2.id()]) + + def testLayerRole(self): + l1 = create_layer('l1') + l2 = create_layer('l2') + QgsMapLayerRegistry.instance().addMapLayers([l1, l2]) + m = QgsMapLayerModel() + self.assertEqual(m.data(m.index(0, 0), QgsMapLayerModel.LayerRole), l1) + self.assertEqual(m.data(m.index(1, 0), QgsMapLayerModel.LayerRole), l2) + m.setAllowEmptyLayer(True) + self.assertFalse(m.data(m.index(0, 0), QgsMapLayerModel.LayerRole)) + self.assertEqual(m.data(m.index(1, 0), QgsMapLayerModel.LayerRole), l1) + self.assertEqual(m.data(m.index(2, 0), QgsMapLayerModel.LayerRole), l2) + + QgsMapLayerRegistry.instance().removeMapLayers([l1.id(), l2.id()]) + + def testIsEmptyRole(self): + l1 = create_layer('l1') + l2 = create_layer('l2') + QgsMapLayerRegistry.instance().addMapLayers([l1, l2]) + m = QgsMapLayerModel() + self.assertFalse(m.data(m.index(0, 0), QgsMapLayerModel.IsEmptyRole)) + self.assertFalse(m.data(m.index(1, 0), QgsMapLayerModel.IsEmptyRole)) + m.setAllowEmptyLayer(True) + self.assertTrue(m.data(m.index(0, 0), QgsMapLayerModel.IsEmptyRole)) + self.assertFalse(m.data(m.index(1, 0), QgsMapLayerModel.IsEmptyRole)) + self.assertFalse(m.data(m.index(2, 0), QgsMapLayerModel.IsEmptyRole)) + + QgsMapLayerRegistry.instance().removeMapLayers([l1.id(), l2.id()]) + + def testCheckStateRole(self): + l1 = create_layer('l1') + l2 = create_layer('l2') + QgsMapLayerRegistry.instance().addMapLayers([l1, l2]) + m = QgsMapLayerModel() + + # not checkable + self.assertFalse(m.data(m.index(0, 0), Qt.CheckStateRole)) + self.assertFalse(m.data(m.index(1, 0), Qt.CheckStateRole)) + m.setAllowEmptyLayer(True) + self.assertFalse(m.data(m.index(0, 0), Qt.CheckStateRole)) + self.assertFalse(m.data(m.index(1, 0), Qt.CheckStateRole)) + self.assertFalse(m.data(m.index(2, 0), Qt.CheckStateRole)) + m.setAllowEmptyLayer(False) + + # checkable + m.setItemsCheckable(True) + m.checkAll(Qt.Checked) + self.assertTrue(m.data(m.index(0, 0), Qt.CheckStateRole)) + self.assertTrue(m.data(m.index(1, 0), Qt.CheckStateRole)) + m.setAllowEmptyLayer(True) + self.assertFalse(m.data(m.index(0, 0), Qt.CheckStateRole)) + self.assertTrue(m.data(m.index(1, 0), Qt.CheckStateRole)) + self.assertTrue(m.data(m.index(2, 0), Qt.CheckStateRole)) + + QgsMapLayerRegistry.instance().removeMapLayers([l1.id(), l2.id()]) + + def testFlags(self): + l1 = create_layer('l1') + l2 = create_layer('l2') + QgsMapLayerRegistry.instance().addMapLayers([l1, l2]) + m = QgsMapLayerModel() + + # not checkable + self.assertFalse(m.flags(m.index(0, 0)) & Qt.ItemIsUserCheckable) + self.assertFalse(m.flags(m.index(1, 0)) & Qt.ItemIsUserCheckable) + m.setAllowEmptyLayer(True) + self.assertFalse(m.flags(m.index(0, 0)) & Qt.ItemIsUserCheckable) + self.assertFalse(m.flags(m.index(1, 0)) & Qt.ItemIsUserCheckable) + self.assertFalse(m.flags(m.index(2, 0)) & Qt.ItemIsUserCheckable) + m.setAllowEmptyLayer(False) + + # checkable + m.setItemsCheckable(True) + self.assertTrue(m.flags(m.index(0, 0)) & Qt.ItemIsUserCheckable) + self.assertTrue(m.flags(m.index(1, 0)) & Qt.ItemIsUserCheckable) + m.setAllowEmptyLayer(True) + self.assertFalse(m.flags(m.index(0, 0)) & Qt.ItemIsUserCheckable) + self.assertTrue(m.flags(m.index(1, 0)) & Qt.ItemIsUserCheckable) + self.assertTrue(m.flags(m.index(2, 0)) & Qt.ItemIsUserCheckable) + + QgsMapLayerRegistry.instance().removeMapLayers([l1.id(), l2.id()]) + + def testSetData(self): + l1 = create_layer('l1') + l2 = create_layer('l2') + QgsMapLayerRegistry.instance().addMapLayers([l1, l2]) + m = QgsMapLayerModel() + + # set checked + m.setItemsCheckable(True) + self.assertTrue(m.setData(m.index(0, 0), True, Qt.CheckStateRole)) + self.assertTrue(m.data(m.index(0, 0), Qt.CheckStateRole)) + self.assertFalse(m.data(m.index(1, 0), Qt.CheckStateRole)) + self.assertTrue(m.setData(m.index(1, 0), True, Qt.CheckStateRole)) + self.assertTrue(m.data(m.index(0, 0), Qt.CheckStateRole)) + self.assertTrue(m.data(m.index(1, 0), Qt.CheckStateRole)) + + m.setAllowEmptyLayer(True) + self.assertFalse(m.setData(m.index(0, 0), True, Qt.CheckStateRole)) + self.assertTrue(m.setData(m.index(1, 0), True, Qt.CheckStateRole)) + + QgsMapLayerRegistry.instance().removeMapLayers([l1.id(), l2.id()]) + +if __name__ == '__main__': + unittest.main()