Skip to content
Permalink
Browse files

[composer] New QSortFilterProxyModel for filtering items by type

and new widget QgsComposerItemComboBox for showing matching composer
items.

Swap existing comboboxes to use the new widget, which removes a lot
of fragile code designed to allow selection of items. Additionally
the combobox now show the correct item id rather than always showing
"Map 0/1/..."
  • Loading branch information
nyalldawson committed Apr 8, 2016
1 parent 4764b53 commit 1b4bd47076103e931e642c9c2b6a363f14b20a45
@@ -23,6 +23,14 @@ class QgsComposerModel : QAbstractItemModel
%End
public:

//! Columns returned by the model
enum Columns
{
Visibility, /*!< Item visibility check box */
LockStatus, /*!< Item lock status check box */
ItemId, /*!< Item ID */
};

/** Constructor
* @param composition composition to attach to
* @param parent parent object
@@ -202,6 +210,13 @@ class QgsComposerModel : QAbstractItemModel
*/
void updateItemSelectStatus( QgsComposerItem *item );

/** Returns the QModelIndex corresponding to a QgsComposerItem, if possible
* @param item QgsComposerItem to find index for
* @param column column number for created QModelIndex
* @returns QModelIndex corresponding to item and specified column
*/
QModelIndex indexForItem( QgsComposerItem *item, const int column = 0 );

public slots:

/** Sets an item as the current selection from a QModelIndex
@@ -210,3 +225,65 @@ class QgsComposerModel : QAbstractItemModel
*/
void setSelected( const QModelIndex &index );
};


/**
* /class QgsComposerProxyModel
* /ingroup core
* /brief Allows for filtering a QgsComposerModel by item type.
* /note added in 2.16
*/
class QgsComposerProxyModel: QSortFilterProxyModel
{
%TypeHeaderCode
#include "qgscomposermodel.h"
%End
public:

/** Constructor for QgsComposerProxyModel.
* @param composition composition to attach model to
* @param parent optional parent
*/
QgsComposerProxyModel( QgsComposition* composition, QObject *parent /TransferThis/ = nullptr );

/** Returns the current item type filter, or QgsComposerItem::ComposerItem if no
* item type filter is set.
* @see setFilterType()
*/
QgsComposerItem::ItemType filterType() const;

/** Sets the item type filter. Only matching item types will be shown.
* @param itemType type to filter. Set to QgsComposerItem::ComposerItem to show all
* item types.
* @see filterType()
*/
void setFilterType( QgsComposerItem::ItemType itemType );

/** Sets a list of specific items to exclude from the model
* @param exceptList list of items to exclude
* @see exceptedItemList()
*/
void setExceptedItemList( const QList< QgsComposerItem* >& exceptList );

/** Returns the list of specific items excluded from the model.
* @see setExceptedItemList()
*/
QList< QgsComposerItem* > exceptedItemList() const;

/** Returns the QgsComposerModel used in this proxy model.
*/
QgsComposerModel* sourceLayerModel() const;

/** Returns the QgsComposerItem corresponding to an index from the source
* QgsComposerModel model.
* @param sourceIndex a QModelIndex
* @returns QgsComposerItem for specified index from QgsComposerModel
*/
QgsComposerItem* itemFromSourceIndex( const QModelIndex& sourceIndex ) const;

protected:
bool filterAcceptsRow( int source_row, const QModelIndex & source_parent ) const;
bool lessThan( const QModelIndex &left, const QModelIndex &right ) const;

};

@@ -49,6 +49,7 @@
%Include qgscolorschemelist.sip
%Include qgscolorswatchgrid.sip
%Include qgscolorwidgets.sip
%Include qgscomposeritemcombobox.sip
%Include qgscomposerruler.sip
%Include qgscomposerview.sip
%Include qgscredentialdialog.sip
@@ -0,0 +1,72 @@
/**
* /class QgsComposerItemComboBox
* /ingroup gui
* /brief The QgsComposerItemComboBox class is a combo box which displays items of
* a matching type from a composition.
* /note added in 2.16
*/
class QgsComposerItemComboBox : QComboBox
{
%TypeHeaderCode
#include "qgscomposeritemcombobox.h"
%End

public:
/**
* QgsComposerItemComboBox creates a combo box to display a list of items in a
* composition. The items can optionally be filtered by type.
* @param parent parent widget
* @param composition composition to show items from. If not set, no items will be shown
* until setComposition() is called
*/
explicit QgsComposerItemComboBox( QWidget* parent /TransferThis/ = nullptr, QgsComposition* composition = nullptr );

/** Sets the composition containing the items to list in the combo box.
*/
void setComposition( QgsComposition* composition );

/** Sets a filter for the item type to show in the combo box.
* @param itemType type of items to show. Set to QgsComposerItem::ComposerItem to
* show all items.
* @see itemType()
*/
void setItemType( QgsComposerItem::ItemType itemType );

/** Returns the filter for the item types to show in the combo box.
* @see setItemType()
*/
QgsComposerItem::ItemType itemType() const;

/** Sets a list of specific items to exclude from the combo box.
* @param exceptList list of items to exclude
* @see exceptedItemList()
*/
void setExceptedItemList( const QList< QgsComposerItem* >& exceptList );

/** Returns the list of specific items excluded from the combo box.
* @see setExceptedItemList()
*/
QList< QgsComposerItem* > exceptedItemList() const;

/** Return the item currently shown at the specified index within the combo box.
* @param index position of item to return
* @see currentItem()
*/
const QgsComposerItem* item( int index ) const;

/** Returns the item currently selected in the combo box.
*/
const QgsComposerItem* currentItem() const;

public slots:
/** Sets the currently selected item in the combo box.
* @param item selected item
*/
void setItem( const QgsComposerItem* item );

signals:

//! Emitted whenever the currently selected item changes
void itemChanged( QgsComposerItem* item );

};
@@ -61,7 +61,9 @@ QgsComposerAttributeTableWidget::QgsComposerAttributeTableWidget( QgsComposerAtt
mLayerComboBox->setFilters( QgsMapLayerProxyModel::VectorLayer );
connect( mLayerComboBox, SIGNAL( layerChanged( QgsMapLayer* ) ), this, SLOT( changeLayer( QgsMapLayer* ) ) );

refreshMapComboBox();
mComposerMapComboBox->setComposition( mComposerTable->composition() );
mComposerMapComboBox->setItemType( QgsComposerItem::ComposerMap );
connect( mComposerMapComboBox, SIGNAL( itemChanged( const QgsComposerItem* ) ), this, SLOT( composerMapChanged( const QgsComposerItem* ) ) );

mHeaderFontColorButton->setColorDialogTitle( tr( "Select header font color" ) );
mHeaderFontColorButton->setAllowAlpha( true );
@@ -80,7 +82,6 @@ QgsComposerAttributeTableWidget::QgsComposerAttributeTableWidget( QgsComposerAtt
mBackgroundColorButton->setNoColorString( tr( "No background" ) );

updateGuiElements();
on_mComposerMapComboBox_activated( mComposerMapComboBox->currentIndex() );

if ( mComposerTable )
{
@@ -107,47 +108,6 @@ QgsComposerAttributeTableWidget::QgsComposerAttributeTableWidget( QgsComposerAtt

QgsComposerAttributeTableWidget::~QgsComposerAttributeTableWidget()
{

}

void QgsComposerAttributeTableWidget::showEvent( QShowEvent* /* event */ )
{
refreshMapComboBox();
}

void QgsComposerAttributeTableWidget::refreshMapComboBox()
{
//save the current entry in case it is still present after refresh
QString saveCurrentComboText = mComposerMapComboBox->currentText();

mComposerMapComboBox->blockSignals( true );
mComposerMapComboBox->clear();
if ( mComposerTable )
{
const QgsComposition* tableComposition = mComposerTable->composition();
if ( tableComposition )
{
QList<const QgsComposerMap*> mapList = tableComposition->composerMapItems();
QList<const QgsComposerMap*>::const_iterator mapIt = mapList.constBegin();
for ( ; mapIt != mapList.constEnd(); ++mapIt )
{
int mapId = ( *mapIt )->id();
mComposerMapComboBox->addItem( tr( "Map %1" ).arg( mapId ), mapId );
}
}
}
mComposerMapComboBox->blockSignals( false );

if ( mComposerMapComboBox->findText( saveCurrentComboText ) == -1 )
{
//the former entry is no longer present. Inform the scalebar about the changed composer map
on_mComposerMapComboBox_activated( mComposerMapComboBox->currentIndex() );
}
else
{
//the former entry is still present. Make it the current entry again
mComposerMapComboBox->setCurrentIndex( mComposerMapComboBox->findText( saveCurrentComboText ) );
}
}

void QgsComposerAttributeTableWidget::on_mRefreshPushButton_clicked()
@@ -213,31 +173,24 @@ void QgsComposerAttributeTableWidget::on_mAttributesPushButton_clicked()
}
}

void QgsComposerAttributeTableWidget::on_mComposerMapComboBox_activated( int index )
void QgsComposerAttributeTableWidget::composerMapChanged( const QgsComposerItem* item )
{
if ( !mComposerTable )
{
return;
}

QVariant itemData = mComposerMapComboBox->itemData( index );
if ( itemData.type() == QVariant::Invalid )
{
return;
}

int mapId = itemData.toInt();
const QgsComposition* tableComposition = mComposerTable->composition();
if ( tableComposition )
{
QgsComposition* composition = mComposerTable->composition();
if ( sender() && composition ) //only create command if called from GUI
if ( composition )
{
composition->beginMultiFrameCommand( mComposerTable, tr( "Table map changed" ) );
}
mComposerTable->setComposerMap( tableComposition->getComposerMapById( mapId ) );
mComposerTable->setComposerMap( dynamic_cast< const QgsComposerMap* >( item ) );
mComposerTable->update();
if ( sender() && composition )
if ( composition )
{
composition->endMultiFrameCommand();
}
@@ -467,16 +420,7 @@ void QgsComposerAttributeTableWidget::updateGuiElements()
}
}

//map combo box
const QgsComposerMap* cm = mComposerTable->composerMap();
if ( cm )
{
int mapIndex = mComposerMapComboBox->findText( tr( "Map %1" ).arg( cm->id() ) );
if ( mapIndex != -1 )
{
mComposerMapComboBox->setCurrentIndex( mapIndex );
}
}
mComposerMapComboBox->setItem( mComposerTable->composerMap() );
mMaximumRowsSpinBox->setValue( mComposerTable->maximumNumberOfFeatures() );
mMarginSpinBox->setValue( mComposerTable->cellMargin() );
mGridStrokeWidthSpinBox->setValue( mComposerTable->gridStrokeWidth() );
@@ -31,16 +31,12 @@ class QgsComposerAttributeTableWidget: public QgsComposerItemBaseWidget, private
QgsComposerAttributeTableWidget( QgsComposerAttributeTableV2* table, QgsComposerFrame* frame );
~QgsComposerAttributeTableWidget();

protected:
void showEvent( QShowEvent * event ) override;

private:
QgsComposerAttributeTableV2* mComposerTable;
QgsComposerFrame* mFrame;

/** Blocks / unblocks the signals of all GUI elements*/
void blockAllSignals( bool b );
void refreshMapComboBox();

void toggleSourceControls();

@@ -49,7 +45,7 @@ class QgsComposerAttributeTableWidget: public QgsComposerItemBaseWidget, private
private slots:
void on_mRefreshPushButton_clicked();
void on_mAttributesPushButton_clicked();
void on_mComposerMapComboBox_activated( int index );
void composerMapChanged( const QgsComposerItem* item );
void on_mMaximumRowsSpinBox_valueChanged( int i );
void on_mMarginSpinBox_valueChanged( double d );
void on_mGridStrokeWidthSpinBox_valueChanged( double d );

0 comments on commit 1b4bd47

Please sign in to comment.
You can’t perform that action at this time.