diff --git a/python/core/auto_generated/qgsmaplayermodel.sip.in b/python/core/auto_generated/qgsmaplayermodel.sip.in index abb5624bb76..376fc783cc1 100644 --- a/python/core/auto_generated/qgsmaplayermodel.sip.in +++ b/python/core/auto_generated/qgsmaplayermodel.sip.in @@ -79,10 +79,12 @@ Returns ``True`` if items in the model can be reordered via drag and drop. checkAll changes the checkstate for all the layers %End - void setAllowEmptyLayer( bool allowEmpty ); + void setAllowEmptyLayer( bool allowEmpty, const QString &text = QString(), const QIcon &icon = QIcon() ); %Docstring Sets whether an optional empty layer ("not set") option is present in the model. +Since QGIS 3.20, the optional ``text`` and ``icon`` arguments allows the text and icon for the empty layer item to be set. + .. seealso:: :py:func:`allowEmptyLayer` .. versionadded:: 3.0 diff --git a/python/gui/auto_generated/qgsmaplayercombobox.sip.in b/python/gui/auto_generated/qgsmaplayercombobox.sip.in index 9a6a68290e6..0a9880f6d20 100644 --- a/python/gui/auto_generated/qgsmaplayercombobox.sip.in +++ b/python/gui/auto_generated/qgsmaplayercombobox.sip.in @@ -68,10 +68,12 @@ Returns the list of data providers which are excluded from the combobox. .. versionadded:: 3.0 %End - void setAllowEmptyLayer( bool allowEmpty ); + void setAllowEmptyLayer( bool allowEmpty, const QString &text = QString(), const QIcon &icon = QIcon() ); %Docstring Sets whether an optional empty layer ("not set") option is shown in the combo box. +Since QGIS 3.20, the optional ``text`` and ``icon`` arguments allows the text and icon for the empty layer item to be set. + .. seealso:: :py:func:`allowEmptyLayer` .. versionadded:: 3.0 diff --git a/src/core/qgsmaplayermodel.cpp b/src/core/qgsmaplayermodel.cpp index 74776150c78..fcd66b4a5d4 100644 --- a/src/core/qgsmaplayermodel.cpp +++ b/src/core/qgsmaplayermodel.cpp @@ -63,8 +63,10 @@ void QgsMapLayerModel::checkAll( Qt::CheckState checkState ) emit dataChanged( index( 0, 0 ), index( rowCount() - 1, 0 ) ); } -void QgsMapLayerModel::setAllowEmptyLayer( bool allowEmpty ) +void QgsMapLayerModel::setAllowEmptyLayer( bool allowEmpty, const QString &text, const QIcon &icon ) { + mEmptyText = text; + mEmptyIcon = icon; if ( allowEmpty == mAllowEmpty ) return; @@ -252,7 +254,7 @@ QVariant QgsMapLayerModel::data( const QModelIndex &index, int role ) const case Qt::EditRole: { if ( index.row() == 0 && mAllowEmpty ) - return QVariant(); + return mEmptyText; if ( additionalIndex >= 0 ) return mAdditionalItems.at( additionalIndex ); @@ -337,7 +339,10 @@ QVariant QgsMapLayerModel::data( const QModelIndex &index, int role ) const case Qt::DecorationRole: { - if ( isEmpty || additionalIndex >= 0 ) + if ( isEmpty ) + return mEmptyIcon.isNull() ? QVariant() : mEmptyIcon; + + if ( additionalIndex >= 0 ) return QVariant(); QgsMapLayer *layer = mLayers.value( index.row() - ( mAllowEmpty ? 1 : 0 ) ); diff --git a/src/core/qgsmaplayermodel.h b/src/core/qgsmaplayermodel.h index 4a5028de895..63b40eee0bc 100644 --- a/src/core/qgsmaplayermodel.h +++ b/src/core/qgsmaplayermodel.h @@ -19,6 +19,7 @@ #include #include #include +#include #include "qgis_core.h" #include "qgis_sip.h" @@ -98,10 +99,13 @@ class CORE_EXPORT QgsMapLayerModel : public QAbstractItemModel /** * Sets whether an optional empty layer ("not set") option is present in the model. + * + * Since QGIS 3.20, the optional \a text and \a icon arguments allows the text and icon for the empty layer item to be set. + * * \see allowEmptyLayer() * \since QGIS 3.0 */ - void setAllowEmptyLayer( bool allowEmpty ); + void setAllowEmptyLayer( bool allowEmpty, const QString &text = QString(), const QIcon &icon = QIcon() ); /** * Returns TRUE if the model allows the empty layer ("not set") choice. @@ -210,6 +214,8 @@ class CORE_EXPORT QgsMapLayerModel : public QAbstractItemModel private: bool mAllowEmpty = false; + QString mEmptyText; + QIcon mEmptyIcon; bool mShowCrs = false; QStringList mAdditionalItems; }; diff --git a/src/gui/qgsmaplayercombobox.cpp b/src/gui/qgsmaplayercombobox.cpp index 9cdce45585a..27246bf41ac 100644 --- a/src/gui/qgsmaplayercombobox.cpp +++ b/src/gui/qgsmaplayercombobox.cpp @@ -44,9 +44,9 @@ QStringList QgsMapLayerComboBox::excludedProviders() const return mProxyModel->excludedProviders(); } -void QgsMapLayerComboBox::setAllowEmptyLayer( bool allowEmpty ) +void QgsMapLayerComboBox::setAllowEmptyLayer( bool allowEmpty, const QString &text, const QIcon &icon ) { - mProxyModel->sourceLayerModel()->setAllowEmptyLayer( allowEmpty ); + mProxyModel->sourceLayerModel()->setAllowEmptyLayer( allowEmpty, text, icon ); } bool QgsMapLayerComboBox::allowEmptyLayer() const diff --git a/src/gui/qgsmaplayercombobox.h b/src/gui/qgsmaplayercombobox.h index 49c4569aa65..ce7773edb56 100644 --- a/src/gui/qgsmaplayercombobox.h +++ b/src/gui/qgsmaplayercombobox.h @@ -75,10 +75,13 @@ class GUI_EXPORT QgsMapLayerComboBox : public QComboBox /** * Sets whether an optional empty layer ("not set") option is shown in the combo box. + * + * Since QGIS 3.20, the optional \a text and \a icon arguments allows the text and icon for the empty layer item to be set. + * * \see allowEmptyLayer() * \since QGIS 3.0 */ - void setAllowEmptyLayer( bool allowEmpty ); + void setAllowEmptyLayer( bool allowEmpty, const QString &text = QString(), const QIcon &icon = QIcon() ); /** * Returns TRUE if the combo box allows the empty layer ("not set") choice. diff --git a/tests/src/python/test_qgsmaplayermodel.py b/tests/src/python/test_qgsmaplayermodel.py index 20a4dfb8897..bc2de7a1e49 100644 --- a/tests/src/python/test_qgsmaplayermodel.py +++ b/tests/src/python/test_qgsmaplayermodel.py @@ -12,7 +12,7 @@ __copyright__ = 'Copyright 2016, The QGIS Project' import qgis # NOQA -from qgis.core import QgsVectorLayer, QgsProject, QgsMapLayerModel +from qgis.core import QgsVectorLayer, QgsProject, QgsMapLayerModel, QgsApplication from qgis.PyQt.QtCore import Qt, QModelIndex from qgis.testing import start_app, unittest @@ -125,6 +125,12 @@ class TestQgsMapLayerModel(unittest.TestCase): self.assertEqual(m.data(m.index(2, 0), Qt.DisplayRole), 'l2') self.assertEqual(m.data(m.index(3, 0), Qt.DisplayRole), 'l3') + self.assertIsNone(m.data(m.index(0, 0), Qt.DecorationRole)) + # set icon and text for empty item + m.setAllowEmptyLayer(True, 'empty', QgsApplication.getThemeIcon('/mItemBookmark.svg')) + self.assertEqual(m.data(m.index(0, 0), Qt.DisplayRole), 'empty') + self.assertFalse(m.data(m.index(0, 0), Qt.DecorationRole).isNull()) + QgsProject.instance().removeMapLayers([l1.id(), l2.id(), l3.id()]) def testAdditionalItems(self):