From 99b218c63def131c420c0b653f3a79282679caac Mon Sep 17 00:00:00 2001 From: Russell Johnson <47639332+Russ4262@users.noreply.github.com> Date: Wed, 26 May 2021 23:02:57 -0500 Subject: [PATCH 1/4] Path: Prioritize `self.parent` and `self.obj` declarations This prioritization and conversion of `self.parent` declaration allows for removal of the `setParent()` method. --- src/Mod/Path/PathScripts/PathOpGui.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/Mod/Path/PathScripts/PathOpGui.py b/src/Mod/Path/PathScripts/PathOpGui.py index 6fcdf86e54..9d9ef3d4dd 100644 --- a/src/Mod/Path/PathScripts/PathOpGui.py +++ b/src/Mod/Path/PathScripts/PathOpGui.py @@ -214,11 +214,6 @@ class TaskPanelPage(object): def _installTCUpdate(self): return hasattr(self.form, 'toolController') - def setParent(self, parent): - '''setParent() ... used to transfer parent object link to child class. - Do not overwrite.''' - self.parent = parent - def onDirtyChanged(self, callback): '''onDirtyChanged(callback) ... set callback when dirty state changes.''' self.signalDirtyChanged = callback @@ -1000,8 +995,10 @@ class TaskPanel(object): def __init__(self, obj, deleteOnReject, opPage, selectionFactory): PathLog.track(obj.Label, deleteOnReject, opPage, selectionFactory) FreeCAD.ActiveDocument.openTransaction(translate("Path", "AreaOp Operation")) + self.obj = obj self.deleteOnReject = deleteOnReject self.featurePages = [] + self.parent = None # members initialized later self.clearanceHeight = None @@ -1050,9 +1047,9 @@ class TaskPanel(object): self.featurePages.append(opPage) for page in self.featurePages: + page.parent = self # save pointer to this current class as "parent" page.initPage(obj) page.onDirtyChanged(self.pageDirtyChanged) - page.setParent(self) taskPanelLayout = PathPreferences.defaultTaskPanelLayout() @@ -1092,7 +1089,6 @@ class TaskPanel(object): self.form = forms self.selectionFactory = selectionFactory - self.obj = obj self.isdirty = deleteOnReject self.visibility = obj.ViewObject.Visibility obj.ViewObject.Visibility = True From 495a4e610ab5fe6ae4cb967c14fc0061e03515ff Mon Sep 17 00:00:00 2001 From: Russell Johnson <47639332+Russ4262@users.noreply.github.com> Date: Wed, 26 May 2021 23:03:43 -0500 Subject: [PATCH 2/4] Path: Fix readonly lockout bug with blank expression --- src/Mod/Path/PathScripts/PathGui.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Mod/Path/PathScripts/PathGui.py b/src/Mod/Path/PathScripts/PathGui.py index fb37725bf3..3280a93d02 100644 --- a/src/Mod/Path/PathScripts/PathGui.py +++ b/src/Mod/Path/PathScripts/PathGui.py @@ -68,10 +68,10 @@ def updateInputField(obj, prop, widget, onBeforeChange=None): isDiff = True break if noExpr: - widget.setProperty('readonly', False) + widget.setReadOnly(False) widget.setStyleSheet("color: black") else: - widget.setProperty('readonly', True) + widget.setReadOnly(True) widget.setStyleSheet("color: gray") widget.update() From 527e168be275e0f14212cf90e29fcda1dc503684 Mon Sep 17 00:00:00 2001 From: Russell Johnson <47639332+Russ4262@users.noreply.github.com> Date: Wed, 26 May 2021 23:09:36 -0500 Subject: [PATCH 3/4] Path: Fix bug with inaccurate Task Panel values upon new op creation Path: Fix bug with inaccurate Task Panel values upon new op creation --- src/Mod/Path/PathScripts/PathGui.py | 14 +++++++++++++- src/Mod/Path/PathScripts/PathOpGui.py | 11 +++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/Mod/Path/PathScripts/PathGui.py b/src/Mod/Path/PathScripts/PathGui.py index 3280a93d02..1d0d58f358 100644 --- a/src/Mod/Path/PathScripts/PathGui.py +++ b/src/Mod/Path/PathScripts/PathGui.py @@ -100,6 +100,7 @@ class QuantitySpinBox: self.widget = widget self.onBeforeChange = onBeforeChange self.prop = None + self.obj = obj self.attachTo(obj, prop) def attachTo(self, obj, prop = None): @@ -139,9 +140,14 @@ class QuantitySpinBox: If no value is provided the value of the bound property is used. quantity can be of type Quantity or Float.''' PathLog.track(self.prop, self.valid) + if self.valid: + expr = self._hasExpression() if quantity is None: - quantity = PathUtil.getProperty(self.obj, self.prop) + if expr: + quantity = FreeCAD.Units.Quantity(self.obj.evalExpression(expr)) + else: + quantity = PathUtil.getProperty(self.obj, self.prop) value = quantity.Value if hasattr(quantity, 'Value') else quantity self.widget.setProperty('rawValue', value) @@ -151,3 +157,9 @@ class QuantitySpinBox: if self.valid: return updateInputField(self.obj, self.prop, self.widget, self.onBeforeChange) return None + + def _hasExpression(self): + for (prop, exp) in self.obj.ExpressionEngine: + if prop == self.prop: + return exp + return None diff --git a/src/Mod/Path/PathScripts/PathOpGui.py b/src/Mod/Path/PathScripts/PathOpGui.py index 9d9ef3d4dd..33de983c24 100644 --- a/src/Mod/Path/PathScripts/PathOpGui.py +++ b/src/Mod/Path/PathScripts/PathOpGui.py @@ -1203,7 +1203,18 @@ class TaskPanel(object): page.clearBase() page.addBaseGeometry(sel) + # Update properties based upon expressions in case expression value has changed + for (prp, expr) in self.obj.ExpressionEngine: + val = FreeCAD.Units.Quantity(self.obj.evalExpression(expr)) + value = val.Value if hasattr(val, 'Value') else val + prop = getattr(self.obj, prp) + if hasattr(prop, "Value"): + prop.Value = value + else: + prop = value + self.panelSetFields() + for page in self.featurePages: page.pageRegisterSignalHandlers() From d008303ae78d0973309ea54f5f18b502031131a7 Mon Sep 17 00:00:00 2001 From: Russell Johnson <47639332+Russ4262@users.noreply.github.com> Date: Thu, 27 May 2021 20:20:47 -0500 Subject: [PATCH 4/4] Path: Code cleanup, remove duplication, fix `obj.removalshape` shape --- src/Mod/Path/PathScripts/PathPocketShape.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Mod/Path/PathScripts/PathPocketShape.py b/src/Mod/Path/PathScripts/PathPocketShape.py index 902fb21c44..a35326b9be 100644 --- a/src/Mod/Path/PathScripts/PathPocketShape.py +++ b/src/Mod/Path/PathScripts/PathPocketShape.py @@ -84,6 +84,7 @@ class ObjectPocket(PathPocketBase.ObjectPocket): def areaOpShapes(self, obj): '''areaOpShapes(obj) ... return shapes representing the solids to be removed.''' PathLog.track() + self.removalshapes = [] # self.isDebug = True if PathLog.getLevel(PathLog.thisModule()) == 4 else False self.removalshapes = [] @@ -162,7 +163,8 @@ class ObjectPocket(PathPocketBase.ObjectPocket): # shape.tessellate(0.05) # originally 0.1 if self.removalshapes: - obj.removalshape = self.removalshapes[0][0] + obj.removalshape = Part.makeCompound([tup[0] for tup in self.removalshapes]) + return self.removalshapes # Support methods