diff --git a/src/Mod/Path/CMakeLists.txt b/src/Mod/Path/CMakeLists.txt index 84a17bf39a..5a99e4aa09 100644 --- a/src/Mod/Path/CMakeLists.txt +++ b/src/Mod/Path/CMakeLists.txt @@ -89,6 +89,7 @@ SET(PathScripts_SRCS PathScripts/PathSanity.py PathScripts/PathSelection.py PathScripts/PathSetupSheet.py + PathScripts/PathSetupSheetGui.py PathScripts/PathSimpleCopy.py PathScripts/PathStock.py PathScripts/PathStop.py diff --git a/src/Mod/Path/Gui/Resources/Path.qrc b/src/Mod/Path/Gui/Resources/Path.qrc index c35656dbac..b16080f099 100644 --- a/src/Mod/Path/Gui/Resources/Path.qrc +++ b/src/Mod/Path/Gui/Resources/Path.qrc @@ -90,6 +90,7 @@ panels/PageOpSurfaceEdit.ui panels/PathEdit.ui panels/PointEdit.ui + panels/SetupGlobal.ui panels/ToolEditor.ui panels/ToolLibraryEditor.ui panels/TaskPathSimulator.ui diff --git a/src/Mod/Path/Gui/Resources/panels/SetupGlobal.ui b/src/Mod/Path/Gui/Resources/panels/SetupGlobal.ui new file mode 100644 index 0000000000..49ed83717f --- /dev/null +++ b/src/Mod/Path/Gui/Resources/panels/SetupGlobal.ui @@ -0,0 +1,246 @@ + + + Form + + + + 0 + 0 + 642 + 721 + + + + Setup Global + + + + + + 0 + + + + Operation + + + + + + Depths + + + + + + Start Depth + + + + + + + <html><head/><body><p>Expression set as the StartDepth of a newly created operation.</p><p><br/></p><p>Default: OpStartDepth</p></body></html> + + + + + + + Final Depth + + + + + + + <html><head/><body><p>Expression set as the FinalDepth for a newly created operation.</p><p><br/></p><p>Default: OpFinalDepth</p></body></html> + + + + + + + Step Down + + + + + + + <html><head/><body><p>Expression set as the StepDown of a newly created operation.</p><p><br/></p><p>Default: OpToolDiameter</p></body></html> + + + + + + + + + + Heights + + + + + + Safe + + + + + + + Clearance + + + + + + + <html><head/><body><p>Expression set as SafeHeight for new operations.</p><p><br/></p><p>Default: &quot;OpStockZMax+SetupSheet.SafeHeightOffset&quot;</p></body></html> + + + + + + + <html><head/><body><p>Expression set as ClearanceHeight for new operations.</p><p><br/></p><p>Default: &quot;OpStockZMax+SetupSheet.ClearanceHeightOffset&quot;</p></body></html> + + + + + + + <html><head/><body><p>ClearanceHeightOffset - can be used by expressions to set the default ClearanceHeight for new operations.</p><p><br/></p><p>Default: &quot;3 mm&quot;</p></body></html> + + + + + + + Offset + + + Qt::AlignCenter + + + + + + + Expression + + + Qt::AlignCenter + + + + + + + <html><head/><body><p>SafeHeightOffset can be for expressions to set the SafeHeight for new operations.</p><p><br/></p><p>Default: &quot;5 mm&quot;</p></body></html> + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + Tool Controller + + + + + + Rapid Speeds + + + + + + Horizontal + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Rapid horizontal speed assigned as HorizRapid to new ToolController.</p></body></html> + + + + + + + Vertical + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Rapid vertical speed assigne to VertRapid of new ToolController.</p></body></html> + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + Gui::QuantitySpinBox + QDoubleSpinBox +
gui_quantityspinbox.h
+
+
+ + +
diff --git a/src/Mod/Path/InitGui.py b/src/Mod/Path/InitGui.py index 1e01a6c651..dd6363b304 100644 --- a/src/Mod/Path/InitGui.py +++ b/src/Mod/Path/InitGui.py @@ -95,6 +95,7 @@ class PathWorkbench (Workbench): from PathScripts import PathProfileEdgesGui from PathScripts import PathProfileFacesGui from PathScripts import PathSanity + from PathScripts import PathSetupSheetGui from PathScripts import PathSimpleCopy from PathScripts import PathStop from PathScripts import PathSurfaceGui diff --git a/src/Mod/Path/PathScripts/PathIconViewProvider.py b/src/Mod/Path/PathScripts/PathIconViewProvider.py index a224bc2d7c..88713a7096 100644 --- a/src/Mod/Path/PathScripts/PathIconViewProvider.py +++ b/src/Mod/Path/PathScripts/PathIconViewProvider.py @@ -22,6 +22,8 @@ # * * # *************************************************************************** +import PathScripts.PathLog as PathLog +import PathScripts.PathUtil as PathUtil import importlib __title__ = "Path Icon ViewProvider" @@ -29,6 +31,12 @@ __author__ = "sliptonic (Brad Collette)" __url__ = "http://www.freecadweb.org" __doc__ = "ViewProvider who's main and only task is to assign an icon." +if False: + PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule()) + PathLog.trackModule(PathLog.thisModule()) +else: + PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule()) + class ViewProvider(object): '''Generic view provider to assign an icon.''' @@ -72,3 +80,25 @@ class ViewProvider(object): def unsetEdit(self, arg1, arg2): self._onEditCallback(False) +_factory = {} + +def Attach(vobj, name): + '''Attach(vobj, name) ... attach the appropriate view provider to the view object. + If no view provider was registered for the given name a default IconViewProvider is created.''' + + PathLog.track(name) + global _factory + for key,value in PathUtil.keyValueIter(_factory): + if key == name: + return value(vobj, name) + PathLog.track(name, 'PathIconViewProvider') + return ViewProvider(vobj, name) + +def RegisterViewProvider(name, provider): + '''RegisterViewProvider(name, provider) ... if an IconViewProvider is created for an object with the given name + an instance of provider is used instead.''' + + PathLog.track(name) + global _factory + _factory[name] = provider + diff --git a/src/Mod/Path/PathScripts/PathJob.py b/src/Mod/Path/PathScripts/PathJob.py index de9bf09803..cb407e0f54 100644 --- a/src/Mod/Path/PathScripts/PathJob.py +++ b/src/Mod/Path/PathScripts/PathJob.py @@ -83,7 +83,7 @@ def createResourceClone(obj, orig, name, icon): clone.addProperty('App::PropertyString', 'PathResource') clone.PathResource = name if clone.ViewObject: - PathIconViewProvider.ViewProvider(clone.ViewObject, icon) + PathIconViewProvider.Attach(clone.ViewObject, icon) clone.ViewObject.Visibility = False obj.Document.recompute() # necessary to create the clone shape return clone @@ -144,7 +144,7 @@ class ObjectJob: obj.addProperty('App::PropertyLink', 'SetupSheet', 'Base', QtCore.QT_TRANSLATE_NOOP('PathJob', 'SetupSheet holding the settings for this job')) obj.SetupSheet = PathSetupSheet.Create() if obj.SetupSheet.ViewObject: - PathIconViewProvider.ViewProvider(obj.SetupSheet.ViewObject, 'SetupSheet') + PathIconViewProvider.Attach(obj.SetupSheet.ViewObject, 'SetupSheet') self.setupSheet = obj.SetupSheet.Proxy def onDelete(self, obj, arg2=None): diff --git a/src/Mod/Path/PathScripts/PathJobGui.py b/src/Mod/Path/PathScripts/PathJobGui.py index 4b67900da4..ddc0244cc1 100644 --- a/src/Mod/Path/PathScripts/PathJobGui.py +++ b/src/Mod/Path/PathScripts/PathJobGui.py @@ -38,6 +38,7 @@ import PathScripts.PathUtil as PathUtil import PathScripts.PathUtils as PathUtils import math import sys +import traceback from PySide import QtCore, QtGui from pivy import coin @@ -1032,7 +1033,8 @@ def Create(base, template=None): obj.Document.recompute() obj.ViewObject.Proxy.editObject(obj.Stock) return obj - except: + except Exception as exc: PathLog.error(sys.exc_info()) + #traceback.print_exc(exc) FreeCAD.ActiveDocument.abortTransaction() diff --git a/src/Mod/Path/PathScripts/PathSetupSheet.py b/src/Mod/Path/PathScripts/PathSetupSheet.py index 6f5f59210c..a1df2d88a6 100644 --- a/src/Mod/Path/PathScripts/PathSetupSheet.py +++ b/src/Mod/Path/PathScripts/PathSetupSheet.py @@ -207,7 +207,7 @@ class SetupSheet: return _traverseTemplateAttributes(attrs, self.decodeAttributeString) -def Create(name='SetupSheet'): +def Create(name = 'SetupSheet'): obj = FreeCAD.ActiveDocument.addObject('App::FeaturePython', name) proxy = SetupSheet(obj) return obj diff --git a/src/Mod/Path/PathScripts/PathSetupSheetGui.py b/src/Mod/Path/PathScripts/PathSetupSheetGui.py new file mode 100644 index 0000000000..e2aaee9af5 --- /dev/null +++ b/src/Mod/Path/PathScripts/PathSetupSheetGui.py @@ -0,0 +1,178 @@ +# -*- coding: utf-8 -*- + +# *************************************************************************** +# * * +# * Copyright (c) 2018 sliptonic * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +import Draft +import DraftVecUtils +import FreeCAD +import FreeCADGui +import PathScripts.PathGui as PathGui +import PathScripts.PathLog as PathLog +import PathScripts.PathIconViewProvider as PathIconViewProvider + +from PySide import QtCore, QtGui + +# Qt tanslation handling +def translate(context, text, disambig=None): + return QtCore.QCoreApplication.translate(context, text, disambig) + +if True: + PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule()) + PathLog.trackModule(PathLog.thisModule()) +else: + PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule()) + +class ViewProvider: + + def __init__(self, vobj, name): + PathLog.track(name) + vobj.Proxy = self + self.icon = name + mode = 2 + #vobj.setEditorMode('BoundingBox', mode) + #vobj.setEditorMode('DisplayMode', mode) + #vobj.setEditorMode('Selectable', mode) + #vobj.setEditorMode('ShapeColor', mode) + #vobj.setEditorMode('Transparency', mode) + + def attach(self, vobj): + PathLog.track() + self.vobj = vobj + self.obj = vobj.Object + + def getIcon(self): + PathLog.track() + return ":/icons/Path-SetupSheet.svg" + + def __getstate__(self): + return None + + def __setstate__(self, state): + return None + + def getDisplayMode(self, mode): + return 'Default' + + def setEdit(self, vobj, mode=0): + PathLog.track() + taskPanel = TaskPanel(vobj) + FreeCADGui.Control.closeDialog() + FreeCADGui.Control.showDialog(taskPanel) + taskPanel.setupUi() + return True + + def unsetEdit(self, vobj, mode): + FreeCADGui.Control.closeDialog() + return + + def claimChildren(self): + return [] + + def doubleClicked(self, vobj): + self.setEdit(vobj) + +class TaskPanel: + DataIds = QtCore.Qt.ItemDataRole.UserRole + DataKey = QtCore.Qt.ItemDataRole.UserRole + 1 + + def __init__(self, vobj): + self.vobj = vobj + self.obj = vobj.Object + PathLog.track(self.obj.Label) + self.form = FreeCADGui.PySideUic.loadUi(":/panels/SetupGlobal.ui") + FreeCAD.ActiveDocument.openTransaction(translate("Path_SetupSheet", "Edit SetupSheet")) + + def reject(self): + FreeCAD.ActiveDocument.abortTransaction() + FreeCADGui.Control.closeDialog() + FreeCAD.ActiveDocument.recompute() + + def accept(self): + self.getFields() + FreeCAD.ActiveDocument.commitTransaction() + FreeCADGui.ActiveDocument.resetEdit() + FreeCADGui.Control.closeDialog() + FreeCAD.ActiveDocument.recompute() + #FreeCADGui.Selection.removeObserver(self.s) + #FreeCAD.ActiveDocument.recompute() + + def getFields(self): + def updateExpression(name, widget): + value = str(widget.text()) + val = PathGui.getProperty(self.obj, name) + if val != value: + PathGui.setProperty(self.obj, name, value) + + updateExpression('StartDepthExpression', self.form.startDepthExpr) + updateExpression('FinalDepthExpression', self.form.finalDepthExpr) + updateExpression('StepDownExpression', self.form.stepDownExpr) + updateExpression('ClearanceHeightExpression', self.form.clearanceHeightExpr) + updateExpression('SafeHeightExpression', self.form.safeHeightExpr) + self.clearanceHeightOffs.updateProperty() + self.safeHeightOffs.updateProperty() + self.rapidVertical.updateProperty() + self.rapidHorizontal.updateProperty() + + def updateUI(self): + self.form.startDepthExpr.setText( self.obj.StartDepthExpression) + self.form.finalDepthExpr.setText( self.obj.FinalDepthExpression) + self.form.stepDownExpr.setText( self.obj.StepDownExpression) + self.form.clearanceHeightExpr.setText( self.obj.ClearanceHeightExpression) + self.form.safeHeightExpr.setText( self.obj.SafeHeightExpression) + self.clearanceHeightOffs.updateSpinBox() + self.safeHeightOffs.updateSpinBox() + self.rapidVertical.updateSpinBox() + self.rapidHorizontal.updateSpinBox() + + def updateModel(self): + self.getFields() + self.updateUI() + FreeCAD.ActiveDocument.recompute() + + def setupCombo(self, combo, text, items): + if items and len(items) > 0: + for i in range(combo.count(), -1, -1): + combo.removeItem(i) + combo.addItems(items) + index = combo.findText(text, QtCore.Qt.MatchFixedString) + if index >= 0: + combo.setCurrentIndex(index) + + def setFields(self): + self.updateUI() + + def setupUi(self): + self.clearanceHeightOffs = PathGui.QuantitySpinBox(self.form.clearanceHeightOffs, self.obj, 'ClearanceHeightOffset') + self.safeHeightOffs = PathGui.QuantitySpinBox(self.form.safeHeightOffs, self.obj, 'SafeHeightOffset') + self.rapidHorizontal = PathGui.QuantitySpinBox(self.form.rapidHorizontal, self.obj, 'HorizRapid') + self.rapidVertical = PathGui.QuantitySpinBox(self.form.rapidVertical, self.obj, 'VertRapid') + self.setFields() + +def Create(name = 'SetupSheet'): + '''Create(name = 'SetupSheet') ... creates a new setup sheet''' + FreeCAD.ActiveDocument.openTransaction(translate("Path_Job", "Create Job")) + ssheet = SetupSheet.Create(name) + PathIconViewProvider.Attach(ssheet) + return ssheet + +PathIconViewProvider.RegisterViewProvider('SetupSheet', ViewProvider)