Skip to content

Commit

Permalink
[composer] New QSortFilterProxyModel for filtering items by type
Browse files Browse the repository at this point in the history
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 1b4bd47
Show file tree
Hide file tree
Showing 26 changed files with 733 additions and 599 deletions.
77 changes: 77 additions & 0 deletions python/core/composer/qgscomposermodel.sip
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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;

};

1 change: 1 addition & 0 deletions python/gui/gui.sip
Expand Up @@ -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
Expand Down
72 changes: 72 additions & 0 deletions python/gui/qgscomposeritemcombobox.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 );

};
72 changes: 8 additions & 64 deletions src/app/composer/qgscomposerattributetablewidget.cpp
Expand Up @@ -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 );
Expand All @@ -80,7 +82,6 @@ QgsComposerAttributeTableWidget::QgsComposerAttributeTableWidget( QgsComposerAtt
mBackgroundColorButton->setNoColorString( tr( "No background" ) );

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

if ( mComposerTable )
{
Expand All @@ -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()
Expand Down Expand Up @@ -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();
}
Expand Down Expand Up @@ -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() );
Expand Down
6 changes: 1 addition & 5 deletions src/app/composer/qgscomposerattributetablewidget.h
Expand Up @@ -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();

Expand All @@ -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 );
Expand Down

0 comments on commit 1b4bd47

Please sign in to comment.