Skip to content

Commit

Permalink
Allow a QgsFeedback object to be associated with a render context,
Browse files Browse the repository at this point in the history
for cancelation check support

While there is the existing QgsRenderContext::renderingStopped()
check, this doesn't play well with other parts of QGIS which utilise
a QgsFeedback object for cancelation support. By adding support
for a proper QgsFeedback object in render contexts then it becomes
trivial to pass this on to feature requests, expression contexts,
and other potentially expensive functions so that these can
all be canceled responsively too.

(At some stage in the future we should consider deprecating
QgsRenderContext::rendereringStopped(), but that's not done here)
  • Loading branch information
nyalldawson committed Sep 24, 2021
1 parent 07a5503 commit d838ce7
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 0 deletions.
37 changes: 37 additions & 0 deletions python/core/auto_generated/qgsrendercontext.sip.in
Expand Up @@ -294,7 +294,36 @@ Returns the targeted DPI for rendering.
Returns ``True`` if the rendering operation has been stopped and any ongoing
rendering should be canceled immediately.

.. note::

Since QGIS 3.22 the :py:func:`~QgsRenderContext.feedback` member exists as an alternative means of cancelation support.

.. seealso:: :py:func:`setRenderingStopped`

.. seealso:: :py:func:`feedback`
%End

void setFeedback( QgsFeedback *feedback );
%Docstring
Attach a ``feedback`` object that can be queried regularly during rendering to check
if rendering should be canceled.

Ownership of ``feedback`` is NOT transferred, and the caller must take care that it exists
for the lifetime of the render context.

.. seealso:: :py:func:`feedback`

.. versionadded:: 3.22
%End

QgsFeedback *feedback() const;
%Docstring
Returns the feedback object that can be queried regularly during rendering to check
if rendering should be canceled, if set. Maybe be ``None``.

.. seealso:: :py:func:`setFeedback`

.. versionadded:: 3.22
%End

bool forceVectorOutput() const;
Expand Down Expand Up @@ -436,7 +465,15 @@ Sets whether edit markers should be drawn during the render operation.
Sets whether the rendering operation has been ``stopped`` and any ongoing
rendering should be canceled immediately.

.. note::

Since QGIS 3.22 the :py:func:`~QgsRenderContext.feedback` member exists as an alternative means of cancelation support.

.. seealso:: :py:func:`renderingStopped`

.. seealso:: :py:func:`feedback`

.. seealso:: :py:func:`setFeedback`
%End

void setDistanceArea( const QgsDistanceArea &distanceArea );
Expand Down
12 changes: 12 additions & 0 deletions src/core/qgsrendercontext.cpp
Expand Up @@ -50,6 +50,7 @@ QgsRenderContext::QgsRenderContext( const QgsRenderContext &rh )
, mOriginalMapExtent( rh.mOriginalMapExtent )
, mMapToPixel( rh.mMapToPixel )
, mRenderingStopped( rh.mRenderingStopped )
, mFeedback( rh.mFeedback )
, mScaleFactor( rh.mScaleFactor )
, mDpiTarget( rh.mDpiTarget )
, mRendererScale( rh.mRendererScale )
Expand Down Expand Up @@ -89,6 +90,7 @@ QgsRenderContext &QgsRenderContext::operator=( const QgsRenderContext &rh )
mOriginalMapExtent = rh.mOriginalMapExtent;
mMapToPixel = rh.mMapToPixel;
mRenderingStopped = rh.mRenderingStopped;
mFeedback = rh.mFeedback;
mScaleFactor = rh.mScaleFactor;
mDpiTarget = rh.mDpiTarget;
mRendererScale = rh.mRendererScale;
Expand Down Expand Up @@ -177,6 +179,16 @@ void QgsRenderContext::setTransformContext( const QgsCoordinateTransformContext
#endif
}

void QgsRenderContext::setFeedback( QgsFeedback *feedback )
{
mFeedback = feedback;
}

QgsFeedback *QgsRenderContext::feedback() const
{
return mFeedback;
}

void QgsRenderContext::setFlags( QgsRenderContext::Flags flags )
{
mFlags = flags;
Expand Down
33 changes: 33 additions & 0 deletions src/core/qgsrendercontext.h
Expand Up @@ -344,10 +344,36 @@ class CORE_EXPORT QgsRenderContext : public QgsTemporalRangeObject
* Returns TRUE if the rendering operation has been stopped and any ongoing
* rendering should be canceled immediately.
*
* \note Since QGIS 3.22 the feedback() member exists as an alternative means of cancelation support.
*
* \see setRenderingStopped()
* \see feedback()
*/
bool renderingStopped() const {return mRenderingStopped;}

/**
* Attach a \a feedback object that can be queried regularly during rendering to check
* if rendering should be canceled.
*
* Ownership of \a feedback is NOT transferred, and the caller must take care that it exists
* for the lifetime of the render context.
*
* \see feedback()
*
* \since QGIS 3.22
*/
void setFeedback( QgsFeedback *feedback );

/**
* Returns the feedback object that can be queried regularly during rendering to check
* if rendering should be canceled, if set. Maybe be NULLPTR.
*
* \see setFeedback()
*
* \since QGIS 3.22
*/
QgsFeedback *feedback() const;

/**
* Returns TRUE if rendering operations should use vector operations instead
* of any faster raster shortcuts.
Expand Down Expand Up @@ -482,7 +508,11 @@ class CORE_EXPORT QgsRenderContext : public QgsTemporalRangeObject
* Sets whether the rendering operation has been \a stopped and any ongoing
* rendering should be canceled immediately.
*
* \note Since QGIS 3.22 the feedback() member exists as an alternative means of cancelation support.
*
* \see renderingStopped()
* \see feedback()
* \see setFeedback()
*/
void setRenderingStopped( bool stopped ) {mRenderingStopped = stopped;}

Expand Down Expand Up @@ -975,6 +1005,9 @@ class CORE_EXPORT QgsRenderContext : public QgsTemporalRangeObject
//! True if the rendering has been canceled
bool mRenderingStopped = false;

//! Optional feedback object, as an alternative for mRenderingStopped for cancelation support
QgsFeedback *mFeedback = nullptr;

//! Factor to scale line widths and point marker sizes
double mScaleFactor = 1.0;

Expand Down

0 comments on commit d838ce7

Please sign in to comment.