|
34 | 34 | QgsLayoutItemMap::QgsLayoutItemMap( QgsLayout *layout )
|
35 | 35 | : QgsLayoutItem( layout )
|
36 | 36 | {
|
37 |
| - assignFreeId(); |
| 37 | + mBackgroundUpdateTimer = new QTimer( this ); |
| 38 | + mBackgroundUpdateTimer->setSingleShot( true ); |
| 39 | + connect( mBackgroundUpdateTimer, &QTimer::timeout, this, &QgsLayoutItemMap::recreateCachedImageInBackground ); |
38 | 40 |
|
| 41 | + assignFreeId(); |
39 | 42 |
|
40 | 43 | if ( layout )
|
41 | 44 | {
|
@@ -774,18 +777,20 @@ void QgsLayoutItemMap::paint( QPainter *painter, const QStyleOptionGraphicsItem
|
774 | 777 | painter->setFont( messageFont );
|
775 | 778 | painter->setPen( QColor( 255, 255, 255, 255 ) );
|
776 | 779 | painter->drawText( thisPaintRect, Qt::AlignCenter | Qt::AlignHCenter, tr( "Rendering map" ) );
|
777 |
| - if ( !mPainterJob ) |
| 780 | + if ( !mPainterJob && !mDrawingPreview ) |
778 | 781 | {
|
779 | 782 | // this is the map's very first paint - trigger a cache update
|
780 |
| - recreateCachedImageInBackground( style->matrix.m11() ); |
| 783 | + mPreviewScaleFactor = style->matrix.m11(); |
| 784 | + mBackgroundUpdateTimer->start( 1 ); |
781 | 785 | }
|
782 | 786 | }
|
783 | 787 | else
|
784 | 788 | {
|
785 |
| - if ( mCacheInvalidated ) |
| 789 | + if ( mCacheInvalidated && !mDrawingPreview ) |
786 | 790 | {
|
787 | 791 | // cache was invalidated - trigger a background update
|
788 |
| - recreateCachedImageInBackground( style->matrix.m11() ); |
| 792 | + mPreviewScaleFactor = style->matrix.m11(); |
| 793 | + mBackgroundUpdateTimer->start( 1 ); |
789 | 794 | }
|
790 | 795 |
|
791 | 796 | //Background color is already included in cached image, so no need to draw
|
@@ -966,7 +971,7 @@ void QgsLayoutItemMap::drawMap( QPainter *painter, const QgsRectangle &extent, Q
|
966 | 971 | job.renderSynchronously();
|
967 | 972 | }
|
968 | 973 |
|
969 |
| -void QgsLayoutItemMap::recreateCachedImageInBackground( double viewScaleFactor ) |
| 974 | +void QgsLayoutItemMap::recreateCachedImageInBackground() |
970 | 975 | {
|
971 | 976 | if ( mPainterJob )
|
972 | 977 | {
|
@@ -995,8 +1000,8 @@ void QgsLayoutItemMap::recreateCachedImageInBackground( double viewScaleFactor )
|
995 | 1000 | double widthLayoutUnits = ext.width() * mapUnitsToLayoutUnits();
|
996 | 1001 | double heightLayoutUnits = ext.height() * mapUnitsToLayoutUnits();
|
997 | 1002 |
|
998 |
| - int w = widthLayoutUnits * viewScaleFactor; |
999 |
| - int h = heightLayoutUnits * viewScaleFactor; |
| 1003 | + int w = widthLayoutUnits * mPreviewScaleFactor; |
| 1004 | + int h = heightLayoutUnits * mPreviewScaleFactor; |
1000 | 1005 |
|
1001 | 1006 | // limit size of image for better performance
|
1002 | 1007 | if ( w > 5000 || h > 5000 )
|
@@ -1040,6 +1045,18 @@ void QgsLayoutItemMap::recreateCachedImageInBackground( double viewScaleFactor )
|
1040 | 1045 | mPainterJob.reset( new QgsMapRendererCustomPainterJob( settings, mPainter.get() ) );
|
1041 | 1046 | connect( mPainterJob.get(), &QgsMapRendererCustomPainterJob::finished, this, &QgsLayoutItemMap::painterJobFinished );
|
1042 | 1047 | mPainterJob->start();
|
| 1048 | + |
| 1049 | + // from now on we can accept refresh requests again |
| 1050 | + // this must be reset only after the job has been started, because |
| 1051 | + // some providers (yes, it's you WCS and AMS!) during preparation |
| 1052 | + // do network requests and start an internal event loop, which may |
| 1053 | + // end up calling refresh() and would schedule another refresh, |
| 1054 | + // deleting the one we have just started. |
| 1055 | + |
| 1056 | + // ^^ that comment was directly copied from a similar fix in QgsMapCanvas. And |
| 1057 | + // with little surprise, both those providers are still badly behaved and causing |
| 1058 | + // annoying bugs for us to deal with... |
| 1059 | + mDrawingPreview = false; |
1043 | 1060 | }
|
1044 | 1061 |
|
1045 | 1062 | QgsMapSettings QgsLayoutItemMap::mapSettings( const QgsRectangle &extent, QSizeF size, double dpi, bool includeLayerSettings ) const
|
|
0 commit comments