From 09c10dada05dfd214d231a89d69eabb663351126 Mon Sep 17 00:00:00 2001 From: markus Date: Tue, 15 Feb 2022 13:37:44 -0800 Subject: [PATCH] Gracefully handle op creation abort when no TC is available or selected. --- src/Mod/Path/PathScripts/PathOp.py | 9 ++++++++- src/Mod/Path/PathScripts/PathOpGui.py | 24 +++++++++++++++++------- src/Mod/Path/PathScripts/PathUtils.py | 13 ++++++++++--- 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/Mod/Path/PathScripts/PathOp.py b/src/Mod/Path/PathScripts/PathOp.py index 9bcb53b249..5ed12e6fd5 100644 --- a/src/Mod/Path/PathScripts/PathOp.py +++ b/src/Mod/Path/PathScripts/PathOp.py @@ -68,6 +68,13 @@ FeatureDiameters = 0x4000 # Turning Diameters FeatureBaseGeometry = FeatureBaseVertexes | FeatureBaseFaces | FeatureBaseEdges +class PathNoTCException(Exception): + '''PathNoTCException is raised when no TC was selected or matches the input + criteria. This can happen intentionally by the user when they cancel the TC + selection dialog.''' + + def __init__(self): + super().__init__('No Tool Controller found') class ObjectOp(object): """ @@ -568,7 +575,7 @@ class ObjectOp(object): else: obj.ToolController = PathUtils.findToolController(obj, self) if not obj.ToolController: - return None + raise PathNoTCException() obj.OpToolDiameter = obj.ToolController.Tool.Diameter if FeatureCoolant & features: diff --git a/src/Mod/Path/PathScripts/PathOpGui.py b/src/Mod/Path/PathScripts/PathOpGui.py index 76fa36a783..50d5345539 100644 --- a/src/Mod/Path/PathScripts/PathOpGui.py +++ b/src/Mod/Path/PathScripts/PathOpGui.py @@ -1388,15 +1388,25 @@ def Create(res): this function directly, but calls the Activated() function of the Command object that is created in each operations Gui implementation.""" FreeCAD.ActiveDocument.openTransaction("Create %s" % res.name) - obj = res.objFactory(res.name, obj=None, parentJob=res.job) - if obj.Proxy: - obj.ViewObject.Proxy = ViewProvider(obj.ViewObject, res) - obj.ViewObject.Visibility = False - FreeCAD.ActiveDocument.commitTransaction() + try: + obj = res.objFactory(res.name, obj=None, parentJob=res.job) + if obj.Proxy: + obj.ViewObject.Proxy = ViewProvider(obj.ViewObject, res) + obj.ViewObject.Visibility = False + FreeCAD.ActiveDocument.commitTransaction() + + obj.ViewObject.Document.setEdit(obj.ViewObject, 0) + return obj + except PathUtils.PathNoTCExistsException: + msg = translate('PathOp', 'No suitable tool controller found.\nAborting op creation') + diag = QtGui.QMessageBox(QtGui.QMessageBox.Warning, "Error", msg) + diag.setWindowModality(QtCore.Qt.ApplicationModal) + diag.exec_() + except PathOp.PathNoTCException: + PathLog.warning(translate('PathOp', 'No tool controller, aborting op creation')) - obj.ViewObject.Document.setEdit(obj.ViewObject, 0) - return obj FreeCAD.ActiveDocument.abortTransaction() + FreeCAD.ActiveDocument.recompute() return None diff --git a/src/Mod/Path/PathScripts/PathUtils.py b/src/Mod/Path/PathScripts/PathUtils.py index 9b7cb4ff4c..4a4e837673 100644 --- a/src/Mod/Path/PathScripts/PathUtils.py +++ b/src/Mod/Path/PathScripts/PathUtils.py @@ -51,6 +51,13 @@ else: UserInput = None +class PathNoTCExistsException(Exception): + '''PathNoECExistsException is raised when no TC exists at all, or when all + existing TCs are rejected by a given op. + This is typically an error because avery op requires a TC. ''' + + def __init__(self): + super().__init__('No Tool Controllers exist') def waiting_effects(function): def new_function(*args, **kwargs): @@ -375,7 +382,7 @@ def findToolController(obj, proxy, name=None): controllers = getToolControllers(obj, proxy) if len(controllers) == 0: - return None + raise PathNoTCExistsException() # If there's only one in the job, use it. if len(controllers) == 1: @@ -383,9 +390,9 @@ def findToolController(obj, proxy, name=None): tc = controllers[0] else: tc = None - elif name is not None: # More than one, make the user choose. + elif name is not None: tc = [i for i in controllers if i.Label == name][0] - elif UserInput: + elif UserInput: # More than one, make the user choose. tc = UserInput.chooseToolController(controllers) return tc