Skip to content
Permalink
Browse files
Only create composer item config widgets on demand
Instead of creating them for all items when composer window
is opened, instead just create and destroy them when
required. None are too heavy to have a noticable delay
when selecting items, but in contrast keeping them around
forever is wasteful on memory.

Also clean up a lot of duplicate composer/composition
code and remove unnecessary signals from api (use a single
itemAdded signal instead of multiple signals for every
item type)
  • Loading branch information
nyalldawson committed Mar 21, 2017
1 parent dbf0160 commit 885269ee789dba7e36c9489ce9a4462be210332e
@@ -728,6 +728,10 @@ were removed. Use setSnapTolerance() and snapTolerance() instead.
- dataDefinedProperty() and setDataDefinedProperty() now use the QgsProperty framework instead
of QgsDataDefined objects.
- mapSettings() was removed. Use QgsComposerMap::mapSettings() instead.
- The composerArrowAdded, composerPolygonAdded, composerPolylineAdded, composerHtmlFrameAdded, composerItemGroupAdded,
composerLabelAdded, composerMapAdded, composerScaleBarAdded, composerLegendAdded, composerPictureAdded,
composerShapeAdded, and composerTableFrameAdded were removed. Use the general itemAdded signal instead to catch
all these item added events.


QgsCoordinateReferenceSystem {#qgis_api_break_3_0_QgsCoordinateReferenceSystem}
@@ -659,37 +659,10 @@ class QgsComposition : QGraphicsScene, QgsExpressionContextGenerator
void paperSizeChanged();
void nPagesChanged();
void printResolutionChanged();

/** Is emitted when selected item changed. If 0, no item is selected*/
void selectedItemChanged( QgsComposerItem* selected );
/** Is emitted when new composer arrow has been added to the view*/
void composerArrowAdded( QgsComposerArrow* arrow );
/** Is emitted when new composer polygon has been added to the view*/
void composerPolygonAdded( QgsComposerPolygon* polygon );
/** Is emitted when new composer polyline has been added to the view*/
void composerPolylineAdded( QgsComposerPolyline* polyline );
/** Is emitted when a new composer html has been added to the view*/
void composerHtmlFrameAdded( QgsComposerHtml* html, QgsComposerFrame* frame );
/** Is emitted when a new item group has been added to the view*/
void composerItemGroupAdded( QgsComposerItemGroup* group );
/** Is emitted when new composer label has been added to the view*/
void composerLabelAdded( QgsComposerLabel* label );
/** Is emitted when new composer map has been added to the view*/
void composerMapAdded( QgsComposerMap* map );
/** Is emitted when new composer scale bar has been added*/
void composerScaleBarAdded( QgsComposerScaleBar* scalebar );
/** Is emitted when a new composer legend has been added*/
void composerLegendAdded( QgsComposerLegend* legend );
/** Is emitted when a new composer picture has been added*/
void composerPictureAdded( QgsComposerPicture* picture );
/** Is emitted when a new composer shape has been added*/
void composerShapeAdded( QgsComposerShape* shape );
/** Is emitted when a new composer table frame has been added to the view*/
void composerTableFrameAdded( QgsComposerAttributeTableV2* table, QgsComposerFrame* frame );
/** Is emitted when a composer item has been removed from the scene*/
void itemRemoved( QgsComposerItem* );

/** Is emitted when item in the composition must be refreshed*/
void selectedItemChanged( QgsComposerItem *selected );
void itemAdded( QgsComposerItem *item );
void composerItemGroupAdded( QgsComposerItemGroup *group );
void itemRemoved( QgsComposerItem * );
void refreshItemsTriggered();

/** Is emitted when the composition has an updated status bar message for the composer window*/
@@ -673,7 +673,6 @@ QgsComposer::QgsComposer( QgsComposition *composition )

QgsComposer::~QgsComposer()
{
deleteItemWidgets();
delete mPrinter;
}

@@ -774,17 +773,7 @@ void QgsComposer::connectCompositionSlots()

connect( mComposition, &QgsComposition::nameChanged, this, &QgsComposer::setWindowTitle );
connect( mComposition, &QgsComposition::selectedItemChanged, this, &QgsComposer::showItemOptions );
connect( mComposition, &QgsComposition::composerArrowAdded, this, &QgsComposer::addComposerArrow );
connect( mComposition, &QgsComposition::composerPolygonAdded, this, &QgsComposer::addComposerPolygon );
connect( mComposition, &QgsComposition::composerPolylineAdded, this, &QgsComposer::addComposerPolyline );
connect( mComposition, &QgsComposition::composerHtmlFrameAdded, this, &QgsComposer::addComposerHtmlFrame );
connect( mComposition, &QgsComposition::composerLabelAdded, this, &QgsComposer::addComposerLabel );
connect( mComposition, &QgsComposition::composerMapAdded, this, &QgsComposer::addComposerMap );
connect( mComposition, &QgsComposition::composerScaleBarAdded, this, &QgsComposer::addComposerScaleBar );
connect( mComposition, &QgsComposition::composerLegendAdded, this, &QgsComposer::addComposerLegend );
connect( mComposition, &QgsComposition::composerPictureAdded, this, &QgsComposer::addComposerPicture );
connect( mComposition, &QgsComposition::composerShapeAdded, this, &QgsComposer::addComposerShape );
connect( mComposition, &QgsComposition::composerTableFrameAdded, this, &QgsComposer::addComposerTableV2 );
connect( mComposition, &QgsComposition::itemAdded, this, &QgsComposer::compositionItemAdded );
connect( mComposition, &QgsComposition::itemRemoved, this, &QgsComposer::deleteItem );
connect( mComposition, &QgsComposition::paperSizeChanged, this, [ = ]
{
@@ -847,6 +836,7 @@ bool QgsComposer::loadFromTemplate( const QDomDocument &templateDoc, bool clearE

setUpdatesEnabled( false );
bool result = mComposition->loadFromTemplate( templateDoc, nullptr, false, clearExisting );
cleanupAfterTemplateRead();
setUpdatesEnabled( true );

dlg->close();
@@ -947,25 +937,19 @@ void QgsComposer::showItemOptions( QgsComposerItem *item )
{
if ( !item )
{
mItemPropertiesStack->takeMainPanel();
delete mItemPropertiesStack->takeMainPanel();
return;
}

QMap<QgsComposerItem *, QgsPanelWidget *>::const_iterator it = mItemWidgetMap.constFind( item );
if ( it == mItemWidgetMap.constEnd() )
std::unique_ptr< QgsPanelWidget > widget( createItemWidget( item ) );
if ( ! widget )
{
return;
}

QgsPanelWidget *newWidget = it.value();
if ( !newWidget || newWidget == mItemPropertiesStack->mainPanel() ) //bail out if new widget does not exist or is already there
{
return;
}

( void ) mItemPropertiesStack->takeMainPanel();
newWidget->setDockMode( true );
mItemPropertiesStack->setMainPanel( newWidget );
delete mItemPropertiesStack->takeMainPanel();
widget->setDockMode( true );
mItemPropertiesStack->setMainPanel( widget.release() );
}

void QgsComposer::on_mActionOptions_triggered()
@@ -1039,6 +1023,63 @@ void QgsComposer::atlasFeatureChanged( QgsFeature *feature )
mapCanvas()->expressionContextScope().addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_geometry" ), QVariant::fromValue( atlasFeature.geometry() ), true ) );
}

void QgsComposer::compositionItemAdded( QgsComposerItem *item )
{
if ( item && item->type() == QgsComposerItem::ComposerMap )
{
connect( this, &QgsComposer::zoomLevelChanged, static_cast< QgsComposerMap *>( item ), &QgsComposerMap::renderModeUpdateCachedImage );
}
}

QgsPanelWidget *QgsComposer::createItemWidget( QgsComposerItem *item )
{
if ( !item )
return nullptr;

switch ( item->type() )
{
case QgsComposerItem::ComposerArrow:
return new QgsComposerArrowWidget( static_cast< QgsComposerArrow * >( item ) );

case QgsComposerItem::ComposerPolygon:
return new QgsComposerPolygonWidget( static_cast< QgsComposerPolygon * >( item ) );

case QgsComposerItem::ComposerPolyline:
return new QgsComposerPolylineWidget( static_cast< QgsComposerPolyline * >( item ) );

case QgsComposerItem::ComposerLabel:
return new QgsComposerLabelWidget( static_cast< QgsComposerLabel * >( item ) );

case QgsComposerItem::ComposerMap:
return new QgsComposerMapWidget( static_cast< QgsComposerMap * >( item ) );

case QgsComposerItem::ComposerScaleBar:
return new QgsComposerScaleBarWidget( static_cast< QgsComposerScaleBar * >( item ) );

case QgsComposerItem::ComposerLegend:
return new QgsComposerLegendWidget( static_cast< QgsComposerLegend * >( item ) );

case QgsComposerItem::ComposerPicture:
return new QgsComposerPictureWidget( static_cast< QgsComposerPicture * >( item ) );

case QgsComposerItem::ComposerFrame:
{
QgsComposerFrame *frame = static_cast< QgsComposerFrame * >( item );
if ( QgsComposerHtml *html = dynamic_cast< QgsComposerHtml * >( frame->multiFrame() ) )
{
return new QgsComposerHtmlWidget( html, frame );
}
else if ( QgsComposerAttributeTableV2 *table = dynamic_cast< QgsComposerAttributeTableV2 * >( frame->multiFrame() ) )
{
return new QgsComposerAttributeTableWidget( table, frame );
}
break;
}

}
return nullptr; // no warnings!
}

void QgsComposer::on_mActionAtlasPreview_triggered( bool checked )
{
QgsAtlasComposition *atlasMap = &mComposition->atlasComposition();
@@ -3376,145 +3417,9 @@ void QgsComposer::restoreGridSettings()
mActionShowBoxes->setChecked( mComposition->boundingBoxesVisible() );
}

void QgsComposer::deleteItemWidgets()
{
//delete all the items
qDeleteAll( mItemWidgetMap );
mItemWidgetMap.clear();
}

void QgsComposer::addComposerArrow( QgsComposerArrow *arrow )
void QgsComposer::deleteItem( QgsComposerItem * )
{
if ( !arrow )
{
return;
}

QgsComposerArrowWidget *arrowWidget = new QgsComposerArrowWidget( arrow );
mItemWidgetMap.insert( arrow, arrowWidget );
}

void QgsComposer::addComposerPolygon( QgsComposerPolygon *polygon )
{
if ( !polygon )
{
return;
}

QgsComposerPolygonWidget *polygonWidget = new QgsComposerPolygonWidget( polygon );
mItemWidgetMap.insert( polygon, polygonWidget );
}

void QgsComposer::addComposerPolyline( QgsComposerPolyline *polyline )
{
if ( !polyline )
{
return;
}

QgsComposerPolylineWidget *polylineWidget = new QgsComposerPolylineWidget( polyline );
mItemWidgetMap.insert( polyline, polylineWidget );
}

void QgsComposer::addComposerMap( QgsComposerMap *map )
{
if ( !map )
{
return;
}

QgsComposerMapWidget *mapWidget = new QgsComposerMapWidget( map );
connect( this, &QgsComposer::zoomLevelChanged, map, &QgsComposerMap::renderModeUpdateCachedImage );
mItemWidgetMap.insert( map, mapWidget );
}

void QgsComposer::addComposerLabel( QgsComposerLabel *label )
{
if ( !label )
{
return;
}

QgsComposerLabelWidget *labelWidget = new QgsComposerLabelWidget( label );
mItemWidgetMap.insert( label, labelWidget );
}

void QgsComposer::addComposerScaleBar( QgsComposerScaleBar *scalebar )
{
if ( !scalebar )
{
return;
}

QgsComposerScaleBarWidget *sbWidget = new QgsComposerScaleBarWidget( scalebar );
mItemWidgetMap.insert( scalebar, sbWidget );
}

void QgsComposer::addComposerLegend( QgsComposerLegend *legend )
{
if ( !legend )
{
return;
}

QgsComposerLegendWidget *lWidget = new QgsComposerLegendWidget( legend );
mItemWidgetMap.insert( legend, lWidget );
}

void QgsComposer::addComposerPicture( QgsComposerPicture *picture )
{
if ( !picture )
{
return;
}

QgsComposerPictureWidget *pWidget = new QgsComposerPictureWidget( picture );
mItemWidgetMap.insert( picture, pWidget );
}

void QgsComposer::addComposerShape( QgsComposerShape *shape )
{
if ( !shape )
{
return;
}
QgsComposerShapeWidget *sWidget = new QgsComposerShapeWidget( shape );
mItemWidgetMap.insert( shape, sWidget );
}

void QgsComposer::addComposerTableV2( QgsComposerAttributeTableV2 *table, QgsComposerFrame *frame )
{
if ( !table )
{
return;
}
QgsComposerAttributeTableWidget *tWidget = new QgsComposerAttributeTableWidget( table, frame );
mItemWidgetMap.insert( frame, tWidget );
}

void QgsComposer::addComposerHtmlFrame( QgsComposerHtml *html, QgsComposerFrame *frame )
{
if ( !html )
{
return;
}

QgsComposerHtmlWidget *hWidget = new QgsComposerHtmlWidget( html, frame );
mItemWidgetMap.insert( frame, hWidget );
}

void QgsComposer::deleteItem( QgsComposerItem *item )
{
QMap<QgsComposerItem *, QgsPanelWidget *>::const_iterator it = mItemWidgetMap.constFind( item );

if ( it == mItemWidgetMap.constEnd() )
{
return;
}

//the item itself is not deleted here (usually, this is done in the destructor of QgsAddRemoveItemCommand)
it.value()->deleteLater();
mItemWidgetMap.remove( it.key() );
showItemOptions( nullptr );
}

void QgsComposer::setSelectionTool()
@@ -3608,19 +3513,18 @@ void QgsComposer::showAdvancedEffectsWarning()

void QgsComposer::cleanupAfterTemplateRead()
{
QMap<QgsComposerItem *, QgsPanelWidget *>::const_iterator itemIt = mItemWidgetMap.constBegin();
for ( ; itemIt != mItemWidgetMap.constEnd(); ++itemIt )
Q_FOREACH ( QGraphicsItem *item, mComposition->items() )
{
//update all legends completely
QgsComposerLegend *legendItem = dynamic_cast<QgsComposerLegend *>( itemIt.key() );
QgsComposerLegend *legendItem = dynamic_cast<QgsComposerLegend *>( item );
if ( legendItem )
{
legendItem->updateLegend();
continue;
}

//update composer map extent if it does not intersect the full extent of all layers
QgsComposerMap *mapItem = dynamic_cast<QgsComposerMap *>( itemIt.key() );
QgsComposerMap *mapItem = dynamic_cast<QgsComposerMap *>( item );
if ( mapItem )
{
//test if composer map extent intersects extent of all layers

0 comments on commit 885269e

Please sign in to comment.