diff --git a/src/Mod/Path/Gui/Resources/panels/ToolBitEditor.ui b/src/Mod/Path/Gui/Resources/panels/ToolBitEditor.ui index 5ed0208067..d77a523a12 100644 --- a/src/Mod/Path/Gui/Resources/panels/ToolBitEditor.ui +++ b/src/Mod/Path/Gui/Resources/panels/ToolBitEditor.ui @@ -13,168 +13,214 @@ Tool Bit Attributes - - - + + + 0 0 - - Tool Bit + + 0 - - - - - Name - - - - - - - <html><head/><body><p>Display name of the Tool Bit (initial value taken from the shape file).</p></body></html> - - - 50 - - - Display Name - - - - - - - Shape File - - - - - - - - 0 - 0 - - - - - 0 + + + Shape + + + + + + + 0 + 0 + - - 0 + + Tool Bit - - 0 + + + + + Name + + + + + + + <html><head/><body><p>Display name of the Tool Bit (initial value taken from the shape file).</p></body></html> + + + 50 + + + Display Name + + + + + + + Shape File + + + + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + <html><head/><body><p>The file which defines the type and shape of the Tool Bit.</p></body></html> + + + path + + + + + + + <html><head/><body><p>Change file defining type and shape of Tool Bit.</p></body></html> + + + ... + + + + + + + + + + + + + Parameter - - 0 + + + QFormLayout::AllNonFixedFieldsGrow + + + + + Point/Tip Angle + + + + + + + 0 ° + + + ° + + + + + + + Cutting Edge Height + + + + + + + 0 mm + + + mm + + + + + + + + + + + 210 + 297 + - - - - <html><head/><body><p>The file which defines the type and shape of the Tool Bit.</p></body></html> - - - path - - - - - - - <html><head/><body><p>Change file defining type and shape of Tool Bit.</p></body></html> - - - ... - - - - - - - + + Image + + + Qt::AlignCenter + + + + + + + Qt::Vertical + + + + 20 + 277 + + + + + + + + + Attributes + + + + + + + 0 + 2 + + + + + 0 + 300 + + + + QAbstractItemView::AllEditTriggers + + + + + - - - - Parameter - - - - QFormLayout::AllNonFixedFieldsGrow - - - - - Point/Tip Angle - - - - - - - 0 ° - - - ° - - - - - - - Cutting Edge Height - - - - - - - 0 mm - - - mm - - - - - - - - - - - 210 - 297 - - - - Image - - - Qt::AlignCenter - - - - - - - Qt::Vertical - - - - 20 - 277 - - - - @@ -184,13 +230,6 @@
Gui/InputField.h
- - toolName - toolCuttingEdgeAngle - toolCuttingEdgeHeight - shapePath - shapeSet - diff --git a/src/Mod/Path/PathScripts/PathToolBit.py b/src/Mod/Path/PathScripts/PathToolBit.py index 0445feabab..97176b86cd 100644 --- a/src/Mod/Path/PathScripts/PathToolBit.py +++ b/src/Mod/Path/PathScripts/PathToolBit.py @@ -47,8 +47,8 @@ PropertyGroupShape = 'Shape' _DebugFindTool = False -PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule()) -PathLog.trackModule() +PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule()) +#PathLog.trackModule() def translate(context, text, disambig=None): @@ -294,17 +294,22 @@ class ToolBit(object): self._copyBitShape(obj) def toolShapeProperties(self, obj): - '''toolShapeProperties(obj) ... return all properties defining the geometry''' + '''toolShapeProperties(obj) ... return all properties defining it's shape''' return sorted([prop for prop in obj.BitPropertyNames if obj.getGroupOfProperty(prop) == PropertyGroupShape]) + def toolAdditionalProperties(self, obj): + '''toolShapeProperties(obj) ... return all properties unrelated to it's shape''' + return sorted([prop for prop in obj.BitPropertyNames if obj.getGroupOfProperty(prop) != PropertyGroupShape]) + def toolGroupsAndProperties(self, obj, includeShape=True): '''toolGroupsAndProperties(obj) ... returns a dictionary of group names with a list of property names.''' category = {} for prop in obj.BitPropertyNames: group = obj.getGroupOfProperty(prop) - properties = category.get(group, []) - properties.append(prop) - category[group] = properties + if includeShape or group != PropertyGroupShape: + properties = category.get(group, []) + properties.append(prop) + category[group] = properties return category def getBitThumbnail(self, obj): diff --git a/src/Mod/Path/PathScripts/PathToolBitEdit.py b/src/Mod/Path/PathScripts/PathToolBitEdit.py index 5ced9249aa..26ccd068d5 100644 --- a/src/Mod/Path/PathScripts/PathToolBitEdit.py +++ b/src/Mod/Path/PathScripts/PathToolBitEdit.py @@ -20,11 +20,13 @@ # * * # *************************************************************************** +import FreeCAD import FreeCADGui import PathScripts.PathGui as PathGui import PathScripts.PathLog as PathLog import PathScripts.PathPreferences as PathPreferences import PathScripts.PathToolBit as PathToolBit +import PathScripts.PathUtil as PathUtil import os import re @@ -38,6 +40,90 @@ 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 + PropertyRole = QtCore.Qt.UserRole + 2 + EditorRole = QtCore.Qt.UserRole + 3 + + def createEditor(self, parent, option, index): + editor = index.data(self.EditorRole) + if editor is None: + obj = index.data(self.ObjectRole) + prp = index.data(self.PropertyRole) + editor = _PropertyEditorFactory[type(getattr(obj, prp))](obj, prp) + index.model().setData(index, editor, self.EditorRole) + return editor.widget(parent) + + def setEditorData(self, widget, index): + # called to update the widget with the current data + index.data(self.EditorRole).setEditorData(widget) + + def setModelData(self, widget, model, index): + # called to update the model with the data from the widget + editor = index.data(self.EditorRole) + editor.setModelData(widget) + index.model().setData(index, PathUtil.getPropertyValueString(editor.obj, editor.prop), QtCore.Qt.DisplayRole) + class ToolBitEditor(object): '''UI and controller for editing a ToolBit. @@ -69,6 +155,7 @@ class ToolBitEditor(object): self.widgets = [] self.setupTool(self.tool) + self.setupAttributes(self.tool) def setupTool(self, tool): PathLog.track() @@ -120,6 +207,39 @@ class ToolBitEditor(object): else: self.form.image.setPixmap(QtGui.QPixmap()) + def setupAttributes(self, tool): + PathLog.track() + + self.delegate = _Delegate(self.form.attrTree) + self.model = QtGui.QStandardItemModel(self.form.attrTree) + self.model.setHorizontalHeaderLabels(['Property', 'Value']) + + attributes = tool.Proxy.toolGroupsAndProperties(tool, False) + for name in attributes: + group = QtGui.QStandardItem() + group.setData(name, QtCore.Qt.EditRole) + group.setEditable(False) + for prop in attributes[name]: + label = QtGui.QStandardItem() + label.setData(prop, QtCore.Qt.EditRole) + label.setEditable(False) + + value = QtGui.QStandardItem() + value.setData(PathUtil.getPropertyValueString(tool, prop), QtCore.Qt.DisplayRole) + value.setData(tool, _Delegate.ObjectRole) + value.setData(prop, _Delegate.PropertyRole) + + group.appendRow([label, value]) + self.model.appendRow(group) + + + self.form.attrTree.setModel(self.model) + self.form.attrTree.setItemDelegateForColumn(1, self.delegate) + self.form.attrTree.expandAll() + self.form.attrTree.resizeColumnToContents(0) + self.form.attrTree.resizeColumnToContents(1) + #self.form.attrTree.collapseAll() + def accept(self): PathLog.track() self.refresh()