Skip to content

Commit

Permalink
Add method to filter QgsLayoutItemComboBox by item flags
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jul 30, 2020
1 parent 836666e commit 6d647aa
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 3 deletions.
22 changes: 22 additions & 0 deletions python/core/auto_generated/layout/qgslayoutmodel.sip.in
Expand Up @@ -178,6 +178,28 @@ Returns ``True`` if the model includes the empty item choice.
.. seealso:: :py:func:`setAllowEmptyItem`

.. versionadded:: 3.8
%End

void setItemFlags( QgsLayoutItem::Flags flags );
%Docstring
Sets layout item flags to use for filtering the available items.

Set ``flags`` to ``None`` to clear the flag based filtering.

.. seealso:: :py:func:`itemFlags`

.. versionadded:: 3.16
%End

QgsLayoutItem::Flags itemFlags() const;
%Docstring
Returns the layout item flags used for filtering the available items.

Returns ``None`` if no flag based filtering is occurring.

.. seealso:: :py:func:`setItemFlags`

.. versionadded:: 3.16
%End

protected:
Expand Down
22 changes: 22 additions & 0 deletions python/gui/auto_generated/layout/qgslayoutitemcombobox.sip.in
Expand Up @@ -92,6 +92,28 @@ Returns ``True`` if the model includes the empty item choice.
.. seealso:: :py:func:`setAllowEmptyItem`

.. versionadded:: 3.8
%End

void setItemFlags( QgsLayoutItem::Flags flags );
%Docstring
Sets layout item flags to use for filtering the available items.

Set ``flags`` to ``None`` to clear the flag based filtering.

.. seealso:: :py:func:`itemFlags`

.. versionadded:: 3.16
%End

QgsLayoutItem::Flags itemFlags() const;
%Docstring
Returns the layout item flags used for filtering the available items.

Returns ``None`` if no flag based filtering is occurring.

.. seealso:: :py:func:`setItemFlags`

.. versionadded:: 3.16
%End

QgsLayoutItem *item( int index ) const;
Expand Down
16 changes: 16 additions & 0 deletions src/core/layout/qgslayoutmodel.cpp
Expand Up @@ -1000,6 +1000,17 @@ bool QgsLayoutProxyModel::allowEmptyItem() const
return mAllowEmpty;
}

void QgsLayoutProxyModel::setItemFlags( QgsLayoutItem::Flags flags )
{
mItemFlags = flags;
invalidateFilter();
}

QgsLayoutItem::Flags QgsLayoutProxyModel::itemFlags() const
{
return mItemFlags;
}

void QgsLayoutProxyModel::setFilterType( QgsLayoutItemRegistry::ItemType filter )
{
mItemTypeFilter = filter;
Expand Down Expand Up @@ -1032,6 +1043,11 @@ bool QgsLayoutProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex &so
if ( mItemTypeFilter != QgsLayoutItemRegistry::LayoutItem && item->type() != mItemTypeFilter )
return false;

if ( mItemFlags && !( item->itemFlags() & mItemFlags ) )
{
return false;
}

return true;
}

21 changes: 21 additions & 0 deletions src/core/layout/qgslayoutmodel.h
Expand Up @@ -372,6 +372,26 @@ class CORE_EXPORT QgsLayoutProxyModel: public QSortFilterProxyModel
*/
bool allowEmptyItem() const;

/**
* Sets layout item flags to use for filtering the available items.
*
* Set \a flags to NULLPTR to clear the flag based filtering.
*
* \see itemFlags()
* \since QGIS 3.16
*/
void setItemFlags( QgsLayoutItem::Flags flags );

/**
* Returns the layout item flags used for filtering the available items.
*
* Returns NULLPTR if no flag based filtering is occurring.
*
* \see setItemFlags()
* \since QGIS 3.16
*/
QgsLayoutItem::Flags itemFlags() const;

protected:
bool filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent ) const override;
bool lessThan( const QModelIndex &left, const QModelIndex &right ) const override;
Expand All @@ -381,6 +401,7 @@ class CORE_EXPORT QgsLayoutProxyModel: public QSortFilterProxyModel
QgsLayoutItemRegistry::ItemType mItemTypeFilter;
QList< QgsLayoutItem * > mExceptedList;
bool mAllowEmpty = false;
QgsLayoutItem::Flags mItemFlags = nullptr;

};

Expand Down
10 changes: 10 additions & 0 deletions src/gui/layout/qgslayoutitemcombobox.cpp
Expand Up @@ -121,6 +121,16 @@ bool QgsLayoutItemComboBox::allowEmptyItem() const
return mProxyModel->allowEmptyItem();
}

void QgsLayoutItemComboBox::setItemFlags( QgsLayoutItem::Flags flags )
{
mProxyModel->setItemFlags( flags );
}

QgsLayoutItem::Flags QgsLayoutItemComboBox::itemFlags() const
{
return mProxyModel->itemFlags();
}

QgsLayoutItem *QgsLayoutItemComboBox::item( int index ) const
{
const QModelIndex proxyIndex = mProxyModel->index( index, 0 );
Expand Down
20 changes: 20 additions & 0 deletions src/gui/layout/qgslayoutitemcombobox.h
Expand Up @@ -99,6 +99,26 @@ class GUI_EXPORT QgsLayoutItemComboBox : public QComboBox
*/
bool allowEmptyItem() const;

/**
* Sets layout item flags to use for filtering the available items.
*
* Set \a flags to NULLPTR to clear the flag based filtering.
*
* \see itemFlags()
* \since QGIS 3.16
*/
void setItemFlags( QgsLayoutItem::Flags flags );

/**
* Returns the layout item flags used for filtering the available items.
*
* Returns NULLPTR if no flag based filtering is occurring.
*
* \see setItemFlags()
* \since QGIS 3.16
*/
QgsLayoutItem::Flags itemFlags() const;

/**
* Returns the item currently shown at the specified \a index within the combo box.
* \see currentItem()
Expand Down
25 changes: 23 additions & 2 deletions tests/src/core/testqgslayoutmodel.cpp
Expand Up @@ -23,6 +23,7 @@
#include "qgsproject.h"
#include "qgslayoutitemlabel.h"
#include "qgslayoutitemgroup.h"
#include "qgslayoutitemshape.h"
#include <QObject>
#include "qgstest.h"
#include <QList>
Expand Down Expand Up @@ -967,17 +968,27 @@ void TestQgsLayoutModel::proxy()
QgsLayoutItemLabel *item3 = new QgsLayoutItemLabel( layout );
item3->setId( QStringLiteral( "a" ) );
layout->addLayoutItem( item3 );
QCOMPARE( proxy->rowCount( QModelIndex() ), 3 );
QgsLayoutItemShape *item4 = new QgsLayoutItemShape( layout );
item4->setId( QStringLiteral( "d" ) );
layout->addLayoutItem( item4 );
QgsLayoutItemShape *item5 = new QgsLayoutItemShape( layout );
item5->setId( QStringLiteral( "e" ) );
layout->addLayoutItem( item5 );
QCOMPARE( proxy->rowCount( QModelIndex() ), 5 );
QCOMPARE( proxy->data( proxy->index( 0, 2, QModelIndex() ) ).toString(), QStringLiteral( "a" ) );
QCOMPARE( proxy->data( proxy->index( 1, 2, QModelIndex() ) ).toString(), QStringLiteral( "b" ) );
QCOMPARE( proxy->data( proxy->index( 2, 2, QModelIndex() ) ).toString(), QStringLiteral( "c" ) );
QCOMPARE( proxy->data( proxy->index( 3, 2, QModelIndex() ) ).toString(), QStringLiteral( "d" ) );
QCOMPARE( proxy->data( proxy->index( 4, 2, QModelIndex() ) ).toString(), QStringLiteral( "e" ) );

proxy->setAllowEmptyItem( true );
QCOMPARE( proxy->rowCount( QModelIndex() ), 4 );
QCOMPARE( proxy->rowCount( QModelIndex() ), 6 );
QCOMPARE( proxy->data( proxy->index( 0, 2, QModelIndex() ) ).toString(), QString() );
QCOMPARE( proxy->data( proxy->index( 1, 2, QModelIndex() ) ).toString(), QStringLiteral( "a" ) );
QCOMPARE( proxy->data( proxy->index( 2, 2, QModelIndex() ) ).toString(), QStringLiteral( "b" ) );
QCOMPARE( proxy->data( proxy->index( 3, 2, QModelIndex() ) ).toString(), QStringLiteral( "c" ) );
QCOMPARE( proxy->data( proxy->index( 4, 2, QModelIndex() ) ).toString(), QStringLiteral( "d" ) );
QCOMPARE( proxy->data( proxy->index( 5, 2, QModelIndex() ) ).toString(), QStringLiteral( "e" ) );

proxy->setFilterType( QgsLayoutItemRegistry::LayoutMap );
QCOMPARE( proxy->rowCount( QModelIndex() ), 3 );
Expand All @@ -993,6 +1004,16 @@ void TestQgsLayoutModel::proxy()
proxy->setFilterType( QgsLayoutItemRegistry::LayoutScaleBar );
QCOMPARE( proxy->rowCount( QModelIndex() ), 1 );
QCOMPARE( proxy->data( proxy->index( 0, 2, QModelIndex() ) ).toString(), QString() );

proxy->setAllowEmptyItem( false );
proxy->setFilterType( QgsLayoutItemRegistry::LayoutItem );
QCOMPARE( proxy->rowCount( QModelIndex() ), 5 );
proxy->setItemFlags( QgsLayoutItem::FlagProvidesClipPath );
QCOMPARE( proxy->rowCount( QModelIndex() ), 2 );
QCOMPARE( proxy->data( proxy->index( 0, 2, QModelIndex() ) ).toString(), QStringLiteral( "d" ) );
QCOMPARE( proxy->data( proxy->index( 1, 2, QModelIndex() ) ).toString(), QStringLiteral( "e" ) );
proxy->setItemFlags( nullptr );
QCOMPARE( proxy->rowCount( QModelIndex() ), 5 );
}

void TestQgsLayoutModel::proxyCrash()
Expand Down
21 changes: 20 additions & 1 deletion tests/src/python/test_qgslayoutitemcombobox.py
Expand Up @@ -16,7 +16,9 @@
QgsPrintLayout,
QgsLayoutItemMap,
QgsLayoutItemLabel,
QgsLayoutItemRegistry)
QgsLayoutItemRegistry,
QgsLayoutItemShape,
QgsLayoutItem)
from qgis.gui import QgsLayoutItemComboBox
from qgis.PyQt.QtCore import Qt, QModelIndex
from qgis.testing import start_app, unittest
Expand Down Expand Up @@ -242,6 +244,23 @@ def testCombo(self):
self.assertIsNone(combo.currentItem())
self.assertEqual(combo.currentIndex(), -1)

combo.setItemType(QgsLayoutItemRegistry.LayoutItem)
self.assertEqual(combo.count(), 2)
combo.setItemFlags(QgsLayoutItem.FlagProvidesClipPath)
self.assertEqual(combo.count(), 0)
shape = QgsLayoutItemShape(layout)
shape.setId('shape 1')
layout.addLayoutItem(shape)
self.assertEqual(combo.count(), 1)
shape2 = QgsLayoutItemShape(layout)
shape2.setId('shape 2')
layout.addLayoutItem(shape2)
self.assertEqual(combo.count(), 2)
self.assertEqual(combo.itemText(0), 'shape 1')
self.assertEqual(combo.itemText(1), 'shape 2')
combo.setItemFlags(QgsLayoutItem.Flags())
self.assertEqual(combo.count(), 4)


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

0 comments on commit 6d647aa

Please sign in to comment.