Skip to content

Commit

Permalink
[api] Also expose method for adding additional (non-project) layers
Browse files Browse the repository at this point in the history
to QgsMapLayerComboBox
  • Loading branch information
nyalldawson committed Sep 6, 2021
1 parent 1d73ea8 commit 3f977b5
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 0 deletions.
21 changes: 21 additions & 0 deletions python/gui/auto_generated/qgsmaplayercombobox.sip.in
Expand Up @@ -124,6 +124,27 @@ Returns the list of additional (non map layer) items included at the end of the
.. seealso:: :py:func:`setAdditionalItems`

.. versionadded:: 3.0
%End

void setAdditionalLayers( const QList<QgsMapLayer *> &layers );
%Docstring
Sets a list of additional ``layers`` to include in the combobox.

This method allows adding additional layers, which are not part of a project's
layers, into the combobox.

.. seealso:: :py:func:`additionalLayers`

.. versionadded:: 3.22
%End

QList< QgsMapLayer * > additionalLayers() const;
%Docstring
Returns the list of additional layers added to the combobox.

.. seealso:: :py:func:`setAdditionalLayers`

.. versionadded:: 3.22
%End

QgsMapLayer *currentLayer() const;
Expand Down
10 changes: 10 additions & 0 deletions src/gui/qgsmaplayercombobox.cpp
Expand Up @@ -74,6 +74,16 @@ QStringList QgsMapLayerComboBox::additionalItems() const
return mProxyModel->sourceLayerModel()->additionalItems();
}

void QgsMapLayerComboBox::setAdditionalLayers( const QList<QgsMapLayer *> &layers )
{
mProxyModel->sourceLayerModel()->setAdditionalLayers( layers );
}

QList<QgsMapLayer *> QgsMapLayerComboBox::additionalLayers() const
{
return mProxyModel->sourceLayerModel()->additionalLayers();
}

void QgsMapLayerComboBox::setLayer( QgsMapLayer *layer )
{
if ( layer == currentLayer() && ( layer || !isEditable() || currentText().isEmpty() ) )
Expand Down
19 changes: 19 additions & 0 deletions src/gui/qgsmaplayercombobox.h
Expand Up @@ -120,6 +120,25 @@ class GUI_EXPORT QgsMapLayerComboBox : public QComboBox
*/
QStringList additionalItems() const;

/**
* Sets a list of additional \a layers to include in the combobox.
*
* This method allows adding additional layers, which are not part of a project's
* layers, into the combobox.
*
* \see additionalLayers()
* \since QGIS 3.22
*/
void setAdditionalLayers( const QList<QgsMapLayer *> &layers );

/**
* Returns the list of additional layers added to the combobox.
*
* \see setAdditionalLayers()
* \since QGIS 3.22
*/
QList< QgsMapLayer * > additionalLayers() const;

/**
* Returns the current layer selected in the combo box.
* \see layer
Expand Down
77 changes: 77 additions & 0 deletions tests/src/python/test_qgsmaplayercombobox.py
Expand Up @@ -14,6 +14,10 @@

from qgis.core import QgsVectorLayer, QgsMeshLayer, QgsProject, QgsMapLayerProxyModel
from qgis.gui import QgsMapLayerComboBox
from qgis.PyQt.QtCore import (
QCoreApplication,
QEvent
)
from qgis.PyQt.QtTest import QSignalSpy

from qgis.testing import start_app, unittest
Expand Down Expand Up @@ -187,6 +191,79 @@ def testSignals(self):
self.assertEqual(len(spy), 4)
self.assertEqual(m.currentLayer(), l1)

def testAdditionalLayers(self):
QgsProject.instance().clear()
l1 = create_layer('l1')
l2 = create_layer('l2')
QgsProject.instance().addMapLayers([l1, l2])
m = QgsMapLayerComboBox()
self.assertEqual(m.count(), 2)
l3 = create_layer('l3')
l4 = create_layer('l4')
m.setAdditionalLayers([l3, l4])
self.assertEqual(m.count(), 4)

m.setAdditionalItems(['a', 'b'])
self.assertEqual(m.count(), 6)
self.assertEqual(m.itemText(0), 'l1')
self.assertEqual(m.itemText(1), 'l2')
self.assertEqual(m.itemText(2), 'l3')
self.assertEqual(m.itemText(3), 'l4')
self.assertEqual(m.itemText(4), 'a')
self.assertEqual(m.itemText(5), 'b')

m.setAllowEmptyLayer(True)
self.assertEqual(m.count(), 7)
self.assertFalse(m.itemText(0))
self.assertEqual(m.itemText(1), 'l1')
self.assertEqual(m.itemText(2), 'l2')
self.assertEqual(m.itemText(3), 'l3')
self.assertEqual(m.itemText(4), 'l4')
self.assertEqual(m.itemText(5), 'a')
self.assertEqual(m.itemText(6), 'b')

l3.deleteLater()
QCoreApplication.sendPostedEvents(None, QEvent.DeferredDelete)
self.assertEqual(m.count(), 6)
self.assertFalse(m.itemText(0))
self.assertEqual(m.itemText(1), 'l1')
self.assertEqual(m.itemText(2), 'l2')
self.assertEqual(m.itemText(3), 'l4')
self.assertEqual(m.itemText(4), 'a')
self.assertEqual(m.itemText(5), 'b')

l5 = create_layer('l5')
l6 = create_layer('l6')
m.setAdditionalLayers([l5, l6, l4])
self.assertEqual(m.count(), 8)
self.assertFalse(m.itemText(0))
self.assertEqual(m.itemText(1), 'l1')
self.assertEqual(m.itemText(2), 'l2')
self.assertEqual(m.itemText(3), 'l4')
self.assertEqual(m.itemText(4), 'l5')
self.assertEqual(m.itemText(5), 'l6')
self.assertEqual(m.itemText(6), 'a')
self.assertEqual(m.itemText(7), 'b')

m.setAdditionalLayers([l5, l4])
self.assertEqual(m.count(), 7)
self.assertFalse(m.itemText(0))
self.assertEqual(m.itemText(1), 'l1')
self.assertEqual(m.itemText(2), 'l2')
self.assertEqual(m.itemText(3), 'l4')
self.assertEqual(m.itemText(4), 'l5')
self.assertEqual(m.itemText(5), 'a')
self.assertEqual(m.itemText(6), 'b')

QgsProject.instance().removeMapLayers([l1.id(), l2.id()])

self.assertEqual(m.count(), 5)
self.assertFalse(m.itemText(0))
self.assertEqual(m.itemText(1), 'l4')
self.assertEqual(m.itemText(2), 'l5')
self.assertEqual(m.itemText(3), 'a')
self.assertEqual(m.itemText(4), 'b')


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

0 comments on commit 3f977b5

Please sign in to comment.