diff --git a/src/Mod/Path/Gui/Resources/panels/DlgToolControllerEdit.ui b/src/Mod/Path/Gui/Resources/panels/DlgToolControllerEdit.ui
index 9e5c1ed9e2..845e2e923b 100644
--- a/src/Mod/Path/Gui/Resources/panels/DlgToolControllerEdit.ui
+++ b/src/Mod/Path/Gui/Resources/panels/DlgToolControllerEdit.ui
@@ -16,7 +16,15 @@
-
-
+
+
+
+ 0
+ 0
+ 474
+ 535
+
+
Controller
@@ -79,10 +87,13 @@
-
-
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
0.000000000000000
-
+
9999999.000000000000000
@@ -92,10 +103,13 @@
-
-
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
0.000000000000000
-
+
9999999.000000000000000
@@ -105,10 +119,13 @@
-
-
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
0.000000000000000
-
+
9999999.000000000000000
@@ -118,10 +135,13 @@
-
-
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
0.000000000000000
-
+
9999999.000000000000000
@@ -183,7 +203,15 @@
-
+
+
+
+ 0
+ 0
+ 474
+ 535
+
+
Tool
@@ -377,18 +405,21 @@
-
-
-
- 0 mm
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
- 0.125000000000000
+
+ 0.00
-
+
+ 0.000000000000000
+
+
100.000000000000000
-
- 0.000000000000000
+
+ 0.125000000000000
mm
@@ -396,71 +427,86 @@
-
-
-
- 0 mm
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
- 100.000000000000000
+
+ 0.00
-
+
0.000000000000000
+
+ 100.000000000000000
+
mm
-
-
-
- 0 mm
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
- 100.000000000000000
+
+ 0.00
-
+
0.000000000000000
+
+ 100.000000000000000
+
mm
-
-
-
- 0 mm
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
- 100.000000000000000
+
+ 0.00
-
+
0.000000000000000
+
+ 100.000000000000000
+
mm
-
-
-
- 0 mm
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
- 100.000000000000000
+
+ 0.00
-
+
0.000000000000000
+
+ 100.000000000000000
+
mm
-
-
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
°
@@ -502,17 +548,32 @@
-
- Gui::InputField
- QLineEdit
-
-
Gui::QuantitySpinBox
QDoubleSpinBox
+
+ tcName
+ tcNumber
+ horizFeed
+ vertFeed
+ horizRapid
+ vertRapid
+ spindleSpeed
+ spindleDirection
+ buttonBox
+ toolName
+ toolType
+ toolMaterial
+ toolDiameter
+ toolLengthOffset
+ toolFlatRadius
+ toolCornerRadius
+ toolCuttingEdgeAngle
+ toolCuttingEdgeHeight
+
diff --git a/src/Mod/Path/PathScripts/PathGui.py b/src/Mod/Path/PathScripts/PathGui.py
index e53f4cc831..47fcc69069 100644
--- a/src/Mod/Path/PathScripts/PathGui.py
+++ b/src/Mod/Path/PathScripts/PathGui.py
@@ -25,60 +25,114 @@
import FreeCAD
import FreeCADGui
import PathScripts.PathLog as PathLog
-import importlib
+import PySide
from PathScripts.PathGeom import PathGeom
-from PySide import QtCore, QtGui
__title__ = "Path UI helper and utility functions"
__author__ = "sliptonic (Brad Collette)"
__url__ = "http://www.freecadweb.org"
__doc__ = "A collection of helper and utility functions for the Path GUI."
+def translate(context, text, disambig=None):
+ return PySide.QtCore.QCoreApplication.translate(context, text, disambig)
+
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
-def updateInputField(obj, prop, widget, onBeforeChange = None):
- '''updateInputField(obj, prop, widget) ... helper function to update obj's property named prop with the value from widget, if it has changed.'''
+def _getProperty(obj, prop):
+ o = obj
+ attr = obj
+ for name in prop.split('.'):
+ o = attr
+ if not hasattr(o, name):
+ break
+ attr = getattr(o, name)
+
+ if o == attr:
+ PathLog.warning(translate('PathGui', "%s has no property %s (%s))") % (obj.Label, prop))
+ return (None, None, None)
+
+ #PathLog.debug("found property %s of %s (%s: %s)" % (prop, obj.Label, name, attr))
+ return(o, attr, name)
+
+def getProperty(obj, prop):
+ '''getProperty(obj, prop) ... answer obj's property defined by its canonical name.'''
+ o, attr, name = _getProperty(obj, prop)
+ return attr
+
+def setProperty(obj, prop, value):
+ '''setProperty(obj, prop, value) ... set the property value of obj's property defined by its canonical name.'''
+ o, attr, name = _getProperty(obj, prop)
+ if o and name:
+ setattr(o, name, value)
+
+def updateInputField(obj, prop, widget, onBeforeChange=None):
+ '''updateInputField(obj, prop, widget) ... update obj's property prop with the value of widget.
+The property's value is only assigned if the new value differs from the current value.
+This prevents onChanged notifications where the value didn't acutally change.
+Gui::InputField and Gui::QuantitySpinBox widgets are supported - and the property can
+be of type Quantity or Float.
+If onBeforeChange is specified it is called before a new value is assigned to the property.
+Returns True if a new value was assigned, False otherwise (new value is the same as the current).
+'''
value = FreeCAD.Units.Quantity(widget.text()).Value
- attr = getattr(obj, prop)
+ attr = getProperty(obj, prop)
attrValue = attr.Value if hasattr(attr, 'Value') else attr
if not PathGeom.isRoughly(attrValue, value):
- PathLog.debug("updateInputField(%s, %s): %.2f -> %.2f" % (obj.Label, prop, getattr(obj, prop), value))
+ PathLog.debug("updateInputField(%s, %s): %.2f -> %.2f" % (obj.Label, prop, attr, value))
if onBeforeChange:
onBeforeChange(obj)
- setattr(obj, prop, value)
+ setProperty(obj, prop, value)
return True
return False
class QuantitySpinBox:
- def __init__(self, widget, obj, propName, onBeforeChange=None):
+ '''Controller class to interface a Gui::QuantitySpinBox.
+The spin box gets bound to a given property and supports update in both directions.
+ QuatitySpinBox(widget, obj, prop, onBeforeChange=None)
+ widget ... expected to be reference to a Gui::QuantitySpinBox
+ obj ... document object
+ prop ... canonical name of the (sub-) property
+ onBeforeChange ... an optional callback being executed before the value of the property is changed
+'''
+
+ def __init__(self, widget, obj, prop, onBeforeChange=None):
self.obj = obj
self.widget = widget
- self.prop = propName
+ self.prop = prop
self.onBeforeChange = onBeforeChange
- if hasattr(obj, propName):
- widget.setProperty('unit', getattr(self.obj, self.prop).getUserPreferred()[2])
- widget.setProperty('binding', "%s.%s" % (obj.Name, propName))
+ attr = getProperty(self.obj, self.prop)
+ if attr is not None:
+ if hasattr(attr, 'Value'):
+ widget.setProperty('unit', attr.getUserPreferred()[2])
+ widget.setProperty('binding', "%s.%s" % (obj.Name, prop))
self.valid = True
else:
+ PathLog.warning(translate('PathGui', "Cannot find property %s of %s") % (prop, obj.Label))
self.valid = False
def expression(self):
+ '''expression() ... returns the expression if one is bound to the property'''
if self.valid:
return self.widget.property('expression')
- return False
+ return ''
def updateSpinBox(self, quantity=None):
+ '''updateSpinBox(quantity=None) ... update the display value of the spin box.
+If no value is provided the value of the bound property is used.
+quantity can be of type Quantity or Float.'''
if self.valid:
if quantity is None:
- quantity = getattr(self.obj, self.prop)
- self.widget.setProperty('rawValue', quantity.Value)
+ quantity = getProperty(self.obj, self.prop)
+ value = quantity.Value if hasattr(quantity, 'Value') else quantity
+ self.widget.setProperty('rawValue', value)
def updateProperty(self):
+ '''updateProperty() ... update the bound property with the value from the spin box'''
if self.valid:
return updateInputField(self.obj, self.prop, self.widget, self.onBeforeChange)
return None
diff --git a/src/Mod/Path/PathScripts/PathToolController.py b/src/Mod/Path/PathScripts/PathToolController.py
index f1a25f12cd..79d587b40a 100644
--- a/src/Mod/Path/PathScripts/PathToolController.py
+++ b/src/Mod/Path/PathScripts/PathToolController.py
@@ -269,11 +269,19 @@ class ToolControllerEditor:
if not asDialog:
self.form.buttonBox.hide()
self.obj = obj
+
self.vertFeed = PathGui.QuantitySpinBox(self.form.vertFeed, obj, 'VertFeed')
self.horizFeed = PathGui.QuantitySpinBox(self.form.horizFeed, obj, 'HorizFeed')
self.vertRapid = PathGui.QuantitySpinBox(self.form.vertRapid, obj, 'VertRapid')
self.horizRapid = PathGui.QuantitySpinBox(self.form.horizRapid, obj, 'HorizRapid')
+ self.toolDiameter = PathGui.QuantitySpinBox(self.form.toolDiameter, obj, 'Tool.Diameter')
+ self.toolLengthOffset = PathGui.QuantitySpinBox(self.form.toolLengthOffset, obj, 'Tool.LengthOffset')
+ self.toolFlatRadius = PathGui.QuantitySpinBox(self.form.toolFlatRadius, obj, 'Tool.FlatRadius')
+ self.toolCornerRadius = PathGui.QuantitySpinBox(self.form.toolCornerRadius, obj, 'Tool.CornerRadius')
+ self.toolCuttingEdgeAngle = PathGui.QuantitySpinBox(self.form.toolCuttingEdgeAngle, obj, 'Tool.CuttingEdgeAngle')
+ self.toolCuttingEdgeHeight = PathGui.QuantitySpinBox(self.form.toolCuttingEdgeHeight, obj, 'Tool.CuttingEdgeHeight')
+
def getType(self, tooltype):
"gets a combobox index number for a given type or viceversa"
toolslist = ["Drill", "CenterDrill", "CounterSink", "CounterBore",
@@ -315,12 +323,12 @@ class ToolControllerEditor:
self.form.toolName.setText(tc.Tool.Name)
self.form.toolType.setCurrentIndex(self.getType(tc.Tool.ToolType))
self.form.toolMaterial.setCurrentIndex(self.getMaterial(tc.Tool.Material))
- self.form.toolDiameter.setText(FreeCAD.Units.Quantity(tc.Tool.Diameter, FreeCAD.Units.Length).UserString)
- self.form.toolLengthOffset.setText(FreeCAD.Units.Quantity(tc.Tool.LengthOffset, FreeCAD.Units.Length).UserString)
- self.form.toolFlatRadius.setText(FreeCAD.Units.Quantity(tc.Tool.FlatRadius, FreeCAD.Units.Length).UserString)
- self.form.toolCornerRadius.setText(FreeCAD.Units.Quantity(tc.Tool.CornerRadius, FreeCAD.Units.Length).UserString)
- self.form.toolCuttingEdgeAngle.setText(FreeCAD.Units.Quantity(tc.Tool.CuttingEdgeAngle, FreeCAD.Units.Angle).UserString)
- self.form.toolCuttingEdgeHeight.setText(FreeCAD.Units.Quantity(tc.Tool.CuttingEdgeHeight, FreeCAD.Units.Length).UserString)
+ self.toolDiameter.updateSpinBox()
+ self.toolLengthOffset.updateSpinBox()
+ self.toolFlatRadius.updateSpinBox()
+ self.toolCornerRadius.updateSpinBox()
+ self.toolCuttingEdgeAngle.updateSpinBox()
+ self.toolCuttingEdgeHeight.updateSpinBox()
def updateToolController(self):
tc = self.obj
@@ -337,12 +345,12 @@ class ToolControllerEditor:
tc.Tool.Name = str(self.form.toolName.text())
tc.Tool.ToolType = self.getType(self.form.toolType.currentIndex())
tc.Tool.Material = self.getMaterial(self.form.toolMaterial.currentIndex())
- tc.Tool.Diameter = FreeCAD.Units.parseQuantity(self.form.toolDiameter.text())
- tc.Tool.LengthOffset = FreeCAD.Units.parseQuantity(self.form.toolLengthOffset.text())
- tc.Tool.FlatRadius = FreeCAD.Units.parseQuantity(self.form.toolFlatRadius.text())
- tc.Tool.CornerRadius = FreeCAD.Units.parseQuantity(self.form.toolCornerRadius.text())
- tc.Tool.CuttingEdgeAngle = FreeCAD.Units.Quantity(self.form.toolCuttingEdgeAngle.text())
- tc.Tool.CuttingEdgeHeight = FreeCAD.Units.parseQuantity(self.form.toolCuttingEdgeHeight.text())
+ self.toolDiameter.updateProperty()
+ self.toolLengthOffset.updateProperty()
+ self.toolFlatRadius.updateProperty()
+ self.toolCornerRadius.updateProperty()
+ self.toolCuttingEdgeAngle.updateProperty()
+ self.toolCuttingEdgeHeight.updateProperty()
except Exception as e:
PathLog.error(translate("PathToolController", "Error updating TC: %s") % e)