diff --git a/src/Mod/Path/PathScripts/PathToolBit.py b/src/Mod/Path/PathScripts/PathToolBit.py index 97176b86cd..4a72dedab2 100644 --- a/src/Mod/Path/PathScripts/PathToolBit.py +++ b/src/Mod/Path/PathScripts/PathToolBit.py @@ -192,7 +192,17 @@ class ToolBit(object): if obj.BitBody is not None: for attributes in [o for o in obj.BitBody.Group if hasattr(o, 'Proxy') and hasattr(o.Proxy, 'getCustomProperties')]: for prop in attributes.Proxy.getCustomProperties(): - setattr(attributes, prop, obj.getPropertyByName(prop)) + # the property might not exist in our local object (new attribute in shape) + # for such attributes we just keep the default + if hasattr(obj, prop): + setattr(attributes, prop, obj.getPropertyByName(prop)) + else: + # if the template shape has a new attribute defined we should add that + # to the local object + self._setupProperty(obj, prop, attributes) + propNames = obj.BitPropertyNames + propNames.append(prop) + obj.BitPropertyNames = propNames self._copyBitShape(obj) def _copyBitShape(self, obj): @@ -251,6 +261,20 @@ class ToolBit(object): def unloadBitBody(self, obj): self._removeBitBody(obj) + def _setupProperty(self, obj, prop, orig): + # extract property parameters and values so it can be copied + val = orig.getPropertyByName(prop) + typ = orig.getTypeIdOfProperty(prop) + grp = orig.getGroupOfProperty(prop) + dsc = orig.getDocumentationOfProperty(prop) + + obj.addProperty(typ, prop, grp, dsc) + if 'App::PropertyEnumeration' == typ: + setattr(obj, prop, orig.getEnumerationsOfProperty(prop)) + + obj.setEditorMode(prop, 1) + PathUtil.setProperty(obj, prop, val) + def _setupBitShape(self, obj, path=None): PathLog.track(obj.Label) @@ -275,15 +299,7 @@ class ToolBit(object): for attributes in [o for o in bitBody.Group if PathPropertyBag.IsPropertyBag(o)]: PathLog.debug("Process properties from {}".format(attributes.Label)) for prop in attributes.Proxy.getCustomProperties(): - # extract property parameters and values so it can be copied - src = attributes.getPropertyByName(prop) - typ = PathPropertyBag.getPropertyType(src) - grp = attributes.getGroupOfProperty(prop) - dsc = attributes.getDocumentationOfProperty(prop) - - obj.addProperty(typ, prop, grp, dsc) - obj.setEditorMode(prop, 1) - PathUtil.setProperty(obj, prop, src) + self._setupProperty(obj, prop, attributes) propNames.append(prop) if not propNames: PathLog.error(translate('PathToolBit', 'Did not find a PropertyBag in {} - not a ToolBit shape?').format(docName)) diff --git a/src/Mod/Path/PathScripts/PathToolBitEdit.py b/src/Mod/Path/PathScripts/PathToolBitEdit.py index 26ccd068d5..724f5b65cc 100644 --- a/src/Mod/Path/PathScripts/PathToolBitEdit.py +++ b/src/Mod/Path/PathScripts/PathToolBitEdit.py @@ -25,6 +25,7 @@ import FreeCADGui import PathScripts.PathGui as PathGui import PathScripts.PathLog as PathLog import PathScripts.PathPreferences as PathPreferences +import PathScripts.PathPropertyEditor as PathPropertyEditor import PathScripts.PathToolBit as PathToolBit import PathScripts.PathUtil as PathUtil import os @@ -40,65 +41,6 @@ PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule()) def translate(context, text, disambig=None): return QtCore.QCoreApplication.translate(context, text, disambig) -class _PropertyEditorBase(object): - '''Base class of all typed property editors''' - - def __init__(self, obj, prop): - self.obj = obj - self.prop = prop - def getValue(self): - return getattr(self.obj, self.prop) - def setValue(self, val): - setattr(self.obj, self.prop, val) - -class _PropertyEditorInteger(_PropertyEditorBase): - def widget(self, parent): - return QtGui.QSpinBox(parent) - def setEditorData(self, widget): - widget.setValue(self.getValue()) - def setModelData(self, widget): - self.setValue(widget.value()) - -class _PropertyEditorFloat(_PropertyEditorInteger): - def widget(self, parent): - return QtGui.QDoubleSpinBox(parent) - -class _PropertyEditorBool(_PropertyEditorBase): - def widget(self, parent): - return QtGui.QComboBox(parent) - def setEditorData(self, widget): - widget.clear() - widget.addItems([str(False), str(True)]) - widget.setCurrentIndex(1 if self.getValue() else 0) - def setModelData(self, widget): - self.setValue(widget.currentIndex() == 1) - -class _PropertyEditorString(_PropertyEditorBase): - def widget(self, parent): - return QtGui.QLineEdit(parent) - def setEditorData(self, widget): - widget.setText(self.getValue()) - def setModelData(self, widget): - self.setValue(widget.text()) - -class _PropertyEditorQuantity(_PropertyEditorBase): - def widget(self, parent): - qsb = FreeCADGui.UiLoader().createWidget('Gui::QuantitySpinBox', parent) - self.editor = PathGui.QuantitySpinBox(qsb, self.obj, self.prop) - return qsb - def setEditorData(self, widget): - self.editor.updateSpinBox() - def setModelData(self, widget): - self.editor.updateProperty() - -_PropertyEditorFactory = { - bool : _PropertyEditorBool, - int : _PropertyEditorInteger, - float : _PropertyEditorFloat, - str : _PropertyEditorString, - FreeCAD.Units.Quantity : _PropertyEditorQuantity, - } - class _Delegate(QtGui.QStyledItemDelegate): '''Handles the creation of an appropriate editing widget for a given property.''' ObjectRole = QtCore.Qt.UserRole + 1 @@ -110,7 +52,7 @@ class _Delegate(QtGui.QStyledItemDelegate): if editor is None: obj = index.data(self.ObjectRole) prp = index.data(self.PropertyRole) - editor = _PropertyEditorFactory[type(getattr(obj, prp))](obj, prp) + editor = PathPropertyEditor.Editor(obj, prp) index.model().setData(index, editor, self.EditorRole) return editor.widget(parent) diff --git a/src/Mod/Path/Tools/Shape/endmill.fcstd b/src/Mod/Path/Tools/Shape/endmill.fcstd index a40e5fbe51..60526286e1 100644 Binary files a/src/Mod/Path/Tools/Shape/endmill.fcstd and b/src/Mod/Path/Tools/Shape/endmill.fcstd differ