@@ -73,19 +73,19 @@ def execute(alg, parameters, context=None, feedback=None):
def execute_in_place_run (alg , active_layer , parameters , context = None , feedback = None , raise_exceptions = False ):
"""Executes an algorithm modifying features in-place in the input layer.
The input layer must be editable or an exception is raised.
:param alg: algorithm to run
:type alg: QgsProcessingAlgorithm
:param active_layer: the editable layer
:type active_layer: QgsVectoLayer
:param parameters: parameters of the algorithm
:type parameters: dict
:param context: context, defaults to None
:param context: QgsProcessingContext, optional
:type context: QgsProcessingContext, optional
:param feedback: feedback, defaults to None
:param feedback: QgsProcessingFeedback, optional
:raises QgsProcessingException: raised when the layer is not editable or the layer cannot be found in the current project
:type feedback: QgsProcessingFeedback, optional
:param raise_exceptions: useful for testing, if True exceptions are raised, normally exceptions will be forwarded to the feedback
:type raise_exceptions: boo, default to False
:raises QgsProcessingException: raised when there is no active layer, or it cannot be made editable
:return: a tuple with true if success and results
:rtype: tuple
"""
@@ -95,14 +95,41 @@ def execute_in_place_run(alg, active_layer, parameters, context=None, feedback=N
if context is None :
context = dataobjects .createContext (feedback )
if active_layer is None or not active_layer .isEditable ():
raise QgsProcessingException (tr ("Layer is not editable or layer is None." ))
# Run some checks and prepare the layer for in-place execution by:
# - getting the active layer and checking that it is a vector
# - making the layer editable if it was not already
# - selecting all features if none was selected
# - checking in-place support for the active layer/alg/parameters
# If one of the check fails and raise_exceptions is True an exception
# is raised, else the execution is aborted and the error reported in
# the feedback
try :
if active_layer is None :
raise QgsProcessingException (tr ("There is not active layer." ))
if not active_layer .isEditable ():
if not active_layer .startEditing ():
raise QgsProcessingException (tr ("Active layer is not editable (and editing could not be turned on)." ))
if not alg .supportInPlaceEdit (active_layer ):
raise QgsProcessingException (tr ("Selected algorithm and parameter configuration are not compatible with in-place modifications." ))
except QgsProcessingException as e :
if raise_exceptions :
raise e
QgsMessageLog .logMessage (str (sys .exc_info ()[0 ]), 'Processing' , Qgis .Critical )
if feedback is not None :
feedback .reportError (getattr (e , 'msg' , str (e )), fatalError = True )
return False , {}
if not alg . supportInPlaceEdit ( active_layer ):
raise QgsProcessingException ( tr ( "Selected algorithm and parameter configuration are not compatible with in-place modifications." ) )
if not active_layer . selectedFeatureIds ( ):
active_layer . selectAll ( )
parameters ['OUTPUT' ] = 'memory:'
# Start the execution
# If anything goes wrong and raise_exceptions is True an exception
# is raised, else the execution is aborted and the error reported in
# the feedback
try :
new_feature_ids = []
@@ -190,16 +217,14 @@ def execute_in_place_run(alg, active_layer, parameters, context=None, feedback=N
raise e
QgsMessageLog .logMessage (str (sys .exc_info ()[0 ]), 'Processing' , Qgis .Critical )
if feedback is not None :
feedback .reportError (getattr (e , 'msg' , str (e )))
feedback .reportError (getattr (e , 'msg' , str (e )), fatalError = True )
return False , {}
def execute_in_place (alg , parameters , context = None , feedback = None ):
"""Executes an algorithm modifying features in-place in the active layer.
The input layer must be editable or an exception is raised.
:param alg: algorithm to run
:type alg: QgsProcessingAlgorithm
:param parameters: parameters of the algorithm