[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/..."
This commit is contained in:
Nyall Dawson 2016-04-08 19:27:34 +10:00
parent 4764b53518
commit 1b4bd47076
26 changed files with 733 additions and 599 deletions

View File

@ -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;
};

View File

@ -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

View File

@ -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 );
};

View File

@ -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() );

View File

@ -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 );

View File

@ -64,6 +64,10 @@ QgsComposerLegendWidget::QgsComposerLegendWidget( QgsComposerLegend* legend )
mRasterBorderColorButton->setAllowAlpha( true );
mRasterBorderColorButton->setContext( "composer " );
mMapComboBox->setComposition( legend->composition() );
mMapComboBox->setItemType( QgsComposerItem::ComposerMap );
connect( mMapComboBox, SIGNAL( itemChanged( const QgsComposerItem* ) ), this, SLOT( composerMapChanged( const QgsComposerItem* ) ) );
//add widget for item properties
QgsComposerItemWidget* itemPropertiesWidget = new QgsComposerItemWidget( this, legend );
mainLayout->addWidget( itemPropertiesWidget );
@ -132,17 +136,9 @@ void QgsComposerLegendWidget::setGuiElements()
mRasterBorderColorButton->setColor( mLegend->rasterBorderColor() );
mCheckBoxAutoUpdate->setChecked( mLegend->autoUpdateModel() );
refreshMapComboBox();
const QgsComposerMap* map = mLegend->composerMap();
if ( map )
{
mMapComboBox->setCurrentIndex( mMapComboBox->findData( map->id() ) );
}
else
{
mMapComboBox->setCurrentIndex( mMapComboBox->findData( -1 ) );
}
mMapComboBox->setItem( map );
mFontColorButton->setColor( mLegend->fontColor() );
blockAllSignals( false );
@ -553,40 +549,26 @@ void QgsComposerLegendWidget::on_mCheckBoxAutoUpdate_stateChanged( int state )
}
}
void QgsComposerLegendWidget::on_mMapComboBox_currentIndexChanged( int index )
void QgsComposerLegendWidget::composerMapChanged( const QgsComposerItem* item )
{
if ( !mLegend )
{
return;
}
QVariant itemData = mMapComboBox->itemData( index );
if ( itemData.type() == QVariant::Invalid )
{
return;
}
const QgsComposition* comp = mLegend->composition();
if ( !comp )
{
return;
}
int mapNr = itemData.toInt();
if ( mapNr < 0 )
const QgsComposerMap* map = dynamic_cast< const QgsComposerMap* >( item );
if ( map )
{
mLegend->setComposerMap( nullptr );
}
else
{
const QgsComposerMap* map = comp->getComposerMapById( mapNr );
if ( map )
{
mLegend->beginCommand( tr( "Legend map changed" ) );
mLegend->setComposerMap( map );
mLegend->updateItem();
mLegend->endCommand();
}
mLegend->beginCommand( tr( "Legend map changed" ) );
mLegend->setComposerMap( map );
mLegend->updateItem();
mLegend->endCommand();
}
}
@ -959,48 +941,6 @@ void QgsComposerLegendWidget::blockAllSignals( bool b )
mRasterBorderWidthSpinBox->blockSignals( b );
}
void QgsComposerLegendWidget::refreshMapComboBox()
{
if ( !mLegend )
{
return;
}
const QgsComposition* composition = mLegend->composition();
if ( !composition )
{
return;
}
//save current entry
int currentMapId = mMapComboBox->itemData( mMapComboBox->currentIndex() ).toInt();
mMapComboBox->clear();
QList<const QgsComposerMap*> availableMaps = composition->composerMapItems();
QList<const QgsComposerMap*>::const_iterator mapItemIt = availableMaps.constBegin();
for ( ; mapItemIt != availableMaps.constEnd(); ++mapItemIt )
{
mMapComboBox->addItem( tr( "Map %1" ).arg(( *mapItemIt )->id() ), ( *mapItemIt )->id() );
}
mMapComboBox->addItem( tr( "None" ), -1 );
//the former entry is not there anymore
int entry = mMapComboBox->findData( currentMapId );
if ( entry == -1 )
{
}
else
{
mMapComboBox->setCurrentIndex( entry );
}
}
void QgsComposerLegendWidget::showEvent( QShowEvent * event )
{
refreshMapComboBox();
QWidget::showEvent( event );
}
void QgsComposerLegendWidget::selectedChanged( const QModelIndex & current, const QModelIndex & previous )
{
Q_UNUSED( current );

View File

@ -67,7 +67,7 @@ class QgsComposerLegendWidget: public QgsComposerItemBaseWidget, private Ui::Qgs
void on_mBoxSpaceSpinBox_valueChanged( double d );
void on_mColumnSpaceSpinBox_valueChanged( double d );
void on_mCheckBoxAutoUpdate_stateChanged( int state );
void on_mMapComboBox_currentIndexChanged( int index );
void composerMapChanged( const QgsComposerItem* item );
void on_mRasterBorderGroupBox_toggled( bool state );
void on_mRasterBorderWidthSpinBox_valueChanged( double d );
@ -92,9 +92,6 @@ class QgsComposerLegendWidget: public QgsComposerItemBaseWidget, private Ui::Qgs
void setCurrentNodeStyleFromAction();
protected:
void showEvent( QShowEvent * event ) override;
private slots:
/** Sets GUI according to state of mLegend*/
void setGuiElements();
@ -105,8 +102,6 @@ class QgsComposerLegendWidget: public QgsComposerItemBaseWidget, private Ui::Qgs
private:
QgsComposerLegendWidget();
void blockAllSignals( bool b );
void refreshMapComboBox();
QgsComposerLegend* mLegend;
};

View File

@ -152,6 +152,11 @@ QgsComposerMapWidget::QgsComposerMapWidget( QgsComposerMap* composerMap )
compositionAtlasToggled( atlas->enabled() );
}
mOverviewFrameMapComboBox->setComposition( composerMap->composition() );
mOverviewFrameMapComboBox->setItemType( QgsComposerItem::ComposerMap );
mOverviewFrameMapComboBox->setExceptedItemList( QList< QgsComposerItem* >() << composerMap );
connect( mOverviewFrameMapComboBox, SIGNAL( itemChanged( const QgsComposerItem* ) ), this, SLOT( overviewMapChanged( const QgsComposerItem* ) ) );
}
//connections for data defined buttons
@ -952,12 +957,6 @@ void QgsComposerMapWidget::on_mDrawCanvasItemsCheckBox_stateChanged( int state )
mComposerMap->endCommand();
}
void QgsComposerMapWidget::showEvent( QShowEvent * event )
{
refreshMapComboBox();
QWidget::showEvent( event );
}
void QgsComposerMapWidget::addPageToToolbox( QWidget* widget, const QString& name )
{
Q_UNUSED( name );
@ -1095,53 +1094,6 @@ void QgsComposerMapWidget::initAnnotationDirectionBox( QComboBox* c, QgsComposer
c->setCurrentIndex( c->findData( dir ) );
}
void QgsComposerMapWidget::refreshMapComboBox()
{
if ( !mComposerMap )
{
return;
}
mOverviewFrameMapComboBox->blockSignals( true );
//save the current entry in case it is still present after refresh
QString saveComboText = mOverviewFrameMapComboBox->currentText();
mOverviewFrameMapComboBox->clear();
mOverviewFrameMapComboBox->addItem( tr( "None" ), -1 );
const QgsComposition* composition = mComposerMap->composition();
if ( !composition )
{
return;
}
QList<const QgsComposerMap*> availableMaps = composition->composerMapItems();
QList<const QgsComposerMap*>::const_iterator mapItemIt = availableMaps.constBegin();
for ( ; mapItemIt != availableMaps.constEnd(); ++mapItemIt )
{
if (( *mapItemIt )->id() != mComposerMap->id() )
{
mOverviewFrameMapComboBox->addItem( tr( "Map %1" ).arg(( *mapItemIt )->id() ), ( *mapItemIt )->id() );
}
}
if ( !saveComboText.isEmpty() )
{
int saveTextIndex = mOverviewFrameMapComboBox->findText( saveComboText );
if ( saveTextIndex == -1 )
{
//entry is no longer present
mOverviewFrameMapComboBox->setCurrentIndex( mOverviewFrameMapComboBox->findText( tr( "None" ) ) );
}
else
{
mOverviewFrameMapComboBox->setCurrentIndex( saveTextIndex );
}
}
mOverviewFrameMapComboBox->blockSignals( false );
}
void QgsComposerMapWidget::atlasLayerChanged( QgsVectorLayer* layer )
{
if ( !layer || layer->wkbType() == QGis::WKBNoGeometry )
@ -2412,9 +2364,7 @@ void QgsComposerMapWidget::setOverviewItems( const QgsComposerMapOverview* overv
mOverviewCheckBox->setChecked( overview->enabled() );
//overview frame
refreshMapComboBox();
int overviewMapFrameId = overview->frameMapId();
mOverviewFrameMapComboBox->setCurrentIndex( mOverviewFrameMapComboBox->findData( overviewMapFrameId ) );
mOverviewFrameMapComboBox->setItem( mComposerMap->composition()->getComposerMapById( overview->frameMapId() ) );
//overview frame blending mode
mOverviewBlendModeComboBox->setBlendMode( overview->blendMode() );
//overview inverted
@ -2508,7 +2458,7 @@ void QgsComposerMapWidget::on_mOverviewCheckBox_toggled( bool state )
mComposerMap->endCommand();
}
void QgsComposerMapWidget::on_mOverviewFrameMapComboBox_currentIndexChanged( const QString& text )
void QgsComposerMapWidget::overviewMapChanged( const QgsComposerItem* item )
{
QgsComposerMapOverview* overview = currentOverview();
if ( !overview )
@ -2516,47 +2466,12 @@ void QgsComposerMapWidget::on_mOverviewFrameMapComboBox_currentIndexChanged( con
return;
}
int id;
if ( text == tr( "None" ) )
{
id = -1;
}
else
{
//get composition
const QgsComposition* composition = mComposerMap->composition();
if ( !composition )
{
return;
}
//extract id
bool conversionOk;
QStringList textSplit = text.split( ' ' );
if ( textSplit.size() < 1 )
{
return;
}
QString idString = textSplit.at( textSplit.size() - 1 );
id = idString.toInt( &conversionOk );
if ( !conversionOk )
{
return;
}
const QgsComposerMap* composerMap = composition->getComposerMapById( id );
if ( !composerMap )
{
return;
}
}
const QgsComposerMap* map = dynamic_cast< const QgsComposerMap* >( item );
if ( !map )
return;
mComposerMap->beginCommand( tr( "Overview map changed" ) );
overview->setFrameMap( id );
overview->setFrameMap( map->id() );
mComposerMap->update();
mComposerMap->endCommand();
}

View File

@ -46,7 +46,7 @@ class QgsComposerMapWidget: public QgsComposerItemBaseWidget, private Ui::QgsCom
void on_mKeepLayerListCheckBox_stateChanged( int state );
void on_mKeepLayerStylesCheckBox_stateChanged( int state );
void on_mDrawCanvasItemsCheckBox_stateChanged( int state );
void on_mOverviewFrameMapComboBox_currentIndexChanged( const QString& text );
void overviewMapChanged( const QgsComposerItem* item );
void on_mOverviewFrameStyleButton_clicked();
void on_mOverviewBlendModeComboBox_currentIndexChanged( int index );
void on_mOverviewInvertCheckbox_toggled( bool state );
@ -145,7 +145,6 @@ class QgsComposerMapWidget: public QgsComposerItemBaseWidget, private Ui::QgsCom
void blockOverviewItemsSignals( bool block );
protected:
void showEvent( QShowEvent * event ) override;
void addPageToToolbox( QWidget * widget, const QString& name );
@ -200,9 +199,6 @@ class QgsComposerMapWidget: public QgsComposerItemBaseWidget, private Ui::QgsCom
void updateGridLineSymbolMarker( const QgsComposerMapGrid* grid );
void updateGridMarkerSymbolMarker( const QgsComposerMapGrid* grid );
/** Updates the map combo box with the current composer map ids*/
void refreshMapComboBox();
/** Enables/disables grid frame related controls*/
void toggleFrameControls( bool frameEnabled, bool frameFillEnabled, bool frameSizeEnabled );

View File

@ -48,6 +48,13 @@ QgsComposerPictureWidget::QgsComposerPictureWidget( QgsComposerPicture* picture
QgsComposerItemWidget* itemPropertiesWidget = new QgsComposerItemWidget( this, picture );
mainLayout->addWidget( itemPropertiesWidget );
if ( mPicture->composition() )
{
mComposerMapComboBox->setComposition( mPicture->composition() );
mComposerMapComboBox->setItemType( QgsComposerItem::ComposerMap );
connect( mComposerMapComboBox, SIGNAL( itemChanged( const QgsComposerItem* ) ), this, SLOT( composerMapChanged( const QgsComposerItem* ) ) );
}
setGuiElementValues();
mPreviewsLoadingLabel->hide();
@ -277,23 +284,18 @@ void QgsComposerPictureWidget::on_mRotationFromComposerMapCheckBox_stateChanged(
}
else
{
int currentItemIndex = mComposerMapComboBox->currentIndex();
if ( currentItemIndex == -1 )
{
return;
}
int composerId = mComposerMapComboBox->itemData( currentItemIndex, Qt::UserRole ).toInt();
mPicture->setRotationMap( composerId );
const QgsComposerMap* map = dynamic_cast< const QgsComposerMap* >( mComposerMapComboBox->currentItem() );
int mapId = map ? map->id() : -1;
mPicture->setRotationMap( mapId );
mPictureRotationSpinBox->setEnabled( false );
mComposerMapComboBox->setEnabled( true );
}
mPicture->endCommand();
}
void QgsComposerPictureWidget::on_mComposerMapComboBox_activated( const QString & text )
void QgsComposerPictureWidget::composerMapChanged( const QgsComposerItem* item )
{
if ( !mPicture || text.isEmpty() || !mPicture->useRotationMap() )
if ( !mPicture )
{
return;
}
@ -305,24 +307,8 @@ void QgsComposerPictureWidget::on_mComposerMapComboBox_activated( const QString
return;
}
//extract id
int id;
bool conversionOk;
QStringList textSplit = text.split( ' ' );
if ( textSplit.size() < 1 )
{
return;
}
QString idString = textSplit.at( textSplit.size() - 1 );
id = idString.toInt( &conversionOk );
if ( !conversionOk )
{
return;
}
const QgsComposerMap* composerMap = composition->getComposerMapById( id );
const QgsComposerMap* composerMap = dynamic_cast< const QgsComposerMap*>( item );
int id = composerMap ? composerMap->id() : -1;
if ( !composerMap )
{
return;
@ -333,45 +319,6 @@ void QgsComposerPictureWidget::on_mComposerMapComboBox_activated( const QString
mPicture->endCommand();
}
void QgsComposerPictureWidget::refreshMapComboBox()
{
mComposerMapComboBox->blockSignals( true );
//save the current entry in case it is still present after refresh
QString saveCurrentComboText = mComposerMapComboBox->currentText();
mComposerMapComboBox->clear();
if ( mPicture )
{
//insert available maps into mMapComboBox
const QgsComposition* composition = mPicture->composition();
if ( composition )
{
QList<const QgsComposerMap*> availableMaps = composition->composerMapItems();
QList<const QgsComposerMap*>::const_iterator mapItemIt = availableMaps.constBegin();
for ( ; mapItemIt != availableMaps.constEnd(); ++mapItemIt )
{
mComposerMapComboBox->addItem( tr( "Map %1" ).arg(( *mapItemIt )->id() ), ( *mapItemIt )->id() );
}
}
}
if ( !saveCurrentComboText.isEmpty() )
{
if ( mComposerMapComboBox->findText( saveCurrentComboText ) == -1 )
{
//the former entry is no longer present. Inform the scalebar about the changed composer map
on_mComposerMapComboBox_activated( mComposerMapComboBox->currentText() );
}
else
{
//the former entry is still present. Make it the current entry again
mComposerMapComboBox->setCurrentIndex( mComposerMapComboBox->findText( saveCurrentComboText ) );
}
}
mComposerMapComboBox->blockSignals( false );
}
void QgsComposerPictureWidget::setPicRotationSpinValue( double r )
{
mPictureRotationSpinBox->blockSignals( true );
@ -397,19 +344,17 @@ void QgsComposerPictureWidget::setGuiElementValues()
mPictureLineEdit->setText( mPicture->picturePath() );
mPictureRotationSpinBox->setValue( mPicture->pictureRotation() );
refreshMapComboBox();
const QgsComposerMap* map = mPicture->composition()->getComposerMapById( mPicture->rotationMap() );
if ( map )
mComposerMapComboBox->setItem( map );
else
mComposerMapComboBox->setCurrentIndex( 0 );
if ( mPicture->useRotationMap() )
{
mRotationFromComposerMapCheckBox->setCheckState( Qt::Checked );
mPictureRotationSpinBox->setEnabled( false );
mComposerMapComboBox->setEnabled( true );
QString mapText = tr( "Map %1" ).arg( mPicture->rotationMap() );
int itemId = mComposerMapComboBox->findText( mapText );
if ( itemId >= 0 )
{
mComposerMapComboBox->setCurrentIndex( itemId );
}
}
else
{
@ -720,12 +665,6 @@ void QgsComposerPictureWidget::on_mOutlineWidthSpinBox_valueChanged( double d )
mPicture->update();
}
void QgsComposerPictureWidget::showEvent( QShowEvent * event )
{
Q_UNUSED( event );
refreshMapComboBox();
}
void QgsComposerPictureWidget::resizeEvent( QResizeEvent * event )
{
Q_UNUSED( event );

View File

@ -45,12 +45,11 @@ class QgsComposerPictureWidget: public QgsComposerItemBaseWidget, private Ui::Qg
void on_mAddDirectoryButton_clicked();
void on_mRemoveDirectoryButton_clicked();
void on_mRotationFromComposerMapCheckBox_stateChanged( int state );
void on_mComposerMapComboBox_activated( const QString & text );
void composerMapChanged( const QgsComposerItem* item );
void on_mResizeModeComboBox_currentIndexChanged( int index );
void on_mAnchorPointComboBox_currentIndexChanged( int index );
protected:
void showEvent( QShowEvent * event ) override;
void resizeEvent( QResizeEvent * event ) override;
QgsComposerObject::DataDefinedProperty ddPropertyForWidget( QgsDataDefinedButton *widget ) override;
@ -86,8 +85,6 @@ class QgsComposerPictureWidget: public QgsComposerItemBaseWidget, private Ui::Qg
bool testSvgFile( const QString& filename ) const;
/** Tests if a file is a valid pixel format*/
bool testImageFile( const QString& filename ) const;
/** Updates the map combo box with the current composer map ids*/
void refreshMapComboBox();
//! Renders an svg file to a QIcon, correctly handling any SVG parameters present in the file
QIcon svgToIcon( const QString& filePath ) const;

View File

@ -79,6 +79,15 @@ QgsComposerScaleBarWidget::QgsComposerScaleBarWidget( QgsComposerScaleBar* scale
mStrokeColorButton->setNoColorString( tr( "Transparent line" ) );
mStrokeColorButton->setShowNoColor( true );
QgsComposition* scaleBarComposition = mComposerScaleBar->composition();
if ( scaleBarComposition )
{
mMapItemComboBox->setComposition( scaleBarComposition );
mMapItemComboBox->setItemType( QgsComposerItem::ComposerMap );
}
connect( mMapItemComboBox, SIGNAL( itemChanged( const QgsComposerItem* ) ), this, SLOT( composerMapChanged( const QgsComposerItem* ) ) );
blockMemberSignals( false );
setGuiElements(); //set the GUI elements to the state of scaleBar
}
@ -88,97 +97,6 @@ QgsComposerScaleBarWidget::~QgsComposerScaleBarWidget()
}
void QgsComposerScaleBarWidget::refreshMapComboBox()
{
//save the current entry in case it is still present after refresh
QString saveCurrentComboText = mMapComboBox->currentText();
mMapComboBox->clear();
if ( mComposerScaleBar )
{
//insert available maps into mMapComboBox
const QgsComposition* scaleBarComposition = mComposerScaleBar->composition();
if ( scaleBarComposition )
{
QList<const QgsComposerMap*> availableMaps = scaleBarComposition->composerMapItems();
QList<const QgsComposerMap*>::const_iterator mapItemIt = availableMaps.constBegin();
for ( ; mapItemIt != availableMaps.constEnd(); ++mapItemIt )
{
mMapComboBox->addItem( tr( "Map %1" ).arg(( *mapItemIt )->id() ) );
}
}
if ( saveCurrentComboText.isEmpty() && mComposerScaleBar->composerMap() )
{
//combo box was not initialized before
mMapComboBox->setCurrentIndex( mMapComboBox->findText( tr( "Map %1" ).arg( mComposerScaleBar->composerMap()->id() ) ) );
}
}
if ( mMapComboBox->findText( saveCurrentComboText ) == -1 )
{
//the former entry is no longer present. Inform the scalebar about the changed composer map
on_mMapComboBox_activated( mMapComboBox->currentText() );
}
else
{
//the former entry is still present. Make it the current entry again
mMapComboBox->setCurrentIndex( mMapComboBox->findText( saveCurrentComboText ) );
}
}
void QgsComposerScaleBarWidget::showEvent( QShowEvent * event )
{
refreshMapComboBox();
QWidget::showEvent( event );
}
void QgsComposerScaleBarWidget::on_mMapComboBox_activated( const QString& text )
{
if ( !mComposerScaleBar || text.isEmpty() )
{
return;
}
const QgsComposition* comp = mComposerScaleBar->composition();
if ( !comp )
{
return;
}
//extract id
int id;
bool conversionOk;
QStringList textSplit = text.split( ' ' );
if ( textSplit.size() < 1 )
{
return;
}
QString idString = textSplit.at( textSplit.size() - 1 );
id = idString.toInt( &conversionOk );
if ( !conversionOk )
{
return;
}
//get QgsComposerMap object from composition
const QgsComposerMap* composerMap = comp->getComposerMapById( id );
if ( !composerMap )
{
return;
}
//set it to scale bar
mComposerScaleBar->beginCommand( tr( "Scalebar map changed" ) );
disconnectUpdateSignal();
mComposerScaleBar->setComposerMap( composerMap );
mComposerScaleBar->update();
connectUpdateSignal();
mComposerScaleBar->endCommand();
}
void QgsComposerScaleBarWidget::setGuiElements()
{
if ( !mComposerScaleBar )
@ -204,15 +122,7 @@ void QgsComposerScaleBarWidget::setGuiElements()
mStrokeColorButton->setColor( mComposerScaleBar->pen().color() );
//map combo box
if ( mComposerScaleBar->composerMap() )
{
QString mapText = tr( "Map %1" ).arg( mComposerScaleBar->composerMap()->id() );
int itemId = mMapComboBox->findText( mapText );
if ( itemId >= 0 )
{
mMapComboBox->setCurrentIndex( itemId );
}
}
mMapItemComboBox->setItem( mComposerScaleBar->composerMap() );
//style...
QString style = mComposerScaleBar->style();
@ -634,7 +544,6 @@ void QgsComposerScaleBarWidget::blockMemberSignals( bool block )
mStyleComboBox->blockSignals( block );
mUnitLabelLineEdit->blockSignals( block );
mMapUnitsPerBarUnitSpinBox->blockSignals( block );
mMapComboBox->blockSignals( block );
mHeightSpinBox->blockSignals( block );
mLineWidthSpinBox->blockSignals( block );
mLabelBarSpaceSpinBox->blockSignals( block );
@ -648,6 +557,7 @@ void QgsComposerScaleBarWidget::blockMemberSignals( bool block )
mFillColor2Button->blockSignals( block );
mStrokeColorButton->blockSignals( block );
mSegmentSizeRadioGroup.blockSignals( block );
mMapItemComboBox->blockSignals( block );
}
void QgsComposerScaleBarWidget::connectUpdateSignal()
@ -720,6 +630,23 @@ void QgsComposerScaleBarWidget::segmentSizeRadioChanged( QAbstractButton* radio
mComposerScaleBar->endCommand();
}
void QgsComposerScaleBarWidget::composerMapChanged( const QgsComposerItem* item )
{
const QgsComposerMap* composerMap = dynamic_cast< const QgsComposerMap* >( item );
if ( !composerMap )
{
return;
}
//set it to scale bar
mComposerScaleBar->beginCommand( tr( "Scalebar map changed" ) );
disconnectUpdateSignal();
mComposerScaleBar->setComposerMap( composerMap );
mComposerScaleBar->update();
connectUpdateSignal();
mComposerScaleBar->endCommand();
}
void QgsComposerScaleBarWidget::on_mMinWidthSpinBox_valueChanged( int )
{
if ( !mComposerScaleBar )

View File

@ -34,7 +34,7 @@ class QgsComposerScaleBarWidget: public QgsComposerItemBaseWidget, private Ui::Q
~QgsComposerScaleBarWidget();
public slots:
void on_mMapComboBox_activated( const QString& text );
void on_mHeightSpinBox_valueChanged( int i );
void on_mLineWidthSpinBox_valueChanged( double d );
void on_mSegmentSizeSpinBox_valueChanged( double d );
@ -60,15 +60,12 @@ class QgsComposerScaleBarWidget: public QgsComposerItemBaseWidget, private Ui::Q
private slots:
void setGuiElements();
void segmentSizeRadioChanged( QAbstractButton*radio );
protected:
void showEvent( QShowEvent * event ) override;
void composerMapChanged( const QgsComposerItem* item );
private:
QgsComposerScaleBar* mComposerScaleBar;
QButtonGroup mSegmentSizeRadioGroup;
void refreshMapComboBox();
/** Enables/disables the signals of the input gui elements*/
void blockMemberSignals( bool enable );

View File

@ -81,26 +81,9 @@ QgsCompositionWidget::QgsCompositionWidget( QWidget* parent, QgsComposition* c )
mWorldFileMapComboBox->setEnabled( mComposition->generateWorldFile() );
// populate the map list
mWorldFileMapComboBox->clear();
QList<const QgsComposerMap*> availableMaps = mComposition->composerMapItems();
QList<const QgsComposerMap*>::const_iterator mapItemIt = availableMaps.constBegin();
for ( ; mapItemIt != availableMaps.constEnd(); ++mapItemIt )
{
mWorldFileMapComboBox->addItem( tr( "Map %1" ).arg(( *mapItemIt )->id() ), ( *mapItemIt )->id() );
}
if ( mComposition->worldFileMap() )
{
int idx = mWorldFileMapComboBox->findData( mComposition->worldFileMap()->id() );
if ( idx != -1 )
{
mWorldFileMapComboBox->setCurrentIndex( idx );
}
}
// Connect to addition / removal of maps
connect( mComposition, SIGNAL( composerMapAdded( QgsComposerMap* ) ), this, SLOT( onComposerMapAdded( QgsComposerMap* ) ) );
connect( mComposition, SIGNAL( itemRemoved( QgsComposerItem* ) ), this, SLOT( onItemRemoved( QgsComposerItem* ) ) );
mWorldFileMapComboBox->setComposition( mComposition );
mWorldFileMapComboBox->setItemType( QgsComposerItem::ComposerMap );
mWorldFileMapComboBox->setItem( mComposition->worldFileMap() );
mSnapToleranceSpinBox->setValue( mComposition->snapTolerance() );
@ -140,6 +123,8 @@ QgsCompositionWidget::QgsCompositionWidget( QWidget* parent, QgsComposition* c )
connect( mPaperOrientationDDBtn, SIGNAL( dataDefinedActivated( bool ) ), this, SLOT( updateDataDefinedProperty() ) );
connect( mPaperOrientationDDBtn, SIGNAL( dataDefinedActivated( bool ) ), mPaperOrientationComboBox, SLOT( setDisabled( bool ) ) );
connect( mWorldFileMapComboBox, SIGNAL( itemChanged( const QgsComposerItem* ) ), this, SLOT( worldFileMapChanged( const QgsComposerItem* ) ) );
//initialize data defined buttons
populateDataDefinedButtons();
@ -676,58 +661,15 @@ void QgsCompositionWidget::on_mGenerateWorldFileCheckBox_toggled( bool state )
mWorldFileMapComboBox->setEnabled( state );
}
void QgsCompositionWidget::onComposerMapAdded( QgsComposerMap* map )
void QgsCompositionWidget::worldFileMapChanged( const QgsComposerItem* item )
{
if ( !mComposition )
{
return;
}
mWorldFileMapComboBox->addItem( tr( "Map %1" ).arg( map->id() ), map->id() );
if ( mWorldFileMapComboBox->count() == 1 )
{
mComposition->setWorldFileMap( map );
}
}
void QgsCompositionWidget::onItemRemoved( QgsComposerItem* item )
{
if ( !mComposition )
{
return;
}
QgsComposerMap* map = dynamic_cast<QgsComposerMap*>( item );
if ( map )
{
int idx = mWorldFileMapComboBox->findData( map->id() );
if ( idx != -1 )
{
mWorldFileMapComboBox->removeItem( idx );
}
}
if ( mWorldFileMapComboBox->count() == 0 )
{
mComposition->setWorldFileMap( nullptr );
}
}
void QgsCompositionWidget::on_mWorldFileMapComboBox_currentIndexChanged( int index )
{
if ( !mComposition )
{
return;
}
if ( index == -1 )
{
mComposition->setWorldFileMap( nullptr );
}
else
{
int mapId = mWorldFileMapComboBox->itemData( index ).toInt();
QgsComposerMap* map = const_cast< QgsComposerMap* >( mComposition->getComposerMapById( mapId ) );
mComposition->setWorldFileMap( map );
}
const QgsComposerMap* map = dynamic_cast< const QgsComposerMap* >( item );
mComposition->setWorldFileMap( const_cast< QgsComposerMap* >( map ) );
}
void QgsCompositionWidget::on_mGridResolutionSpinBox_valueChanged( double d )

View File

@ -54,7 +54,7 @@ class QgsCompositionWidget: public QWidget, private Ui::QgsCompositionWidgetBase
void on_mResolutionSpinBox_valueChanged( const int value );
void on_mPrintAsRasterCheckBox_toggled( bool state );
void on_mGenerateWorldFileCheckBox_toggled( bool state );
void on_mWorldFileMapComboBox_currentIndexChanged( int index );
void worldFileMapChanged( const QgsComposerItem* );
void on_mGridResolutionSpinBox_valueChanged( double d );
void on_mOffsetXSpinBox_valueChanged( double d );
@ -73,10 +73,6 @@ class QgsCompositionWidget: public QWidget, private Ui::QgsCompositionWidgetBase
void pageOrientationChanged( const QString& orientation );
private slots:
/* when a new map is added */
void onComposerMapAdded( QgsComposerMap* );
/* when a map is deleted */
void onItemRemoved( QgsComposerItem* );
/** Must be called when a data defined button changes*/
void updateDataDefinedProperty();

View File

@ -18,7 +18,6 @@
#include "qgsapplication.h"
#include "qgscomposermodel.h"
#include "qgscomposition.h"
#include "qgscomposeritem.h"
#include "qgspaperitem.h"
#include "qgslogger.h"
#include <QApplication>
@ -158,6 +157,9 @@ QVariant QgsComposerModel::data( const QModelIndex &index, int role ) const
case Qt::UserRole:
//store item uuid in userrole so we can later get the QModelIndex for a specific item
return item->uuid();
case Qt::UserRole+1:
//user role stores reference in column object
return qVariantFromValue( qobject_cast<QObject *>( item ) );
case Qt::TextAlignmentRole:
return Qt::AlignLeft & Qt::AlignVCenter;
@ -208,19 +210,16 @@ bool QgsComposerModel::setData( const QModelIndex & index, const QVariant & valu
case Visibility:
//first column is item visibility
item->setVisibility( value.toBool() );
emit dataChanged( index, index );
return true;
case LockStatus:
//second column is item lock state
item->setPositionLock( value.toBool() );
emit dataChanged( index, index );
return true;
case ItemId:
//last column is item id
item->setId( value.toString() );
emit dataChanged( index, index );
return true;
}
@ -945,3 +944,82 @@ void QgsComposerModel::setSelected( const QModelIndex &index )
mComposition->setSelectedItem( item );
}
//
// QgsComposerFilteredModel
//
QgsComposerProxyModel::QgsComposerProxyModel( QgsComposition *composition, QObject *parent )
: QSortFilterProxyModel( parent )
, mComposition( composition )
, mItemTypeFilter( QgsComposerItem::ComposerItem )
{
if ( mComposition )
setSourceModel( mComposition->itemsModel() );
// TODO doesn't seem to work correctly - not updated when item changes
setDynamicSortFilter( true );
setSortLocaleAware( true );
sort( QgsComposerModel::ItemId );
}
bool QgsComposerProxyModel::lessThan( const QModelIndex &left, const QModelIndex &right ) const
{
//sort by item id
const QgsComposerItem* item1 = itemFromSourceIndex( left );
const QgsComposerItem* item2 = itemFromSourceIndex( right );
if ( !item1 )
return false;
if ( !item2 )
return true;
return QString::localeAwareCompare( item1->displayName(), item2->displayName() ) < 0;
}
QgsComposerItem* QgsComposerProxyModel::itemFromSourceIndex( const QModelIndex &sourceIndex ) const
{
if ( !mComposition )
return nullptr;
//get column corresponding to an index from the source model
QVariant itemAsVariant = sourceModel()->data( sourceIndex, Qt::UserRole + 1 );
return qobject_cast<QgsComposerItem *>( itemAsVariant.value<QObject *>() );
}
void QgsComposerProxyModel::setFilterType( QgsComposerItem::ItemType itemType )
{
mItemTypeFilter = itemType;
invalidate();
}
void QgsComposerProxyModel::setExceptedItemList( const QList< QgsComposerItem*>& exceptList )
{
if ( mExceptedList == exceptList )
return;
mExceptedList = exceptList;
invalidateFilter();
}
bool QgsComposerProxyModel::filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const
{
//get QgsComposerItem corresponding to row
QModelIndex index = sourceModel()->index( source_row, 0, source_parent );
QgsComposerItem* item = itemFromSourceIndex( index );
if ( !item )
return false;
// specific exceptions
if ( mExceptedList.contains( item ) )
return false;
// filter by type
if ( mItemTypeFilter != QgsComposerItem::ComposerItem && item->type() != mItemTypeFilter )
return false;
return true;
}

View File

@ -19,11 +19,12 @@
#define QGSCOMPOSERMODEL_H
#include <QAbstractItemModel>
#include <QSortFilterProxyModel>
#include <QStringList>
#include <QSet>
#include "qgscomposeritem.h"
class QgsComposition;
class QgsComposerItem;
class QGraphicsItem;
/**
@ -50,6 +51,14 @@ class CORE_EXPORT QgsComposerModel: public QAbstractItemModel
public:
//! Columns returned by the model
enum Columns
{
Visibility = 0, /*!< Item visibility check box */
LockStatus, /*!< Item lock status check box */
ItemId, /*!< Item ID */
};
/** Constructor
* @param composition composition to attach to
* @param parent parent object
@ -229,6 +238,13 @@ class CORE_EXPORT QgsComposerModel: public 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
@ -247,13 +263,6 @@ class CORE_EXPORT QgsComposerModel: public QAbstractItemModel
private:
enum Columns
{
Visibility = 0,
LockStatus,
ItemId
};
/** Parent composition*/
QgsComposition* mComposition;
@ -263,13 +272,6 @@ class CORE_EXPORT QgsComposerModel: public QAbstractItemModel
*/
QgsComposerItem* itemFromIndex( const QModelIndex &index ) const;
/** 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 );
/** Rebuilds the list of all composer items which are present in the composition. This is
* called when the stacking of order changes or when items are removed/restored to the
* composition. Unlike rebuildSceneItemList, this method clears the existing scene item
@ -289,4 +291,71 @@ class CORE_EXPORT QgsComposerModel: public QAbstractItemModel
friend class TestQgsComposerModel;
};
/**
* /class QgsComposerProxyModel
* /ingroup core
* /brief Allows for filtering a QgsComposerModel by item type.
* /note added in 2.16
*/
class CORE_EXPORT QgsComposerProxyModel: public QSortFilterProxyModel
{
Q_OBJECT
public:
/** Constructor for QgsComposerProxyModel.
* @param composition composition to attach model to
* @param parent optional parent
*/
QgsComposerProxyModel( QgsComposition* composition, QObject *parent = nullptr );
/** Returns the current item type filter, or QgsComposerItem::ComposerItem if no
* item type filter is set.
* @see setFilterType()
*/
QgsComposerItem::ItemType filterType() const { return mItemTypeFilter; }
/** 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 { return mExceptedList; }
/** Returns the QgsComposerModel used in this proxy model.
*/
QgsComposerModel* sourceLayerModel() const { return static_cast< QgsComposerModel* >( sourceModel() ); }
/** 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 override;
bool lessThan( const QModelIndex &left, const QModelIndex &right ) const override;
private:
QgsComposition* mComposition;
QgsComposerItem::ItemType mItemTypeFilter;
QList< QgsComposerItem* > mExceptedList;
};
#endif //QGSCOMPOSERMODEL

View File

@ -174,6 +174,7 @@ SET(QGIS_GUI_SRCS
qgscolorschemelist.cpp
qgscolorswatchgrid.cpp
qgscolorwidgets.cpp
qgscomposeritemcombobox.cpp
qgscomposerruler.cpp
qgscomposerview.cpp
qgscredentialdialog.cpp
@ -317,6 +318,7 @@ SET(QGIS_GUI_MOC_HDRS
qgscolorschemelist.h
qgscolorswatchgrid.h
qgscolorwidgets.h
qgscomposeritemcombobox.h
qgscomposerruler.h
qgscomposerview.h
qgscredentialdialog.h

View File

@ -0,0 +1,120 @@
/***************************************************************************
qgscomposeritemcombobox.cpp
--------------------------------------
Date : August 2014
Copyright : (C) 2014 Nyall Dawson
Email : nyall dot dawson at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgscomposeritemcombobox.h"
#include "qgscomposermodel.h"
QgsComposerItemComboBox::QgsComposerItemComboBox( QWidget *parent, QgsComposition* composition )
: QComboBox( parent )
, mProxyModel( nullptr )
{
setComposition( composition );
setModelColumn( QgsComposerModel::ItemId );
connect( this, SIGNAL( activated( int ) ), this, SLOT( indexChanged( int ) ) );
connect( mProxyModel, SIGNAL( rowsInserted( QModelIndex, int, int ) ), this, SLOT( rowsChanged() ) );
connect( mProxyModel, SIGNAL( rowsRemoved( QModelIndex, int, int ) ), this, SLOT( rowsChanged() ) );
}
void QgsComposerItemComboBox::setComposition( QgsComposition *composition )
{
delete mProxyModel;
mProxyModel = new QgsComposerProxyModel( composition, this );
connect( mProxyModel, SIGNAL( rowsInserted( QModelIndex, int, int ) ), this, SLOT( rowsChanged() ) );
connect( mProxyModel, SIGNAL( rowsRemoved( QModelIndex, int, int ) ), this, SLOT( rowsChanged() ) );
setModel( mProxyModel );
setModelColumn( QgsComposerModel::ItemId );
mProxyModel->sort( 0, Qt::AscendingOrder );
}
void QgsComposerItemComboBox::setItem( const QgsComposerItem* item )
{
if ( !mProxyModel->sourceLayerModel() )
return;
QModelIndex idx = mProxyModel->sourceLayerModel()->indexForItem( const_cast< QgsComposerItem* >( item ) );
if ( idx.isValid() )
{
QModelIndex proxyIdx = mProxyModel->mapFromSource( idx );
if ( proxyIdx.isValid() )
{
setCurrentIndex( proxyIdx.row() );
emit itemChanged( currentItem() );
return;
}
}
setCurrentIndex( -1 );
emit itemChanged( currentItem() );
}
QgsComposerItem* QgsComposerItemComboBox::currentItem() const
{
return item( currentIndex() );
}
void QgsComposerItemComboBox::indexChanged( int i )
{
Q_UNUSED( i );
emit itemChanged( currentItem() );
}
void QgsComposerItemComboBox::rowsChanged()
{
if ( count() == 1 )
{
//currently selected item has changed
emit itemChanged( currentItem() );
}
else if ( count() == 0 )
{
emit itemChanged( nullptr );
}
}
void QgsComposerItemComboBox::setItemType( QgsComposerItem::ItemType itemType )
{
mProxyModel->setFilterType( itemType );
}
QgsComposerItem::ItemType QgsComposerItemComboBox::itemType() const
{
return mProxyModel->filterType();
}
void QgsComposerItemComboBox::setExceptedItemList( const QList< QgsComposerItem*>& exceptList )
{
mProxyModel->setExceptedItemList( exceptList );
}
QList< QgsComposerItem*> QgsComposerItemComboBox::exceptedItemList() const
{
return mProxyModel->exceptedItemList();
}
QgsComposerItem* QgsComposerItemComboBox::item( int index ) const
{
const QModelIndex proxyIndex = mProxyModel->index( index, 0 );
if ( !proxyIndex.isValid() )
{
return nullptr;
}
QModelIndex sourceIndex = mProxyModel->mapToSource( proxyIndex );
if ( !sourceIndex.isValid() )
{
return nullptr;
}
return mProxyModel->itemFromSourceIndex( sourceIndex );
}

View File

@ -0,0 +1,102 @@
/***************************************************************************
qgscomposeritemcombobox.h
--------------------------------------
Date : August 2014
Copyright : (C) 2014 Nyall Dawson
Email : nyall dot dawson at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSCOMPOSERITEMCOMBOBOX_H
#define QGSCOMPOSERITEMCOMBOBOX_H
#include <QComboBox>
#include "qgscomposeritem.h"
class QgsComposerProxyModel;
/**
* /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 GUI_EXPORT QgsComposerItemComboBox : public QComboBox
{
Q_OBJECT
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 = 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()
*/
QgsComposerItem* item( int index ) const;
/** Returns the item currently selected in the combo box.
*/
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 );
private slots:
void indexChanged( int i );
void rowsChanged();
private:
QgsComposerProxyModel* mProxyModel;
};
#endif // QGSCOMPOSERITEMCOMBOBOX_H

View File

@ -54,9 +54,9 @@
<property name="geometry">
<rect>
<x>0</x>
<y>-499</y>
<width>392</width>
<height>1291</height>
<y>0</y>
<width>391</width>
<height>1102</height>
</rect>
</property>
<layout class="QVBoxLayout" name="mainLayout">
@ -198,7 +198,7 @@
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="mComposerMapComboBox"/>
<widget class="QgsComposerItemComboBox" name="mComposerMapComboBox"/>
</item>
<item row="4" column="0" colspan="2">
<widget class="QCheckBox" name="mIntersectAtlasCheckBox">
@ -790,6 +790,11 @@
<extends>QSpinBox</extends>
<header>qgsspinbox.h</header>
</customwidget>
<customwidget>
<class>QgsComposerItemComboBox</class>
<extends>QComboBox</extends>
<header>qgscomposeritemcombobox.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>scrollArea</tabstop>

View File

@ -64,8 +64,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>375</width>
<height>1478</height>
<width>374</width>
<height>1293</height>
</rect>
</property>
<layout class="QVBoxLayout" name="mainLayout">
@ -111,7 +111,7 @@
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="mMapComboBox"/>
<widget class="QgsComposerItemComboBox" name="mMapComboBox"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label">
@ -992,7 +992,7 @@
<customwidget>
<class>QgsCollapsibleGroupBoxBasic</class>
<extends>QGroupBox</extends>
<header location="global">qgscollapsiblegroupbox.h</header>
<header>qgscollapsiblegroupbox.h</header>
<container>1</container>
</customwidget>
<customwidget>
@ -1011,6 +1011,11 @@
<extends>QSpinBox</extends>
<header>qgsspinbox.h</header>
</customwidget>
<customwidget>
<class>QgsComposerItemComboBox</class>
<extends>QComboBox</extends>
<header>qgscomposeritemcombobox.h</header>
</customwidget>
<customwidget>
<class>QgsLayerTreeView</class>
<extends>QTreeView</extends>

View File

@ -23,7 +23,16 @@
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
@ -54,9 +63,9 @@
<property name="geometry">
<rect>
<x>0</x>
<y>-1446</y>
<width>444</width>
<height>2493</height>
<y>-1044</y>
<width>438</width>
<height>2111</height>
</rect>
</property>
<property name="sizePolicy">
@ -1350,7 +1359,7 @@
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="mOverviewFrameMapComboBox"/>
<widget class="QgsComposerItemComboBox" name="mOverviewFrameMapComboBox"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="mOverviewFrameStyleLabel">
@ -1436,6 +1445,11 @@
<extends>QComboBox</extends>
<header>qgsblendmodecombobox.h</header>
</customwidget>
<customwidget>
<class>QgsComposerItemComboBox</class>
<extends>QComboBox</extends>
<header>qgscomposeritemcombobox.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>scrollArea</tabstop>

View File

@ -60,9 +60,9 @@
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>314</width>
<height>805</height>
<y>-166</y>
<width>313</width>
<height>719</height>
</rect>
</property>
<layout class="QVBoxLayout" name="mainLayout">
@ -471,7 +471,7 @@
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="mComposerMapComboBox"/>
<widget class="QgsComposerItemComboBox" name="mComposerMapComboBox"/>
</item>
<item row="0" column="0" colspan="2">
<widget class="QgsDoubleSpinBox" name="mPictureRotationSpinBox">
@ -501,9 +501,10 @@
<container>1</container>
</customwidget>
<customwidget>
<class>QgsDataDefinedButton</class>
<class>QgsColorButtonV2</class>
<extends>QToolButton</extends>
<header>qgsdatadefinedbutton.h</header>
<header>qgscolorbuttonv2.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsDoubleSpinBox</class>
@ -511,10 +512,14 @@
<header>qgsdoublespinbox.h</header>
</customwidget>
<customwidget>
<class>QgsColorButtonV2</class>
<class>QgsDataDefinedButton</class>
<extends>QToolButton</extends>
<header>qgscolorbuttonv2.h</header>
<container>1</container>
<header>qgsdatadefinedbutton.h</header>
</customwidget>
<customwidget>
<class>QgsComposerItemComboBox</class>
<extends>QComboBox</extends>
<header>qgscomposeritemcombobox.h</header>
</customwidget>
</customwidgets>
<tabstops>

View File

@ -61,8 +61,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>438</width>
<height>914</height>
<width>437</width>
<height>768</height>
</rect>
</property>
<layout class="QVBoxLayout" name="mainLayout">
@ -80,7 +80,23 @@
<property name="collapsed" stdset="0">
<bool>false</bool>
</property>
<layout class="QGridLayout" name="gridLayout" columnstretch="0,1">
<layout class="QGridLayout" name="gridLayout" columnstretch="0,1,0">
<item row="0" column="1" colspan="2">
<widget class="QgsComposerItemComboBox" name="mMapItemComboBox"/>
</item>
<item row="1" column="1" colspan="2">
<widget class="QComboBox" name="mStyleComboBox"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="mStyleLabel">
<property name="text">
<string>St&amp;yle</string>
</property>
<property name="buddy">
<cstring>mStyleComboBox</cstring>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="mMapLabel">
<property name="sizePolicy">
@ -96,36 +112,10 @@
<bool>true</bool>
</property>
<property name="buddy">
<cstring>mMapComboBox</cstring>
<cstring>mMapItemComboBox</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="mMapComboBox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="mStyleLabel">
<property name="text">
<string>St&amp;yle</string>
</property>
<property name="buddy">
<cstring>mStyleComboBox</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="mStyleComboBox"/>
</item>
</layout>
</widget>
</item>
@ -706,11 +696,16 @@
<header location="global">qgscollapsiblegroupbox.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsComposerItemComboBox</class>
<extends>QComboBox</extends>
<header>qgscomposeritemcombobox.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>scrollArea</tabstop>
<tabstop>groupBox</tabstop>
<tabstop>mMapComboBox</tabstop>
<tabstop>mMapItemComboBox</tabstop>
<tabstop>mStyleComboBox</tabstop>
<tabstop>mGroupBoxUnits</tabstop>
<tabstop>mUnitsComboBox</tabstop>

View File

@ -59,9 +59,9 @@
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>327</width>
<height>1085</height>
<y>-445</y>
<width>326</width>
<height>949</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
@ -462,7 +462,7 @@
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="mWorldFileMapComboBox">
<widget class="QgsComposerItemComboBox" name="mWorldFileMapComboBox">
<property name="enabled">
<bool>false</bool>
</property>
@ -648,22 +648,11 @@
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>QgsCollapsibleGroupBox</class>
<class>QgsCollapsibleGroupBoxBasic</class>
<extends>QGroupBox</extends>
<header>qgscollapsiblegroupbox.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsVariableEditorWidget</class>
<extends>QWidget</extends>
<header location="global">qgsvariableeditorwidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsDataDefinedButton</class>
<extends>QToolButton</extends>
<header>qgsdatadefinedbutton.h</header>
</customwidget>
<customwidget>
<class>QgsDoubleSpinBox</class>
<extends>QDoubleSpinBox</extends>
@ -675,9 +664,25 @@
<header>qgsspinbox.h</header>
</customwidget>
<customwidget>
<class>QgsCollapsibleGroupBoxBasic</class>
<class>QgsComposerItemComboBox</class>
<extends>QComboBox</extends>
<header>qgscomposeritemcombobox.h</header>
</customwidget>
<customwidget>
<class>QgsDataDefinedButton</class>
<extends>QToolButton</extends>
<header>qgsdatadefinedbutton.h</header>
</customwidget>
<customwidget>
<class>QgsCollapsibleGroupBox</class>
<extends>QGroupBox</extends>
<header location="global">qgscollapsiblegroupbox.h</header>
<header>qgscollapsiblegroupbox.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsVariableEditorWidget</class>
<extends>QWidget</extends>
<header location="global">qgsvariableeditorwidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>