Follow up of #60225 where we have allowed that a QgsChunkLoader could
be a job assigned to node update - but I have forgotten to handle
cancellation correctly, so it was possible that in cancelActiveJob()
when a node was waiting for an update, we would mistakenly call
cancelLoading() instead of cancelUpdating(), triggering an assert.
When the reshape line goes backwards against the original line, the
result sometimes follows the reshape line direction, sometimes the
original line direction.
We fix this by always choosing the original line direction (except when
the reshape line completely overrides the original line).
When resetting the master password and wallet storage is enabled,
tweak the reset password dialog label to explicitly state that
the new password will be stored in the wallet.
This keeps users fully advised of what's about to occur.
stored in keychain when password is changed
This used to be a separate menu action that the user had to
remember to run. Let's err on the side of being helpful and
assume that if the user is storing the password in their
keychain, then they want that stored password always to be
the correct one.
When a profile tool is already opened, the output of a procssing is
not added to its layer tree. This is because it relies on a
`QgsLayerTreeRegistryBridge`. Indeed, `QgsLayerTreeRegistryBridge`
listens to the `QgsProject::legendLayersAdded()` signal in order to
update the elevation profile tree view. However this signal is not
triggered by the current logic in `Postprocessing.py`because
`QgsProject::addMaplayer` is called with `addToLegend` set to
False. Then, the layer is added to the tree by calling
`QgsLayerTreeGroup::insertChildNode`.
This issue is fixed by creating a
`QgsLayerTreeRegistryBridge::InsertionPoint` to set the insertion
point and then calling `QgsProject::addMaplayer` with `addToLegend`
set to True.
This change is similar to the previous commit on feature addition.
When a feature is removed from a `QgsVectorLayer`
`QgsVectorLayer::deleteFeature` is called. This function makes mostly
2 things in case of a successful operation:
1. it calls `QgsVectorLayerEditBuffer::deleteFeature` which itself
will emit the `QgsVectorLayerEditBuffer::featureDeleted`
signal. Finally, `QgsVectorLayer` listend to this signal to
directly emit the `QgsVectorLayer::featureDeleted` signal
2. Call `QgsVectorLayer::updateExtents()` to invalidate the cache of
the extent
In practice, this means that the `QgsVectorLayer::featureDeleted`
signal may be emitted before the cache of the extent is
invalidated. This can cause some issues.
This issue is solved by calling `updateExtents()` before emitting the
`featureDeleted` signal.
When a new feature is added to a `QgsVectorLayer`
`QgsVectorLayer::addFeature` is called. This function makes mostly 2
things in case of a successful operation:
1. it calls `QgsVectorLayerEditBuffer::addFeature` which itself will
emit the `QgsVectorLayerEditBuffer::featureAdded` signal. Finally,
`QgsVectorLayer` listend to this signal to directly emit the
`QgsVectorLayer::featureAdded` signal
2. Call `QgsVectorLayer::updateExtents()` to invalidate the cache of
the extent
In practice, this means that the `QgsVectorLayer::featureAdded` signal
may be emitted before the cache of the extent is invalidated. This can
cause some issues.
For example, in the elevation profile tool,
`QgsElevationProfileCanvas` listens to the
`QgsVectorLayer::featureAdded` signal in order to regenerate the
profile of a vector layer when a feature is added. This causes the
creation of a new `QgsVectorLayerProfileGenerator` which needs to copy
the extent of the vector layer. However,
`QgsVectorLayer::updateExtents()` has not been called yet. Thus, it
will use an outdated version of the extent.
This issue is solved by calling `updateExtents()` before emitting the
`featureAdded` signal.