Add tool controller support with inplace editing.
This commit is contained in:
@@ -35,7 +35,7 @@ from PySide import QtCore
|
||||
|
||||
if True:
|
||||
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
|
||||
PathLog.trackModule()
|
||||
PathLog.trackModule(PathLog.thisModule())
|
||||
else:
|
||||
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
|
||||
|
||||
@@ -94,6 +94,7 @@ class ObjectJob:
|
||||
self.assignTemplate(obj, template)
|
||||
|
||||
def onDelete(self, obj, arg2=None):
|
||||
PathLog.track(obj, arg2)
|
||||
for tc in obj.ToolController:
|
||||
FreeCAD.ActiveDocument.removeObject(tc.Name)
|
||||
obj.ToolController = []
|
||||
@@ -129,9 +130,9 @@ class ObjectJob:
|
||||
if job.get(JobTemplate.Description):
|
||||
obj.Description = job.get(JobTemplate.Description)
|
||||
for tc in tree.getroot().iter(JobTemplate.ToolController):
|
||||
tcs.append(PathToolController.CommandPathToolController.FromTemplate(tc))
|
||||
tcs.append(PathToolController.FromTemplate(tc))
|
||||
else:
|
||||
tcs.append(PathToolController.CommandPathToolController.Create(obj.Name))
|
||||
tcs.append(PathToolController.Create(obj.Name))
|
||||
PathLog.debug("setting tool controllers (%d)" % len(tcs))
|
||||
obj.ToolController = tcs
|
||||
|
||||
@@ -167,6 +168,14 @@ class ObjectJob:
|
||||
group.append(op)
|
||||
self.obj.Operations.Group = group
|
||||
|
||||
def addToolController(self, tc):
|
||||
group = self.obj.ToolController
|
||||
PathLog.info("addToolController(%s): %s" % (tc.Label, [t.Label for t in group]))
|
||||
if tc.Name not in [str(t.Name) for t in group]:
|
||||
group.append(tc)
|
||||
self.obj.ToolController = group
|
||||
|
||||
|
||||
@classmethod
|
||||
def baseCandidates(cls):
|
||||
'''Answer all objects in the current document which could serve as a Base for a job.'''
|
||||
|
||||
@@ -27,6 +27,7 @@ import FreeCADGui
|
||||
import PathScripts.PathJob as PathJob
|
||||
import PathScripts.PathLog as PathLog
|
||||
import PathScripts.PathToolController as PathToolController
|
||||
import PathScripts.PathToolLibraryManager as PathToolLibraryManager
|
||||
import sys
|
||||
|
||||
from PathScripts.PathPreferences import PathPreferences
|
||||
@@ -86,6 +87,7 @@ class ViewProvider:
|
||||
|
||||
class TaskPanel:
|
||||
DataObject = QtCore.Qt.ItemDataRole.UserRole
|
||||
DataProperty = QtCore.Qt.ItemDataRole.UserRole + 1
|
||||
|
||||
def __init__(self, vobj, deleteOnReject):
|
||||
FreeCAD.ActiveDocument.openTransaction(translate("Path_Job", "Edit Job"))
|
||||
@@ -94,6 +96,9 @@ class TaskPanel:
|
||||
self.deleteOnReject = deleteOnReject
|
||||
self.form = FreeCADGui.PySideUic.loadUi(":/panels/PathEdit.ui")
|
||||
|
||||
self.form.toolControllerList.horizontalHeader().setResizeMode(0, QtGui.QHeaderView.Stretch)
|
||||
self.form.toolControllerList.resizeColumnsToContents()
|
||||
|
||||
currentPostProcessor = self.obj.PostProcessor
|
||||
postProcessors = PathPreferences.allEnabledPostProcessors(['', currentPostProcessor])
|
||||
for post in postProcessors:
|
||||
@@ -168,6 +173,58 @@ class TaskPanel:
|
||||
widget.setCurrentIndex(index)
|
||||
widget.blockSignals(False)
|
||||
|
||||
def updateToolController(self):
|
||||
self.form.toolControllerList.blockSignals(True)
|
||||
self.form.toolControllerList.clearContents()
|
||||
self.form.toolControllerList.setRowCount(0)
|
||||
|
||||
self.form.activeToolController.blockSignals(True)
|
||||
index = self.form.activeToolController.currentIndex()
|
||||
select = None if index == -1 else self.form.activeToolController.itemData(index)
|
||||
self.form.activeToolController.clear()
|
||||
|
||||
for row,tc in enumerate(sorted(self.obj.ToolController, key=lambda tc: tc.Label)):
|
||||
self.form.activeToolController.addItem(tc.Label, tc)
|
||||
if tc == select:
|
||||
index = row
|
||||
|
||||
self.form.toolControllerList.insertRow(row)
|
||||
|
||||
item = QtGui.QTableWidgetItem(tc.Label)
|
||||
item.setData(self.DataObject, tc)
|
||||
item.setData(self.DataProperty, 'Label')
|
||||
self.form.toolControllerList.setItem(row, 0, item)
|
||||
|
||||
item = QtGui.QTableWidgetItem("%d" % tc.ToolNumber)
|
||||
item.setTextAlignment(QtCore.Qt.AlignRight)
|
||||
item.setData(self.DataObject, tc)
|
||||
item.setData(self.DataProperty, 'Number')
|
||||
self.form.toolControllerList.setItem(row, 1, item)
|
||||
|
||||
item = QtGui.QTableWidgetItem("%g" % tc.HorizFeed)
|
||||
item.setTextAlignment(QtCore.Qt.AlignRight)
|
||||
item.setData(self.DataObject, tc)
|
||||
item.setData(self.DataProperty, 'HorizFeed')
|
||||
self.form.toolControllerList.setItem(row, 2, item)
|
||||
|
||||
item = QtGui.QTableWidgetItem("%g" % tc.VertFeed)
|
||||
item.setTextAlignment(QtCore.Qt.AlignRight)
|
||||
item.setData(self.DataObject, tc)
|
||||
item.setData(self.DataProperty, 'VertFeed')
|
||||
self.form.toolControllerList.setItem(row, 3, item)
|
||||
|
||||
item = QtGui.QTableWidgetItem("%s%g" % ('+' if tc.SpindleDir == 'Forward' else '-', tc.SpindleSpeed))
|
||||
item.setTextAlignment(QtCore.Qt.AlignRight)
|
||||
item.setData(self.DataObject, tc)
|
||||
item.setData(self.DataProperty, 'Spindle')
|
||||
self.form.toolControllerList.setItem(row, 4, item)
|
||||
|
||||
if index != -1:
|
||||
self.form.activeToolController.setCurrentIndex(index)
|
||||
|
||||
self.form.activeToolController.blockSignals(False)
|
||||
self.form.toolControllerList.blockSignals(False)
|
||||
|
||||
def setFields(self):
|
||||
'''sets fields in the form to match the object'''
|
||||
|
||||
@@ -194,6 +251,7 @@ class TaskPanel:
|
||||
if baseindex >= 0:
|
||||
self.form.infoModel.setCurrentIndex(baseindex)
|
||||
|
||||
self.updateToolController()
|
||||
|
||||
def setPostProcessorOutputFile(self):
|
||||
filename = QtGui.QFileDialog.getSaveFileName(self.form, translate("Path_Job", "Select Output File"), None, translate("Path_Job", "All Files (*.*)"))
|
||||
@@ -207,14 +265,80 @@ class TaskPanel:
|
||||
else:
|
||||
self.form.operationModify.setEnabled(False)
|
||||
|
||||
def operationDelete(self):
|
||||
for item in self.form.operationsList.selectedItems():
|
||||
def objectDelete(self, widget):
|
||||
for item in widget.selectedItems():
|
||||
obj = item.data(self.DataObject)
|
||||
if obj.ViewObject and hasattr(obj.ViewObject, 'Proxy') and hasattr(obj.ViewObject.Proxy, 'onDelete'):
|
||||
obj.ViewObject.Proxy.onDelete(obj.ViewObject, None)
|
||||
FreeCAD.ActiveDocument.removeObject(obj.Name)
|
||||
self.setFields()
|
||||
|
||||
def operationDelete(self):
|
||||
self.objectDelete(self.form.operationsList)
|
||||
|
||||
def toolControllerSelect(self):
|
||||
def canDeleteTC(tc):
|
||||
# if the TC is referenced anywhere but the job we don't want to delete it
|
||||
return len(tc.InList) == 1
|
||||
|
||||
# if anything is selected it can be edited
|
||||
edit = True if self.form.toolControllerList.selectedItems() else False
|
||||
self.form.toolControllerEdit.setEnabled(edit)
|
||||
|
||||
# can only delete what is selected
|
||||
delete = edit
|
||||
# ... but we want to make sure there's at least one TC left
|
||||
if len(self.obj.ToolController) == len(self.form.toolControllerList.selectedItems()):
|
||||
delete = False
|
||||
# ... also don't want to delete any TCs that are already used
|
||||
if delete:
|
||||
for item in self.form.toolControllerList.selectedItems():
|
||||
if not canDeleteTC(item.data(self.DataObject)):
|
||||
delete = False
|
||||
break
|
||||
self.form.toolControllerDelete.setEnabled(delete)
|
||||
|
||||
def toolControllerEdit(self):
|
||||
pass
|
||||
|
||||
def toolControllerAdd(self):
|
||||
PathToolLibraryManager.CommandToolLibraryEdit().edit(self.obj, self.updateToolController)
|
||||
|
||||
def toolControllerDelete(self):
|
||||
self.objectDelete(self.form.toolControllerList)
|
||||
|
||||
def toolControllerChanged(self, item):
|
||||
tc = item.data(self.DataObject)
|
||||
prop = item.data(self.DataProperty)
|
||||
if 'Label' == prop:
|
||||
tc.Label = item.text()
|
||||
item.setText(tc.Label)
|
||||
elif 'Number' == prop:
|
||||
try:
|
||||
tc.ToolNumber = int(item.text())
|
||||
except:
|
||||
pass
|
||||
item.setText("%d" % tc.ToolNumber)
|
||||
elif 'Spindle' == prop:
|
||||
try:
|
||||
speed = float(item.text())
|
||||
rot = 'Forward'
|
||||
if speed < 0:
|
||||
rot = 'Reverse'
|
||||
speed = -speed
|
||||
tc.SpindleDir = rot
|
||||
tc.SpindleSpeed = speed
|
||||
except:
|
||||
pass
|
||||
item.setText("%s%g" % ('+' if tc.SpindleDir == 'Forward' else '-', tc.SpindleSpeed))
|
||||
else:
|
||||
try:
|
||||
val = FreeCAD.Units.Quantity(item.text())
|
||||
setattr(tc, prop, val)
|
||||
except:
|
||||
pass
|
||||
item.setText("%g" % getattr(tc, prop).Value)
|
||||
|
||||
def setupUi(self):
|
||||
self.setFields()
|
||||
|
||||
@@ -232,7 +356,14 @@ class TaskPanel:
|
||||
self.form.operationsList.indexesMoved.connect(self.getFields)
|
||||
self.form.operationDelete.clicked.connect(self.operationDelete)
|
||||
|
||||
self.form.toolControllerList.itemSelectionChanged.connect(self.toolControllerSelect)
|
||||
self.form.toolControllerList.itemChanged.connect(self.toolControllerChanged)
|
||||
self.form.toolControllerEdit.clicked.connect(self.toolControllerEdit)
|
||||
self.form.toolControllerDelete.clicked.connect(self.toolControllerDelete)
|
||||
self.form.toolControllerAdd.clicked.connect(self.toolControllerAdd)
|
||||
|
||||
self.operationSelect()
|
||||
self.toolControllerSelect()
|
||||
|
||||
def Create(base, template=None):
|
||||
'''Create(base, template) ... creates a job instance for the given base object
|
||||
|
||||
@@ -150,7 +150,7 @@ class ToolController:
|
||||
return obj.Tool
|
||||
|
||||
|
||||
class _ViewProviderToolController:
|
||||
class ViewProvider:
|
||||
|
||||
def __init__(self, vobj):
|
||||
vobj.Proxy = self
|
||||
@@ -203,6 +203,37 @@ class _ViewProviderToolController:
|
||||
# this is executed when the user cancels or terminates edit mode
|
||||
return False
|
||||
|
||||
def Create(name = 'Default Tool', tool=None, toolNumber=1, assignViewProvider=True):
|
||||
PathLog.track(tool, toolNumber)
|
||||
|
||||
obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name)
|
||||
ToolController(obj)
|
||||
if assignViewProvider:
|
||||
ViewProvider(obj.ViewObject)
|
||||
|
||||
if tool is None:
|
||||
tool = Path.Tool()
|
||||
tool.Diameter = 5.0
|
||||
tool.Name = "Default Tool"
|
||||
tool.CuttingEdgeHeight = 15.0
|
||||
tool.ToolType = "EndMill"
|
||||
tool.Material = "HighSpeedSteel"
|
||||
obj.Tool = tool
|
||||
obj.ToolNumber = toolNumber
|
||||
return obj
|
||||
|
||||
def FromTemplate(template, assignViewProvider=True):
|
||||
PathLog.track()
|
||||
|
||||
obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", template.get(ToolControllerTemplate.Label))
|
||||
tc = ToolController(obj)
|
||||
if assignViewProvider:
|
||||
ViewProvider(obj.ViewObject)
|
||||
|
||||
tc.assignTemplate(obj, template)
|
||||
|
||||
return obj
|
||||
|
||||
|
||||
class CommandPathToolController:
|
||||
def GetResources(self):
|
||||
@@ -219,41 +250,7 @@ class CommandPathToolController:
|
||||
|
||||
def Activated(self):
|
||||
PathLog.track()
|
||||
self.Create()
|
||||
|
||||
@staticmethod
|
||||
def Create(assignViewProvider=True, tool=None, toolNumber=1):
|
||||
PathLog.track("tool: {} with toolNumber: {}".format(tool, toolNumber))
|
||||
|
||||
obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", "Default Tool")
|
||||
PathScripts.PathToolController.ToolController(obj)
|
||||
if FreeCAD.GuiUp and assignViewProvider:
|
||||
PathScripts.PathToolController._ViewProviderToolController(obj.ViewObject)
|
||||
|
||||
if tool is None:
|
||||
tool = Path.Tool()
|
||||
tool.Diameter = 5.0
|
||||
tool.Name = "Default Tool"
|
||||
tool.CuttingEdgeHeight = 15.0
|
||||
tool.ToolType = "EndMill"
|
||||
tool.Material = "HighSpeedSteel"
|
||||
obj.Tool = tool
|
||||
obj.ToolNumber = toolNumber
|
||||
return obj
|
||||
|
||||
@staticmethod
|
||||
def FromTemplate(template, assignViewProvider=True):
|
||||
PathLog.track()
|
||||
|
||||
obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", template.get(ToolControllerTemplate.Label))
|
||||
tc = PathScripts.PathToolController.ToolController(obj)
|
||||
if assignViewProvider:
|
||||
PathScripts.PathToolController._ViewProviderToolController(obj.ViewObject)
|
||||
|
||||
tc.assignTemplate(obj, template)
|
||||
|
||||
return obj
|
||||
|
||||
Create()
|
||||
|
||||
class TaskPanel:
|
||||
def __init__(self):
|
||||
|
||||
@@ -335,7 +335,8 @@ class ToolLibraryManager():
|
||||
|
||||
|
||||
class EditorPanel():
|
||||
def __init__(self):
|
||||
|
||||
def __init__(self, job, cb):
|
||||
#self.form = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Path/ToolLibraryEditor.ui")
|
||||
self.form = FreeCADGui.PySideUic.loadUi(":/panels/ToolLibraryEditor.ui")
|
||||
#self.editform = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Path/ToolEdit.ui")
|
||||
@@ -344,6 +345,8 @@ class EditorPanel():
|
||||
|
||||
self.loadTable()
|
||||
self.form.ToolsList.resizeColumnsToContents()
|
||||
self.job = job
|
||||
self.cb = cb
|
||||
|
||||
def accept(self):
|
||||
pass
|
||||
@@ -545,18 +548,18 @@ class EditorPanel():
|
||||
for toolnum in tools:
|
||||
tool = self.TLM.getTool(currList, int(toolnum))
|
||||
PathLog.debug('tool: {}, toolnum: {}'.format(tool, toolnum))
|
||||
for job in FreeCAD.ActiveDocument.findObjects("Path::Feature"):
|
||||
if isinstance(job.Proxy, PathScripts.PathJob.ObjectJob) and job.Label == targetlist:
|
||||
|
||||
label = "T{}: {}".format(toolnum, tool.Name)
|
||||
obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython",label)
|
||||
PathScripts.PathToolController.ToolController(obj)
|
||||
PathScripts.PathToolController._ViewProviderToolController(obj.ViewObject)
|
||||
PathUtils.addToJob(obj, job.Name)
|
||||
FreeCAD.activeDocument().recompute()
|
||||
obj.Tool = tool.copy()
|
||||
obj.ToolNumber = int(toolnum)
|
||||
#obj.recompute()
|
||||
if self.job:
|
||||
label = "T{}: {}".format(toolnum, tool.Name)
|
||||
tc = PathScripts.PathToolController.Create(label, tool=tool, toolNumber=int(toolnum))
|
||||
self.job.Proxy.addToolController(tc)
|
||||
else:
|
||||
for job in FreeCAD.ActiveDocument.findObjects("Path::Feature"):
|
||||
if isinstance(job.Proxy, PathScripts.PathJob.ObjectJob) and job.Label == targetlist:
|
||||
label = "T{}: {}".format(toolnum, tool.Name)
|
||||
tc = PathScripts.PathToolController.Create(label, tool=tool, toolNumber=int(toolnum))
|
||||
job.Proxy.addToolController(tc)
|
||||
if self.cb:
|
||||
self.cb()
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
|
||||
def getStandardButtons(self):
|
||||
@@ -579,8 +582,8 @@ class EditorPanel():
|
||||
self.setFields()
|
||||
|
||||
class CommandToolLibraryEdit():
|
||||
def edit(self):
|
||||
editor = EditorPanel()
|
||||
def edit(self, job=None, cb=None):
|
||||
editor = EditorPanel(job, cb)
|
||||
editor.setupUi()
|
||||
|
||||
r = editor.form.exec_()
|
||||
|
||||
Reference in New Issue
Block a user