mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
Tweaks to layout item combo box
This commit is contained in:
parent
0003e91f27
commit
f9fb4085b2
@ -155,6 +155,38 @@ Returns the QgsLayoutItem corresponding to an index from the source
|
||||
QgsLayoutModel model.
|
||||
%End
|
||||
|
||||
QgsLayout *layout();
|
||||
%Docstring
|
||||
Returns the associated layout.
|
||||
|
||||
.. versionadded:: 3.8
|
||||
%End
|
||||
|
||||
void setAllowEmptyItem( bool allowEmpty );
|
||||
%Docstring
|
||||
Sets whether an optional empty layout item is present in the model.
|
||||
|
||||
.. seealso:: :py:func:`allowEmptyItem`
|
||||
|
||||
.. versionadded:: 3.8
|
||||
%End
|
||||
|
||||
bool allowEmptyItem() const;
|
||||
%Docstring
|
||||
Returns ``True`` if the model includes the empty item choice.
|
||||
|
||||
.. seealso:: :py:func:`setAllowEmptyItem`
|
||||
|
||||
.. versionadded:: 3.8
|
||||
%End
|
||||
|
||||
virtual int rowCount( const QModelIndex &parent = QModelIndex() ) const;
|
||||
|
||||
virtual QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const;
|
||||
|
||||
virtual bool setData( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole );
|
||||
|
||||
|
||||
protected:
|
||||
virtual bool filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent ) const;
|
||||
|
||||
|
@ -33,6 +33,15 @@ until setCurrentLayout() is called
|
||||
void setCurrentLayout( QgsLayout *layout );
|
||||
%Docstring
|
||||
Sets the ``layout`` containing the items to list in the combo box.
|
||||
|
||||
.. seealso:: :py:func:`currentLayout`
|
||||
%End
|
||||
|
||||
QgsLayout *currentLayout();
|
||||
%Docstring
|
||||
Returns the current layout containing the items shown in the combo box.
|
||||
|
||||
.. seealso:: :py:func:`setCurrentLayout`
|
||||
%End
|
||||
|
||||
void setItemType( QgsLayoutItemRegistry::ItemType itemType );
|
||||
@ -64,6 +73,24 @@ Sets a list of specific items to exclude from the combo box.
|
||||
Returns the list of specific items excluded from the combo box.
|
||||
|
||||
.. seealso:: :py:func:`setExceptedItemList`
|
||||
%End
|
||||
|
||||
void setAllowEmptyItem( bool allowEmpty );
|
||||
%Docstring
|
||||
Sets whether an optional empty layout item is present in the combobox.
|
||||
|
||||
.. seealso:: :py:func:`allowEmptyItem`
|
||||
|
||||
.. versionadded:: 3.8
|
||||
%End
|
||||
|
||||
bool allowEmptyItem() const;
|
||||
%Docstring
|
||||
Returns ``True`` if the model includes the empty item choice.
|
||||
|
||||
.. seealso:: :py:func:`setAllowEmptyItem`
|
||||
|
||||
.. versionadded:: 3.8
|
||||
%End
|
||||
|
||||
QgsLayoutItem *item( int index ) const;
|
||||
|
@ -323,7 +323,7 @@ QgsLayoutManagerModel::QgsLayoutManagerModel( QgsLayoutManager *manager, QObject
|
||||
int QgsLayoutManagerModel::rowCount( const QModelIndex &parent ) const
|
||||
{
|
||||
Q_UNUSED( parent );
|
||||
return mLayoutManager->layouts().count() + ( mAllowEmpty ? 1 : 0 );
|
||||
return ( mLayoutManager ? mLayoutManager->layouts().count() : 0 ) + ( mAllowEmpty ? 1 : 0 );
|
||||
}
|
||||
|
||||
QVariant QgsLayoutManagerModel::data( const QModelIndex &index, int role ) const
|
||||
@ -339,11 +339,11 @@ QVariant QgsLayoutManagerModel::data( const QModelIndex &index, int role ) const
|
||||
case Qt::DisplayRole:
|
||||
case Qt::ToolTipRole:
|
||||
case Qt::EditRole:
|
||||
return !isEmpty ? mLayoutManager->layouts().at( layoutRow )->name() : QVariant();
|
||||
return !isEmpty && mLayoutManager ? mLayoutManager->layouts().at( layoutRow )->name() : QVariant();
|
||||
|
||||
case LayoutRole:
|
||||
{
|
||||
if ( isEmpty )
|
||||
if ( isEmpty || !mLayoutManager )
|
||||
return QVariant();
|
||||
else if ( QgsLayout *l = dynamic_cast< QgsLayout * >( mLayoutManager->layouts().at( layoutRow ) ) )
|
||||
return QVariant::fromValue( l );
|
||||
@ -355,7 +355,7 @@ QVariant QgsLayoutManagerModel::data( const QModelIndex &index, int role ) const
|
||||
|
||||
case Qt::DecorationRole:
|
||||
{
|
||||
return isEmpty ? QIcon() : mLayoutManager->layouts().at( layoutRow )->icon();
|
||||
return isEmpty || !mLayoutManager ? QIcon() : mLayoutManager->layouts().at( layoutRow )->icon();
|
||||
}
|
||||
|
||||
default:
|
||||
|
@ -958,6 +958,13 @@ QgsLayoutProxyModel::QgsLayoutProxyModel( QgsLayout *layout, QObject *parent )
|
||||
|
||||
bool QgsLayoutProxyModel::lessThan( const QModelIndex &left, const QModelIndex &right ) const
|
||||
{
|
||||
const QString leftText = sourceModel()->data( left, Qt::DisplayRole ).toString();
|
||||
const QString rightText = sourceModel()->data( right, Qt::DisplayRole ).toString();
|
||||
if ( leftText.isEmpty() )
|
||||
return true;
|
||||
if ( rightText.isEmpty() )
|
||||
return false;
|
||||
|
||||
//sort by item id
|
||||
const QgsLayoutItem *item1 = itemFromSourceIndex( left );
|
||||
const QgsLayoutItem *item2 = itemFromSourceIndex( right );
|
||||
@ -970,6 +977,35 @@ bool QgsLayoutProxyModel::lessThan( const QModelIndex &left, const QModelIndex &
|
||||
return QString::localeAwareCompare( item1->displayName(), item2->displayName() ) < 0;
|
||||
}
|
||||
|
||||
int QgsLayoutProxyModel::rowCount( const QModelIndex &parent ) const
|
||||
{
|
||||
return QSortFilterProxyModel::rowCount( parent ) + ( mAllowEmpty ? 1 : 0 );
|
||||
}
|
||||
|
||||
QVariant QgsLayoutProxyModel::data( const QModelIndex &index, int role ) const
|
||||
{
|
||||
if ( mAllowEmpty && index.row() == rowCount() - 1 )
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
else
|
||||
{
|
||||
return QSortFilterProxyModel::data( index, role );
|
||||
}
|
||||
}
|
||||
|
||||
bool QgsLayoutProxyModel::setData( const QModelIndex &index, const QVariant &value, int role )
|
||||
{
|
||||
if ( mAllowEmpty && index.row() == rowCount() - 1 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return QSortFilterProxyModel::setData( index, value, role );
|
||||
}
|
||||
}
|
||||
|
||||
QgsLayoutItem *QgsLayoutProxyModel::itemFromSourceIndex( const QModelIndex &sourceIndex ) const
|
||||
{
|
||||
if ( !mLayout )
|
||||
@ -980,6 +1016,17 @@ QgsLayoutItem *QgsLayoutProxyModel::itemFromSourceIndex( const QModelIndex &sour
|
||||
return qobject_cast<QgsLayoutItem *>( itemAsVariant.value<QObject *>() );
|
||||
}
|
||||
|
||||
void QgsLayoutProxyModel::setAllowEmptyItem( bool allowEmpty )
|
||||
{
|
||||
mAllowEmpty = allowEmpty;
|
||||
invalidateFilter();
|
||||
}
|
||||
|
||||
bool QgsLayoutProxyModel::allowEmptyItem() const
|
||||
{
|
||||
return mAllowEmpty;
|
||||
}
|
||||
|
||||
void QgsLayoutProxyModel::setFilterType( QgsLayoutItemRegistry::ItemType filter )
|
||||
{
|
||||
mItemTypeFilter = filter;
|
||||
@ -1002,7 +1049,7 @@ bool QgsLayoutProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex &so
|
||||
QgsLayoutItem *item = itemFromSourceIndex( index );
|
||||
|
||||
if ( !item )
|
||||
return false;
|
||||
return mAllowEmpty;
|
||||
|
||||
// specific exceptions
|
||||
if ( mExceptedList.contains( item ) )
|
||||
|
@ -352,6 +352,30 @@ class CORE_EXPORT QgsLayoutProxyModel: public QSortFilterProxyModel
|
||||
*/
|
||||
QgsLayoutItem *itemFromSourceIndex( const QModelIndex &sourceIndex ) const;
|
||||
|
||||
/**
|
||||
* Returns the associated layout.
|
||||
* \since QGIS 3.8
|
||||
*/
|
||||
QgsLayout *layout() { return mLayout; }
|
||||
|
||||
/**
|
||||
* Sets whether an optional empty layout item is present in the model.
|
||||
* \see allowEmptyItem()
|
||||
* \since QGIS 3.8
|
||||
*/
|
||||
void setAllowEmptyItem( bool allowEmpty );
|
||||
|
||||
/**
|
||||
* Returns TRUE if the model includes the empty item choice.
|
||||
* \see setAllowEmptyItem()
|
||||
* \since QGIS 3.8
|
||||
*/
|
||||
bool allowEmptyItem() const;
|
||||
|
||||
int rowCount( const QModelIndex &parent = QModelIndex() ) const override;
|
||||
QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const override;
|
||||
bool setData( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole ) override;
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent ) const override;
|
||||
bool lessThan( const QModelIndex &left, const QModelIndex &right ) const override;
|
||||
@ -360,6 +384,7 @@ class CORE_EXPORT QgsLayoutProxyModel: public QSortFilterProxyModel
|
||||
QgsLayout *mLayout = nullptr;
|
||||
QgsLayoutItemRegistry::ItemType mItemTypeFilter;
|
||||
QList< QgsLayoutItem * > mExceptedList;
|
||||
bool mAllowEmpty = false;
|
||||
|
||||
};
|
||||
|
||||
|
@ -35,6 +35,11 @@ void QgsLayoutItemComboBox::setCurrentLayout( QgsLayout *layout )
|
||||
mProxyModel->sort( 0, Qt::AscendingOrder );
|
||||
}
|
||||
|
||||
QgsLayout *QgsLayoutItemComboBox::currentLayout()
|
||||
{
|
||||
return mProxyModel->layout();
|
||||
}
|
||||
|
||||
void QgsLayoutItemComboBox::setItem( const QgsLayoutItem *item )
|
||||
{
|
||||
if ( !mProxyModel->sourceLayerModel() )
|
||||
@ -50,7 +55,7 @@ void QgsLayoutItemComboBox::setItem( const QgsLayoutItem *item )
|
||||
return;
|
||||
}
|
||||
}
|
||||
setCurrentIndex( -1 );
|
||||
setCurrentIndex( mProxyModel->allowEmptyItem() ? 0 : -1 );
|
||||
}
|
||||
|
||||
QgsLayoutItem *QgsLayoutItemComboBox::currentItem() const
|
||||
@ -97,6 +102,16 @@ QList< QgsLayoutItem *> QgsLayoutItemComboBox::exceptedItemList() const
|
||||
return mProxyModel->exceptedItemList();
|
||||
}
|
||||
|
||||
void QgsLayoutItemComboBox::setAllowEmptyItem( bool allowEmpty )
|
||||
{
|
||||
mProxyModel->setAllowEmptyItem( allowEmpty );
|
||||
}
|
||||
|
||||
bool QgsLayoutItemComboBox::allowEmptyItem() const
|
||||
{
|
||||
return mProxyModel->allowEmptyItem();
|
||||
}
|
||||
|
||||
QgsLayoutItem *QgsLayoutItemComboBox::item( int index ) const
|
||||
{
|
||||
const QModelIndex proxyIndex = mProxyModel->index( index, 0 );
|
||||
|
@ -46,9 +46,18 @@ class GUI_EXPORT QgsLayoutItemComboBox : public QComboBox
|
||||
|
||||
/**
|
||||
* Sets the \a layout containing the items to list in the combo box.
|
||||
*
|
||||
* \see currentLayout()
|
||||
*/
|
||||
void setCurrentLayout( QgsLayout *layout );
|
||||
|
||||
/**
|
||||
* Returns the current layout containing the items shown in the combo box.
|
||||
*
|
||||
* \see setCurrentLayout()
|
||||
*/
|
||||
QgsLayout *currentLayout();
|
||||
|
||||
/**
|
||||
* Sets a filter for the item type to show in the combo box.
|
||||
* \param itemType type of items to show. Set to QgsLayoutItemRegistry::LayoutItem to
|
||||
@ -75,6 +84,20 @@ class GUI_EXPORT QgsLayoutItemComboBox : public QComboBox
|
||||
*/
|
||||
QList< QgsLayoutItem * > exceptedItemList() const;
|
||||
|
||||
/**
|
||||
* Sets whether an optional empty layout item is present in the combobox.
|
||||
* \see allowEmptyItem()
|
||||
* \since QGIS 3.8
|
||||
*/
|
||||
void setAllowEmptyItem( bool allowEmpty );
|
||||
|
||||
/**
|
||||
* Returns TRUE if the model includes the empty item choice.
|
||||
* \see setAllowEmptyItem()
|
||||
* \since QGIS 3.8
|
||||
*/
|
||||
bool allowEmptyItem() const;
|
||||
|
||||
/**
|
||||
* Returns the item currently shown at the specified \a index within the combo box.
|
||||
* \see currentItem()
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "qgsapplication.h"
|
||||
#include "qgsmapsettings.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgslayoutitemlabel.h"
|
||||
|
||||
#include <QObject>
|
||||
#include "qgstest.h"
|
||||
@ -58,6 +59,7 @@ class TestQgsLayoutModel : public QObject
|
||||
void reorderToTopWithRemoved(); //test reordering to top with removed items
|
||||
void reorderToBottomWithRemoved(); //test reordering to bottom with removed items
|
||||
|
||||
void proxy();
|
||||
void proxyCrash();
|
||||
|
||||
};
|
||||
@ -771,6 +773,48 @@ void TestQgsLayoutModel::reorderToBottomWithRemoved()
|
||||
QCOMPARE( layout.itemsModel()->mItemsInScene.at( 1 ), item2 );
|
||||
}
|
||||
|
||||
void TestQgsLayoutModel::proxy()
|
||||
{
|
||||
QgsLayout *layout = new QgsLayout( QgsProject::instance() );
|
||||
QgsLayoutProxyModel *proxy = new QgsLayoutProxyModel( layout );
|
||||
// add some items to composition
|
||||
QgsLayoutItemMap *item1 = new QgsLayoutItemMap( layout );
|
||||
item1->setId( QStringLiteral( "c" ) );
|
||||
layout->addLayoutItem( item1 );
|
||||
QgsLayoutItemMap *item2 = new QgsLayoutItemMap( layout );
|
||||
item2->setId( QStringLiteral( "b" ) );
|
||||
layout->addLayoutItem( item2 );
|
||||
QgsLayoutItemLabel *item3 = new QgsLayoutItemLabel( layout );
|
||||
item3->setId( QStringLiteral( "a" ) );
|
||||
layout->addLayoutItem( item3 );
|
||||
QCOMPARE( proxy->rowCount( QModelIndex() ), 3 );
|
||||
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" ) );
|
||||
|
||||
proxy->setAllowEmptyItem( true );
|
||||
QCOMPARE( proxy->rowCount( QModelIndex() ), 4 );
|
||||
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(), QString() );
|
||||
|
||||
proxy->setFilterType( QgsLayoutItemRegistry::LayoutMap );
|
||||
QCOMPARE( proxy->rowCount( QModelIndex() ), 3 );
|
||||
QCOMPARE( proxy->data( proxy->index( 0, 2, QModelIndex() ) ).toString(), QStringLiteral( "b" ) );
|
||||
QCOMPARE( proxy->data( proxy->index( 1, 2, QModelIndex() ) ).toString(), QStringLiteral( "c" ) );
|
||||
QCOMPARE( proxy->data( proxy->index( 2, 2, QModelIndex() ) ).toString(), QString() );
|
||||
|
||||
proxy->setFilterType( QgsLayoutItemRegistry::LayoutLabel );
|
||||
QCOMPARE( proxy->rowCount( QModelIndex() ), 2 );
|
||||
QCOMPARE( proxy->data( proxy->index( 0, 2, QModelIndex() ) ).toString(), QStringLiteral( "a" ) );
|
||||
QCOMPARE( proxy->data( proxy->index( 1, 2, QModelIndex() ) ).toString(), QString() );
|
||||
|
||||
proxy->setFilterType( QgsLayoutItemRegistry::LayoutScaleBar );
|
||||
QCOMPARE( proxy->rowCount( QModelIndex() ), 1 );
|
||||
QCOMPARE( proxy->data( proxy->index( 0, 2, QModelIndex() ) ).toString(), QString() );
|
||||
}
|
||||
|
||||
void TestQgsLayoutModel::proxyCrash()
|
||||
{
|
||||
// test for a possible crash when using QgsComposerProxyModel and reordering items
|
||||
|
Loading…
x
Reference in New Issue
Block a user