Toolbit black
This commit is contained in:
@@ -32,24 +32,26 @@ import zipfile
|
||||
|
||||
# lazily loaded modules
|
||||
from lazy_loader.lazy_loader import LazyLoader
|
||||
Part = LazyLoader('Part', globals(), 'Part')
|
||||
|
||||
Part = LazyLoader("Part", globals(), "Part")
|
||||
|
||||
__title__ = "Tool bits."
|
||||
__author__ = "sliptonic (Brad Collette)"
|
||||
__url__ = "https://www.freecadweb.org"
|
||||
__doc__ = "Class to deal with and represent a tool bit."
|
||||
|
||||
PropertyGroupShape = 'Shape'
|
||||
PropertyGroupShape = "Shape"
|
||||
|
||||
_DebugFindTool = False
|
||||
|
||||
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
|
||||
#PathLog.trackModule()
|
||||
# PathLog.trackModule()
|
||||
|
||||
|
||||
def translate(context, text, disambig=None):
|
||||
return PySide.QtCore.QCoreApplication.translate(context, text, disambig)
|
||||
|
||||
|
||||
def _findToolFile(name, containerFile, typ):
|
||||
PathLog.track(name)
|
||||
if os.path.exists(name): # absolute reference
|
||||
@@ -74,7 +76,6 @@ def _findToolFile(name, containerFile, typ):
|
||||
return (True, fullPath)
|
||||
return (False, None)
|
||||
|
||||
|
||||
for p in paths:
|
||||
found, path = _findFile(p, name)
|
||||
if found:
|
||||
@@ -83,26 +84,26 @@ def _findToolFile(name, containerFile, typ):
|
||||
|
||||
|
||||
def findToolShape(name, path=None):
|
||||
'''findToolShape(name, path) ... search for name, if relative path look in path'''
|
||||
"""findToolShape(name, path) ... search for name, if relative path look in path"""
|
||||
PathLog.track(name, path)
|
||||
return _findToolFile(name, path, 'Shape')
|
||||
return _findToolFile(name, path, "Shape")
|
||||
|
||||
|
||||
def findToolBit(name, path=None):
|
||||
'''findToolBit(name, path) ... search for name, if relative path look in path'''
|
||||
"""findToolBit(name, path) ... search for name, if relative path look in path"""
|
||||
PathLog.track(name, path)
|
||||
if name.endswith('.fctb'):
|
||||
return _findToolFile(name, path, 'Bit')
|
||||
return _findToolFile("{}.fctb".format(name), path, 'Bit')
|
||||
if name.endswith(".fctb"):
|
||||
return _findToolFile(name, path, "Bit")
|
||||
return _findToolFile("{}.fctb".format(name), path, "Bit")
|
||||
|
||||
|
||||
# Only used in ToolBit unit test module: TestPathToolBit.py
|
||||
def findToolLibrary(name, path=None):
|
||||
'''findToolLibrary(name, path) ... search for name, if relative path look in path'''
|
||||
"""findToolLibrary(name, path) ... search for name, if relative path look in path"""
|
||||
PathLog.track(name, path)
|
||||
if name.endswith('.fctl'):
|
||||
return _findToolFile(name, path, 'Library')
|
||||
return _findToolFile("{}.fctl".format(name), path, 'Library')
|
||||
if name.endswith(".fctl"):
|
||||
return _findToolFile(name, path, "Library")
|
||||
return _findToolFile("{}.fctl".format(name), path, "Library")
|
||||
|
||||
|
||||
def _findRelativePath(path, typ):
|
||||
@@ -110,7 +111,7 @@ def _findRelativePath(path, typ):
|
||||
relative = path
|
||||
for p in PathPreferences.searchPathsTool(typ):
|
||||
if path.startswith(p):
|
||||
p = path[len(p):]
|
||||
p = path[len(p) :]
|
||||
if os.path.sep == p[0]:
|
||||
p = p[1:]
|
||||
if len(p) < len(relative):
|
||||
@@ -130,23 +131,48 @@ def findRelativePathTool(path):
|
||||
|
||||
|
||||
def findRelativePathLibrary(path):
|
||||
return _findRelativePath(path, 'Library')
|
||||
return _findRelativePath(path, "Library")
|
||||
|
||||
|
||||
class ToolBit(object):
|
||||
|
||||
def __init__(self, obj, shapeFile, path=None):
|
||||
PathLog.track(obj.Label, shapeFile, path)
|
||||
self.obj = obj
|
||||
obj.addProperty('App::PropertyFile', 'BitShape', 'Base', translate('PathToolBit', 'Shape for bit shape'))
|
||||
obj.addProperty('App::PropertyLink', 'BitBody', 'Base', translate('PathToolBit', 'The parametrized body representing the tool bit'))
|
||||
obj.addProperty('App::PropertyFile', 'File', 'Base', translate('PathToolBit', 'The file of the tool'))
|
||||
obj.addProperty('App::PropertyString', 'ShapeName', 'Base', translate('PathToolBit', 'The name of the shape file'))
|
||||
obj.addProperty('App::PropertyStringList', 'BitPropertyNames', 'Base', translate('PathToolBit', 'List of all properties inherited from the bit'))
|
||||
obj.addProperty(
|
||||
"App::PropertyFile",
|
||||
"BitShape",
|
||||
"Base",
|
||||
translate("PathToolBit", "Shape for bit shape"),
|
||||
)
|
||||
obj.addProperty(
|
||||
"App::PropertyLink",
|
||||
"BitBody",
|
||||
"Base",
|
||||
translate("PathToolBit", "The parametrized body representing the tool bit"),
|
||||
)
|
||||
obj.addProperty(
|
||||
"App::PropertyFile",
|
||||
"File",
|
||||
"Base",
|
||||
translate("PathToolBit", "The file of the tool"),
|
||||
)
|
||||
obj.addProperty(
|
||||
"App::PropertyString",
|
||||
"ShapeName",
|
||||
"Base",
|
||||
translate("PathToolBit", "The name of the shape file"),
|
||||
)
|
||||
obj.addProperty(
|
||||
"App::PropertyStringList",
|
||||
"BitPropertyNames",
|
||||
"Base",
|
||||
translate("PathToolBit", "List of all properties inherited from the bit"),
|
||||
)
|
||||
|
||||
if path:
|
||||
obj.File = path
|
||||
if shapeFile is None:
|
||||
obj.BitShape = 'endmill.fcstd'
|
||||
obj.BitShape = "endmill.fcstd"
|
||||
self._setupBitShape(obj)
|
||||
self.unloadBitBody(obj)
|
||||
else:
|
||||
@@ -159,7 +185,7 @@ class ToolBit(object):
|
||||
|
||||
def __setstate__(self, state):
|
||||
for obj in FreeCAD.ActiveDocument.Objects:
|
||||
if hasattr(obj, 'Proxy') and obj.Proxy == self:
|
||||
if hasattr(obj, "Proxy") and obj.Proxy == self:
|
||||
self.obj = obj
|
||||
break
|
||||
return None
|
||||
@@ -168,14 +194,21 @@ class ToolBit(object):
|
||||
# when files are shared it is essential to be able to change/set the shape file,
|
||||
# otherwise the file is hard to use
|
||||
# obj.setEditorMode('BitShape', 1)
|
||||
obj.setEditorMode('BitBody', 2)
|
||||
obj.setEditorMode('File', 1)
|
||||
obj.setEditorMode('Shape', 2)
|
||||
if not hasattr(obj, 'BitPropertyNames'):
|
||||
obj.addProperty('App::PropertyStringList', 'BitPropertyNames', 'Base', translate('PathToolBit', 'List of all properties inherited from the bit'))
|
||||
obj.setEditorMode("BitBody", 2)
|
||||
obj.setEditorMode("File", 1)
|
||||
obj.setEditorMode("Shape", 2)
|
||||
if not hasattr(obj, "BitPropertyNames"):
|
||||
obj.addProperty(
|
||||
"App::PropertyStringList",
|
||||
"BitPropertyNames",
|
||||
"Base",
|
||||
translate(
|
||||
"PathToolBit", "List of all properties inherited from the bit"
|
||||
),
|
||||
)
|
||||
propNames = []
|
||||
for prop in obj.PropertiesList:
|
||||
if obj.getGroupOfProperty(prop) == 'Bit':
|
||||
if obj.getGroupOfProperty(prop) == "Bit":
|
||||
val = obj.getPropertyByName(prop)
|
||||
typ = obj.getTypeIdOfProperty(prop)
|
||||
dsc = obj.getDocumentationOfProperty(prop)
|
||||
@@ -185,10 +218,10 @@ class ToolBit(object):
|
||||
|
||||
PathUtil.setProperty(obj, prop, val)
|
||||
propNames.append(prop)
|
||||
elif obj.getGroupOfProperty(prop) == 'Attribute':
|
||||
elif obj.getGroupOfProperty(prop) == "Attribute":
|
||||
propNames.append(prop)
|
||||
obj.BitPropertyNames = propNames
|
||||
obj.setEditorMode('BitPropertyNames', 2)
|
||||
obj.setEditorMode("BitPropertyNames", 2)
|
||||
|
||||
for prop in obj.BitPropertyNames:
|
||||
if obj.getGroupOfProperty(prop) == PropertyGroupShape:
|
||||
@@ -202,7 +235,7 @@ class ToolBit(object):
|
||||
|
||||
def onChanged(self, obj, prop):
|
||||
PathLog.track(obj.Label, prop)
|
||||
if prop == 'BitShape' and 'Restore' not in obj.State:
|
||||
if prop == "BitShape" and "Restore" not in obj.State:
|
||||
self._setupBitShape(obj)
|
||||
|
||||
def onDelete(self, obj, arg2=None):
|
||||
@@ -212,7 +245,11 @@ class ToolBit(object):
|
||||
|
||||
def _updateBitShape(self, obj, properties=None):
|
||||
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 attributes in [
|
||||
o
|
||||
for o in obj.BitBody.Group
|
||||
if hasattr(o, "Proxy") and hasattr(o.Proxy, "getCustomProperties")
|
||||
]:
|
||||
for prop in attributes.Proxy.getCustomProperties():
|
||||
# the property might not exist in our local object (new attribute in shape)
|
||||
# for such attributes we just keep the default
|
||||
@@ -291,7 +328,7 @@ class ToolBit(object):
|
||||
dsc = orig.getDocumentationOfProperty(prop)
|
||||
|
||||
obj.addProperty(typ, prop, grp, dsc)
|
||||
if 'App::PropertyEnumeration' == typ:
|
||||
if "App::PropertyEnumeration" == typ:
|
||||
setattr(obj, prop, orig.getEnumerationsOfProperty(prop))
|
||||
|
||||
obj.setEditorMode(prop, 1)
|
||||
@@ -315,16 +352,27 @@ class ToolBit(object):
|
||||
if bitBody.ViewObject:
|
||||
bitBody.ViewObject.Visibility = False
|
||||
|
||||
PathLog.debug("bitBody.{} ({}): {}".format(bitBody.Label, bitBody.Name, type(bitBody)))
|
||||
PathLog.debug(
|
||||
"bitBody.{} ({}): {}".format(bitBody.Label, bitBody.Name, type(bitBody))
|
||||
)
|
||||
|
||||
propNames = []
|
||||
for attributes in [o for o in bitBody.Group if PathPropertyBag.IsPropertyBag(o)]:
|
||||
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():
|
||||
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)))
|
||||
PathLog.error(
|
||||
translate(
|
||||
"PathToolBit",
|
||||
"Did not find a PropertyBag in {} - not a ToolBit shape?".format(
|
||||
docName
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
# has to happen last because it could trigger op.execute evaluations
|
||||
obj.BitPropertyNames = propNames
|
||||
@@ -332,20 +380,32 @@ class ToolBit(object):
|
||||
self._copyBitShape(obj)
|
||||
|
||||
def toolShapeProperties(self, obj):
|
||||
'''toolShapeProperties(obj) ... return all properties defining it's shape'''
|
||||
return sorted([prop for prop in obj.BitPropertyNames if obj.getGroupOfProperty(prop) == PropertyGroupShape])
|
||||
"""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])
|
||||
"""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.'''
|
||||
"""toolGroupsAndProperties(obj) ... returns a dictionary of group names with a list of property names."""
|
||||
category = {}
|
||||
for prop in obj.BitPropertyNames:
|
||||
group = obj.getGroupOfProperty(prop)
|
||||
if includeShape or group != PropertyGroupShape:
|
||||
properties = category.get(group, [])
|
||||
properties = category.get(group, [])
|
||||
properties.append(prop)
|
||||
category[group] = properties
|
||||
return category
|
||||
@@ -354,10 +414,10 @@ class ToolBit(object):
|
||||
if obj.BitShape:
|
||||
path = findToolShape(obj.BitShape)
|
||||
if path:
|
||||
with open(path, 'rb') as fd:
|
||||
with open(path, "rb") as fd:
|
||||
try:
|
||||
zf = zipfile.ZipFile(fd)
|
||||
pf = zf.open('thumbnails/Thumbnail.png', 'r')
|
||||
pf = zf.open("thumbnails/Thumbnail.png", "r")
|
||||
data = pf.read()
|
||||
pf.close()
|
||||
return data
|
||||
@@ -368,55 +428,58 @@ class ToolBit(object):
|
||||
def saveToFile(self, obj, path, setFile=True):
|
||||
PathLog.track(path)
|
||||
try:
|
||||
with open(path, 'w') as fp:
|
||||
json.dump(self.templateAttrs(obj), fp, indent=' ')
|
||||
with open(path, "w") as fp:
|
||||
json.dump(self.templateAttrs(obj), fp, indent=" ")
|
||||
if setFile:
|
||||
obj.File = path
|
||||
return True
|
||||
except (OSError, IOError) as e:
|
||||
PathLog.error("Could not save tool {} to {} ({})".format(obj.Label, path, e))
|
||||
PathLog.error(
|
||||
"Could not save tool {} to {} ({})".format(obj.Label, path, e)
|
||||
)
|
||||
raise
|
||||
|
||||
def templateAttrs(self, obj):
|
||||
attrs = {}
|
||||
attrs['version'] = 2 # Path.Tool is version 1
|
||||
attrs['name'] = obj.Label
|
||||
attrs["version"] = 2 # Path.Tool is version 1
|
||||
attrs["name"] = obj.Label
|
||||
if PathPreferences.toolsStoreAbsolutePaths():
|
||||
attrs['shape'] = obj.BitShape
|
||||
attrs["shape"] = obj.BitShape
|
||||
else:
|
||||
# attrs['shape'] = findRelativePathShape(obj.BitShape)
|
||||
# Extract the name of the shape file
|
||||
__, filShp = os.path.split(obj.BitShape) # __ is an ignored placeholder acknowledged by LGTM
|
||||
attrs['shape'] = str(filShp)
|
||||
__, filShp = os.path.split(
|
||||
obj.BitShape
|
||||
) # __ is an ignored placeholder acknowledged by LGTM
|
||||
attrs["shape"] = str(filShp)
|
||||
params = {}
|
||||
for name in obj.BitPropertyNames:
|
||||
params[name] = PathUtil.getPropertyValueString(obj, name)
|
||||
attrs['parameter'] = params
|
||||
attrs["parameter"] = params
|
||||
params = {}
|
||||
attrs['attribute'] = params
|
||||
attrs["attribute"] = params
|
||||
return attrs
|
||||
|
||||
|
||||
def Declaration(path):
|
||||
PathLog.track(path)
|
||||
with open(path, 'r') as fp:
|
||||
with open(path, "r") as fp:
|
||||
return json.load(fp)
|
||||
|
||||
|
||||
class ToolBitFactory(object):
|
||||
|
||||
def CreateFromAttrs(self, attrs, name='ToolBit', path=None):
|
||||
def CreateFromAttrs(self, attrs, name="ToolBit", path=None):
|
||||
PathLog.track(attrs, path)
|
||||
obj = Factory.Create(name, attrs['shape'], path)
|
||||
obj.Label = attrs['name']
|
||||
params = attrs['parameter']
|
||||
obj = Factory.Create(name, attrs["shape"], path)
|
||||
obj.Label = attrs["name"]
|
||||
params = attrs["parameter"]
|
||||
for prop in params:
|
||||
PathUtil.setProperty(obj, prop, params[prop])
|
||||
obj.Proxy._updateBitShape(obj)
|
||||
obj.Proxy.unloadBitBody(obj)
|
||||
return obj
|
||||
|
||||
def CreateFrom(self, path, name='ToolBit'):
|
||||
def CreateFrom(self, path, name="ToolBit"):
|
||||
PathLog.track(name, path)
|
||||
try:
|
||||
data = Declaration(path)
|
||||
@@ -426,9 +489,9 @@ class ToolBitFactory(object):
|
||||
PathLog.error("%s not a valid tool file (%s)" % (path, e))
|
||||
raise
|
||||
|
||||
def Create(self, name='ToolBit', shapeFile=None, path=None):
|
||||
def Create(self, name="ToolBit", shapeFile=None, path=None):
|
||||
PathLog.track(name, shapeFile, path)
|
||||
obj = FreeCAD.ActiveDocument.addObject('Part::FeaturePython', name)
|
||||
obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython", name)
|
||||
obj.Proxy = ToolBit(obj, shapeFile, path)
|
||||
return obj
|
||||
|
||||
|
||||
@@ -27,18 +27,23 @@ import os
|
||||
|
||||
from PySide import QtCore
|
||||
|
||||
|
||||
class CommandToolBitCreate:
|
||||
'''
|
||||
"""
|
||||
Command used to create a new Tool.
|
||||
'''
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def GetResources(self):
|
||||
return {'Pixmap': 'Path_ToolBit',
|
||||
'MenuText': QtCore.QT_TRANSLATE_NOOP("PathToolBit", "Create Tool"),
|
||||
'ToolTip': QtCore.QT_TRANSLATE_NOOP("PathToolBit", "Creates a new ToolBit object")}
|
||||
return {
|
||||
"Pixmap": "Path_ToolBit",
|
||||
"MenuText": QtCore.QT_TRANSLATE_NOOP("PathToolBit", "Create Tool"),
|
||||
"ToolTip": QtCore.QT_TRANSLATE_NOOP(
|
||||
"PathToolBit", "Creates a new ToolBit object"
|
||||
),
|
||||
}
|
||||
|
||||
def IsActive(self):
|
||||
return FreeCAD.ActiveDocument is not None
|
||||
@@ -47,10 +52,11 @@ class CommandToolBitCreate:
|
||||
obj = PathScripts.PathToolBit.Factory.Create()
|
||||
obj.ViewObject.Proxy.setCreate(obj.ViewObject)
|
||||
|
||||
|
||||
class CommandToolBitSave:
|
||||
'''
|
||||
"""
|
||||
Command used to save an existing Tool to a file.
|
||||
'''
|
||||
"""
|
||||
|
||||
def __init__(self, saveAs):
|
||||
self.saveAs = saveAs
|
||||
@@ -60,13 +66,19 @@ class CommandToolBitSave:
|
||||
menuTxt = QtCore.QT_TRANSLATE_NOOP("PathToolBit", "Save Tool as...")
|
||||
else:
|
||||
menuTxt = QtCore.QT_TRANSLATE_NOOP("PathToolBit", "Save Tool")
|
||||
return {'Pixmap': 'Path_ToolBit',
|
||||
'MenuText': menuTxt,
|
||||
'ToolTip': QtCore.QT_TRANSLATE_NOOP("PathToolBit", "Save an existing ToolBit object to a file")}
|
||||
return {
|
||||
"Pixmap": "Path_ToolBit",
|
||||
"MenuText": menuTxt,
|
||||
"ToolTip": QtCore.QT_TRANSLATE_NOOP(
|
||||
"PathToolBit", "Save an existing ToolBit object to a file"
|
||||
),
|
||||
}
|
||||
|
||||
def selectedTool(self):
|
||||
sel = FreeCADGui.Selection.getSelectionEx()
|
||||
if 1 == len(sel) and isinstance(sel[0].Object.Proxy, PathScripts.PathToolBit.ToolBit):
|
||||
if 1 == len(sel) and isinstance(
|
||||
sel[0].Object.Proxy, PathScripts.PathToolBit.ToolBit
|
||||
):
|
||||
return sel[0].Object
|
||||
return None
|
||||
|
||||
@@ -80,6 +92,7 @@ class CommandToolBitSave:
|
||||
|
||||
def Activated(self):
|
||||
from PySide import QtGui
|
||||
|
||||
tool = self.selectedTool()
|
||||
if tool:
|
||||
path = None
|
||||
@@ -87,35 +100,47 @@ class CommandToolBitSave:
|
||||
if tool.File:
|
||||
fname = tool.File
|
||||
else:
|
||||
fname = os.path.join(PathScripts.PathPreferences.lastPathToolBit(), tool.Label + '.fctb')
|
||||
foo = QtGui.QFileDialog.getSaveFileName(QtGui.QApplication.activeWindow(), "Tool", fname, "*.fctb")
|
||||
fname = os.path.join(
|
||||
PathScripts.PathPreferences.lastPathToolBit(),
|
||||
tool.Label + ".fctb",
|
||||
)
|
||||
foo = QtGui.QFileDialog.getSaveFileName(
|
||||
QtGui.QApplication.activeWindow(), "Tool", fname, "*.fctb"
|
||||
)
|
||||
if foo:
|
||||
path = foo[0]
|
||||
else:
|
||||
path = tool.File
|
||||
|
||||
if path:
|
||||
if not path.endswith('.fctb'):
|
||||
path += '.fctb'
|
||||
if not path.endswith(".fctb"):
|
||||
path += ".fctb"
|
||||
tool.Proxy.saveToFile(tool, path)
|
||||
PathScripts.PathPreferences.setLastPathToolBit(os.path.dirname(path))
|
||||
|
||||
|
||||
class CommandToolBitLoad:
|
||||
'''
|
||||
"""
|
||||
Command used to load an existing Tool from a file into the current document.
|
||||
'''
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def GetResources(self):
|
||||
return {'Pixmap': 'Path_ToolBit',
|
||||
'MenuText': QtCore.QT_TRANSLATE_NOOP("PathToolBit", "Load Tool"),
|
||||
'ToolTip': QtCore.QT_TRANSLATE_NOOP("PathToolBit", "Load an existing ToolBit object from a file")}
|
||||
return {
|
||||
"Pixmap": "Path_ToolBit",
|
||||
"MenuText": QtCore.QT_TRANSLATE_NOOP("PathToolBit", "Load Tool"),
|
||||
"ToolTip": QtCore.QT_TRANSLATE_NOOP(
|
||||
"PathToolBit", "Load an existing ToolBit object from a file"
|
||||
),
|
||||
}
|
||||
|
||||
def selectedTool(self):
|
||||
sel = FreeCADGui.Selection.getSelectionEx()
|
||||
if 1 == len(sel) and isinstance(sel[0].Object.Proxy, PathScripts.PathToolBit.ToolBit):
|
||||
if 1 == len(sel) and isinstance(
|
||||
sel[0].Object.Proxy, PathScripts.PathToolBit.ToolBit
|
||||
):
|
||||
return sel[0].Object
|
||||
return None
|
||||
|
||||
@@ -126,12 +151,18 @@ class CommandToolBitLoad:
|
||||
if PathScripts.PathToolBitGui.LoadTools():
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
|
||||
if FreeCAD.GuiUp:
|
||||
FreeCADGui.addCommand('Path_ToolBitCreate', CommandToolBitCreate())
|
||||
FreeCADGui.addCommand('Path_ToolBitLoad', CommandToolBitLoad())
|
||||
FreeCADGui.addCommand('Path_ToolBitSave', CommandToolBitSave(False))
|
||||
FreeCADGui.addCommand('Path_ToolBitSaveAs', CommandToolBitSave(True))
|
||||
|
||||
CommandList = ['Path_ToolBitCreate', 'Path_ToolBitLoad', 'Path_ToolBitSave', 'Path_ToolBitSaveAs']
|
||||
if FreeCAD.GuiUp:
|
||||
FreeCADGui.addCommand("Path_ToolBitCreate", CommandToolBitCreate())
|
||||
FreeCADGui.addCommand("Path_ToolBitLoad", CommandToolBitLoad())
|
||||
FreeCADGui.addCommand("Path_ToolBitSave", CommandToolBitSave(False))
|
||||
FreeCADGui.addCommand("Path_ToolBitSaveAs", CommandToolBitSave(True))
|
||||
|
||||
CommandList = [
|
||||
"Path_ToolBitCreate",
|
||||
"Path_ToolBitLoad",
|
||||
"Path_ToolBitSave",
|
||||
"Path_ToolBitSaveAs",
|
||||
]
|
||||
|
||||
FreeCAD.Console.PrintLog("Loading PathToolBitCmd... done\n")
|
||||
|
||||
@@ -41,11 +41,13 @@ PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
|
||||
def translate(context, text, disambig=None):
|
||||
return QtCore.QCoreApplication.translate(context, text, disambig)
|
||||
|
||||
|
||||
class _Delegate(QtGui.QStyledItemDelegate):
|
||||
'''Handles the creation of an appropriate editing widget for a given property.'''
|
||||
ObjectRole = QtCore.Qt.UserRole + 1
|
||||
"""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
|
||||
EditorRole = QtCore.Qt.UserRole + 3
|
||||
|
||||
def createEditor(self, parent, option, index):
|
||||
editor = index.data(self.EditorRole)
|
||||
@@ -64,14 +66,18 @@ class _Delegate(QtGui.QStyledItemDelegate):
|
||||
# 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)
|
||||
index.model().setData(
|
||||
index,
|
||||
PathUtil.getPropertyValueString(editor.obj, editor.prop),
|
||||
QtCore.Qt.DisplayRole,
|
||||
)
|
||||
|
||||
|
||||
class ToolBitEditor(object):
|
||||
'''UI and controller for editing a ToolBit.
|
||||
"""UI and controller for editing a ToolBit.
|
||||
The controller embeds the UI to the parentWidget which has to have a
|
||||
layout attached to it.
|
||||
'''
|
||||
"""
|
||||
|
||||
def __init__(self, tool, parentWidget=None, loadBitBody=True):
|
||||
PathLog.track()
|
||||
@@ -84,7 +90,7 @@ class ToolBitEditor(object):
|
||||
self.tool = tool
|
||||
self.loadbitbody = loadBitBody
|
||||
if not tool.BitShape:
|
||||
self.tool.BitShape = 'endmill.fcstd'
|
||||
self.tool.BitShape = "endmill.fcstd"
|
||||
|
||||
if self.loadbitbody:
|
||||
self.tool.Proxy.loadBitBody(self.tool)
|
||||
@@ -107,7 +113,7 @@ class ToolBitEditor(object):
|
||||
# which aren't being needed anymore.
|
||||
|
||||
def labelText(name):
|
||||
return re.sub('([A-Z][a-z]+)', r' \1', re.sub('([A-Z]+)', r' \1', name))
|
||||
return re.sub("([A-Z][a-z]+)", r" \1", re.sub("([A-Z]+)", r" \1", name))
|
||||
|
||||
layout = self.form.bitParams.layout()
|
||||
ui = FreeCADGui.UiLoader()
|
||||
@@ -125,12 +131,12 @@ class ToolBitEditor(object):
|
||||
label.show()
|
||||
qsb.show()
|
||||
else:
|
||||
qsb = ui.createWidget('Gui::QuantitySpinBox')
|
||||
qsb = ui.createWidget("Gui::QuantitySpinBox")
|
||||
editor = PathGui.QuantitySpinBox(qsb, tool, name)
|
||||
label = QtGui.QLabel(labelText(name))
|
||||
label = QtGui.QLabel(labelText(name))
|
||||
self.widgets.append((label, qsb, editor))
|
||||
PathLog.debug("create row: {} [{}] {}".format(nr, name, type(qsb)))
|
||||
if hasattr(qsb, 'editingFinished'):
|
||||
if hasattr(qsb, "editingFinished"):
|
||||
qsb.editingFinished.connect(self.updateTool)
|
||||
|
||||
if nr >= layout.rowCount():
|
||||
@@ -156,10 +162,10 @@ class ToolBitEditor(object):
|
||||
PathLog.track()
|
||||
|
||||
setup = True
|
||||
if not hasattr(self, 'delegate'):
|
||||
if not hasattr(self, "delegate"):
|
||||
self.delegate = _Delegate(self.form.attrTree)
|
||||
self.model = QtGui.QStandardItemModel(self.form.attrTree)
|
||||
self.model.setHorizontalHeaderLabels(['Property', 'Value'])
|
||||
self.model.setHorizontalHeaderLabels(["Property", "Value"])
|
||||
else:
|
||||
self.model.removeRows(0, self.model.rowCount())
|
||||
setup = False
|
||||
@@ -175,21 +181,22 @@ class ToolBitEditor(object):
|
||||
label.setEditable(False)
|
||||
|
||||
value = QtGui.QStandardItem()
|
||||
value.setData(PathUtil.getPropertyValueString(tool, prop), QtCore.Qt.DisplayRole)
|
||||
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)
|
||||
|
||||
|
||||
if setup:
|
||||
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()
|
||||
# self.form.attrTree.collapseAll()
|
||||
|
||||
def accept(self):
|
||||
PathLog.track()
|
||||
@@ -215,7 +222,7 @@ class ToolBitEditor(object):
|
||||
# editors fires an event and tries to access its old property, which
|
||||
# might not exist anymore.
|
||||
for lbl, qsb, editor in self.widgets:
|
||||
editor.attachTo(self.tool, 'File')
|
||||
editor.attachTo(self.tool, "File")
|
||||
self.tool.BitShape = shapePath
|
||||
self.setupTool(self.tool)
|
||||
self.form.toolName.setText(self.tool.Label)
|
||||
@@ -260,7 +267,9 @@ class ToolBitEditor(object):
|
||||
path = self.tool.BitShape
|
||||
if not path:
|
||||
path = PathPreferences.lastPathToolShape()
|
||||
foo = QtGui.QFileDialog.getOpenFileName(self.form, "Path - Tool Shape", path, "*.fcstd")
|
||||
foo = QtGui.QFileDialog.getOpenFileName(
|
||||
self.form, "Path - Tool Shape", path, "*.fcstd"
|
||||
)
|
||||
if foo and foo[0]:
|
||||
PathPreferences.setLastPathToolShape(os.path.dirname(foo[0]))
|
||||
self.form.shapePath.setText(foo[0])
|
||||
|
||||
@@ -47,8 +47,8 @@ PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
|
||||
|
||||
|
||||
class ViewProvider(object):
|
||||
'''ViewProvider for a ToolBit.
|
||||
It's sole job is to provide an icon and invoke the TaskPanel on edit.'''
|
||||
"""ViewProvider for a ToolBit.
|
||||
It's sole job is to provide an icon and invoke the TaskPanel on edit."""
|
||||
|
||||
def __init__(self, vobj, name):
|
||||
PathLog.track(name, vobj.Object)
|
||||
@@ -67,9 +67,9 @@ class ViewProvider(object):
|
||||
png = self.obj.Proxy.getBitThumbnail(self.obj)
|
||||
if png:
|
||||
pixmap = QtGui.QPixmap()
|
||||
pixmap.loadFromData(png, 'PNG')
|
||||
pixmap.loadFromData(png, "PNG")
|
||||
return QtGui.QIcon(pixmap)
|
||||
return ':/icons/Path_ToolBit.svg'
|
||||
return ":/icons/Path_ToolBit.svg"
|
||||
|
||||
def __getstate__(self):
|
||||
return None
|
||||
@@ -84,7 +84,7 @@ class ViewProvider(object):
|
||||
|
||||
def getDisplayMode(self, mode):
|
||||
# pylint: disable=unused-argument
|
||||
return 'Default'
|
||||
return "Default"
|
||||
|
||||
def _openTaskPanel(self, vobj, deleteOnReject):
|
||||
PathLog.track()
|
||||
@@ -117,15 +117,16 @@ class ViewProvider(object):
|
||||
if os.path.exists(vobj.Object.BitShape):
|
||||
self.setEdit(vobj)
|
||||
else:
|
||||
msg = translate('PathToolBit',
|
||||
'Toolbit cannot be edited: Shapefile not found')
|
||||
diag = QtGui.QMessageBox(QtGui.QMessageBox.Warning, 'Error', msg)
|
||||
msg = translate(
|
||||
"PathToolBit", "Toolbit cannot be edited: Shapefile not found"
|
||||
)
|
||||
diag = QtGui.QMessageBox(QtGui.QMessageBox.Warning, "Error", msg)
|
||||
diag.setWindowModality(QtCore.Qt.ApplicationModal)
|
||||
diag.exec_()
|
||||
|
||||
|
||||
class TaskPanel:
|
||||
'''TaskPanel for the SetupSheet - if it is being edited directly.'''
|
||||
"""TaskPanel for the SetupSheet - if it is being edited directly."""
|
||||
|
||||
def __init__(self, vobj, deleteOnReject):
|
||||
PathLog.track(vobj.Object.Label)
|
||||
@@ -134,15 +135,16 @@ class TaskPanel:
|
||||
self.editor = PathToolBitEdit.ToolBitEditor(self.obj)
|
||||
self.form = self.editor.form
|
||||
self.deleteOnReject = deleteOnReject
|
||||
FreeCAD.ActiveDocument.openTransaction(translate('PathToolBit',
|
||||
'Edit ToolBit'))
|
||||
FreeCAD.ActiveDocument.openTransaction(translate("PathToolBit", "Edit ToolBit"))
|
||||
|
||||
def reject(self):
|
||||
FreeCAD.ActiveDocument.abortTransaction()
|
||||
self.editor.reject()
|
||||
FreeCADGui.Control.closeDialog()
|
||||
if self.deleteOnReject:
|
||||
FreeCAD.ActiveDocument.openTransaction(translate('PathToolBit', 'Uncreate ToolBit'))
|
||||
FreeCAD.ActiveDocument.openTransaction(
|
||||
translate("PathToolBit", "Uncreate ToolBit")
|
||||
)
|
||||
self.editor.reject()
|
||||
FreeCAD.ActiveDocument.removeObject(self.obj.Name)
|
||||
FreeCAD.ActiveDocument.commitTransaction()
|
||||
@@ -169,18 +171,20 @@ class TaskPanel:
|
||||
|
||||
|
||||
class ToolBitGuiFactory(PathToolBit.ToolBitFactory):
|
||||
|
||||
def Create(self, name='ToolBit', shapeFile=None, path=None):
|
||||
'''Create(name = 'ToolBit') ... creates a new tool bit.
|
||||
It is assumed the tool will be edited immediately so the internal bit body is still attached.'''
|
||||
def Create(self, name="ToolBit", shapeFile=None, path=None):
|
||||
"""Create(name = 'ToolBit') ... creates a new tool bit.
|
||||
It is assumed the tool will be edited immediately so the internal bit body is still attached."""
|
||||
|
||||
PathLog.track(name, shapeFile, path)
|
||||
FreeCAD.ActiveDocument.openTransaction(translate('PathToolBit', 'Create ToolBit'))
|
||||
FreeCAD.ActiveDocument.openTransaction(
|
||||
translate("PathToolBit", "Create ToolBit")
|
||||
)
|
||||
tool = PathToolBit.ToolBitFactory.Create(self, name, shapeFile, path)
|
||||
PathIconViewProvider.Attach(tool.ViewObject, name)
|
||||
FreeCAD.ActiveDocument.commitTransaction()
|
||||
return tool
|
||||
|
||||
|
||||
def isValidFileName(filename):
|
||||
print(filename)
|
||||
try:
|
||||
@@ -194,9 +198,9 @@ def GetNewToolFile(parent=None):
|
||||
if parent is None:
|
||||
parent = QtGui.QApplication.activeWindow()
|
||||
|
||||
foo = QtGui.QFileDialog.getSaveFileName(parent, 'Tool',
|
||||
PathPreferences.lastPathToolBit(),
|
||||
'*.fctb')
|
||||
foo = QtGui.QFileDialog.getSaveFileName(
|
||||
parent, "Tool", PathPreferences.lastPathToolBit(), "*.fctb"
|
||||
)
|
||||
if foo and foo[0]:
|
||||
if not isValidFileName(foo[0]):
|
||||
msgBox = QtGui.QMessageBox()
|
||||
@@ -212,9 +216,9 @@ def GetNewToolFile(parent=None):
|
||||
def GetToolFile(parent=None):
|
||||
if parent is None:
|
||||
parent = QtGui.QApplication.activeWindow()
|
||||
foo = QtGui.QFileDialog.getOpenFileName(parent, 'Tool',
|
||||
PathPreferences.lastPathToolBit(),
|
||||
'*.fctb')
|
||||
foo = QtGui.QFileDialog.getOpenFileName(
|
||||
parent, "Tool", PathPreferences.lastPathToolBit(), "*.fctb"
|
||||
)
|
||||
if foo and foo[0]:
|
||||
PathPreferences.setLastPathToolBit(os.path.dirname(foo[0]))
|
||||
return foo[0]
|
||||
@@ -224,9 +228,9 @@ def GetToolFile(parent=None):
|
||||
def GetToolFiles(parent=None):
|
||||
if parent is None:
|
||||
parent = QtGui.QApplication.activeWindow()
|
||||
foo = QtGui.QFileDialog.getOpenFileNames(parent, 'Tool',
|
||||
PathPreferences.lastPathToolBit(),
|
||||
'*.fctb')
|
||||
foo = QtGui.QFileDialog.getOpenFileNames(
|
||||
parent, "Tool", PathPreferences.lastPathToolBit(), "*.fctb"
|
||||
)
|
||||
if foo and foo[0]:
|
||||
PathPreferences.setLastPathToolBit(os.path.dirname(foo[0][0]))
|
||||
return foo[0]
|
||||
@@ -243,8 +247,9 @@ def GetToolShapeFile(parent=None):
|
||||
elif not os.path.isdir(location):
|
||||
location = PathPreferences.filePath()
|
||||
|
||||
fname = QtGui.QFileDialog.getOpenFileName(parent, 'Select Tool Shape',
|
||||
location, '*.fcstd')
|
||||
fname = QtGui.QFileDialog.getOpenFileName(
|
||||
parent, "Select Tool Shape", location, "*.fcstd"
|
||||
)
|
||||
if fname and fname[0]:
|
||||
if fname != location:
|
||||
newloc = os.path.dirname(fname[0])
|
||||
@@ -255,21 +260,21 @@ def GetToolShapeFile(parent=None):
|
||||
|
||||
|
||||
def LoadTool(parent=None):
|
||||
'''
|
||||
"""
|
||||
LoadTool(parent=None) ... Open a file dialog to load a tool from a file.
|
||||
'''
|
||||
"""
|
||||
foo = GetToolFile(parent)
|
||||
return PathToolBit.Factory.CreateFrom(foo) if foo else foo
|
||||
|
||||
|
||||
def LoadTools(parent=None):
|
||||
'''
|
||||
"""
|
||||
LoadTool(parent=None) ... Open a file dialog to load a tool from a file.
|
||||
'''
|
||||
"""
|
||||
return [PathToolBit.Factory.CreateFrom(foo) for foo in GetToolFiles(parent)]
|
||||
|
||||
|
||||
# Set the factory so all tools are created with UI
|
||||
PathToolBit.Factory = ToolBitGuiFactory()
|
||||
|
||||
PathIconViewProvider.RegisterViewProvider('ToolBit', ViewProvider)
|
||||
PathIconViewProvider.RegisterViewProvider("ToolBit", ViewProvider)
|
||||
|
||||
@@ -27,58 +27,70 @@ import PathScripts.PathPreferences as PathPreferences
|
||||
|
||||
|
||||
class CommandToolBitSelectorOpen:
|
||||
'''
|
||||
"""
|
||||
Command to toggle the ToolBitSelector Dock
|
||||
'''
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def GetResources(self):
|
||||
return {'Pixmap': 'Path_ToolTable',
|
||||
'MenuText': QtCore.QT_TRANSLATE_NOOP("PathToolBitLibrary", "ToolBit Dock"),
|
||||
'ToolTip': QtCore.QT_TRANSLATE_NOOP("PathToolBitLibrary", "Toggle the Toolbit Dock"),
|
||||
'Accel': "P, T",
|
||||
'CmdType': "ForEdit"}
|
||||
return {
|
||||
"Pixmap": "Path_ToolTable",
|
||||
"MenuText": QtCore.QT_TRANSLATE_NOOP("PathToolBitLibrary", "ToolBit Dock"),
|
||||
"ToolTip": QtCore.QT_TRANSLATE_NOOP(
|
||||
"PathToolBitLibrary", "Toggle the Toolbit Dock"
|
||||
),
|
||||
"Accel": "P, T",
|
||||
"CmdType": "ForEdit",
|
||||
}
|
||||
|
||||
def IsActive(self):
|
||||
return FreeCAD.ActiveDocument is not None
|
||||
|
||||
def Activated(self):
|
||||
import PathScripts.PathToolBitLibraryGui as PathToolBitLibraryGui
|
||||
|
||||
dock = PathToolBitLibraryGui.ToolBitSelector()
|
||||
dock.open()
|
||||
|
||||
|
||||
class CommandToolBitLibraryOpen:
|
||||
'''
|
||||
"""
|
||||
Command to open ToolBitLibrary editor.
|
||||
'''
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def GetResources(self):
|
||||
return {'Pixmap': 'Path_ToolTable',
|
||||
'MenuText': QtCore.QT_TRANSLATE_NOOP("PathToolBitLibrary", "ToolBit Library editor"),
|
||||
'ToolTip': QtCore.QT_TRANSLATE_NOOP("PathToolBitLibrary", "Open an editor to manage ToolBit libraries"),
|
||||
'CmdType': "ForEdit"}
|
||||
return {
|
||||
"Pixmap": "Path_ToolTable",
|
||||
"MenuText": QtCore.QT_TRANSLATE_NOOP(
|
||||
"PathToolBitLibrary", "ToolBit Library editor"
|
||||
),
|
||||
"ToolTip": QtCore.QT_TRANSLATE_NOOP(
|
||||
"PathToolBitLibrary", "Open an editor to manage ToolBit libraries"
|
||||
),
|
||||
"CmdType": "ForEdit",
|
||||
}
|
||||
|
||||
def IsActive(self):
|
||||
return FreeCAD.ActiveDocument is not None
|
||||
|
||||
def Activated(self):
|
||||
import PathScripts.PathToolBitLibraryGui as PathToolBitLibraryGui
|
||||
|
||||
library = PathToolBitLibraryGui.ToolBitLibrary()
|
||||
|
||||
library.open()
|
||||
|
||||
|
||||
if FreeCAD.GuiUp:
|
||||
FreeCADGui.addCommand('Path_ToolBitLibraryOpen', CommandToolBitLibraryOpen())
|
||||
FreeCADGui.addCommand('Path_ToolBitDock', CommandToolBitSelectorOpen())
|
||||
FreeCADGui.addCommand("Path_ToolBitLibraryOpen", CommandToolBitLibraryOpen())
|
||||
FreeCADGui.addCommand("Path_ToolBitDock", CommandToolBitSelectorOpen())
|
||||
|
||||
BarList = ['Path_ToolBitDock']
|
||||
MenuList = ['Path_ToolBitLibraryOpen', 'Path_ToolBitDock']
|
||||
BarList = ["Path_ToolBitDock"]
|
||||
MenuList = ["Path_ToolBitLibraryOpen", "Path_ToolBitDock"]
|
||||
|
||||
FreeCAD.Console.PrintLog("Loading PathToolBitLibraryCmd... done\n")
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
import PathGui as PGui # ensure Path/Gui/Resources are loaded
|
||||
import PathGui as PGui # ensure Path/Gui/Resources are loaded
|
||||
import PathScripts.PathLog as PathLog
|
||||
import PathScripts.PathPreferences as PathPreferences
|
||||
import PathScripts.PathToolBit as PathToolBit
|
||||
@@ -52,6 +52,7 @@ _PathRole = PySide.QtCore.Qt.UserRole + 2
|
||||
def translate(context, text, disambig=None):
|
||||
return PySide.QtCore.QCoreApplication.translate(context, text, disambig)
|
||||
|
||||
|
||||
def checkWorkingDir():
|
||||
# users shouldn't use the example toolbits and libraries.
|
||||
# working directory should be writable
|
||||
@@ -60,30 +61,35 @@ def checkWorkingDir():
|
||||
workingdir = os.path.dirname(PathPreferences.lastPathToolLibrary())
|
||||
defaultdir = os.path.dirname(PathPreferences.pathDefaultToolsPath())
|
||||
|
||||
PathLog.debug('workingdir: {} defaultdir: {}'.format(workingdir, defaultdir))
|
||||
PathLog.debug("workingdir: {} defaultdir: {}".format(workingdir, defaultdir))
|
||||
|
||||
dirOK = lambda : workingdir != defaultdir and (os.access(workingdir, os.W_OK))
|
||||
dirOK = lambda: workingdir != defaultdir and (os.access(workingdir, os.W_OK))
|
||||
|
||||
if dirOK():
|
||||
return True
|
||||
|
||||
qm = PySide.QtGui.QMessageBox
|
||||
ret = qm.question(None,'', "Toolbit working directory not set up. Do that now?", qm.Yes | qm.No)
|
||||
ret = qm.question(
|
||||
None, "", "Toolbit working directory not set up. Do that now?", qm.Yes | qm.No
|
||||
)
|
||||
|
||||
if ret == qm.No:
|
||||
return False
|
||||
|
||||
msg = translate("Path", "Choose a writable location for your toolbits", None)
|
||||
while not dirOK():
|
||||
workingdir = PySide.QtGui.QFileDialog.getExistingDirectory(None, msg,
|
||||
PathPreferences.filePath())
|
||||
workingdir = PySide.QtGui.QFileDialog.getExistingDirectory(
|
||||
None, msg, PathPreferences.filePath()
|
||||
)
|
||||
|
||||
if workingdir[-8:] == os.path.sep + 'Library':
|
||||
if workingdir[-8:] == os.path.sep + "Library":
|
||||
workingdir = workingdir[:-8] # trim off trailing /Library if user chose it
|
||||
|
||||
PathPreferences.setLastPathToolLibrary("{}{}Library".format(workingdir, os.path.sep))
|
||||
PathPreferences.setLastPathToolLibrary(
|
||||
"{}{}Library".format(workingdir, os.path.sep)
|
||||
)
|
||||
PathPreferences.setLastPathToolBit("{}{}Bit".format(workingdir, os.path.sep))
|
||||
PathLog.debug('setting workingdir to: {}'.format(workingdir))
|
||||
PathLog.debug("setting workingdir to: {}".format(workingdir))
|
||||
|
||||
# Copy only files of default Path\Tools folder to working directory (targeting the README.md help file)
|
||||
src_toolfiles = os.listdir(defaultdir)
|
||||
@@ -94,7 +100,7 @@ def checkWorkingDir():
|
||||
shutil.copy(full_file_name, workingdir)
|
||||
|
||||
# Determine which subdirectories are missing
|
||||
subdirlist = ['Bit', 'Library', 'Shape']
|
||||
subdirlist = ["Bit", "Library", "Shape"]
|
||||
mode = 0o777
|
||||
for dir in subdirlist.copy():
|
||||
subdir = "{}{}{}".format(workingdir, os.path.sep, dir)
|
||||
@@ -103,9 +109,16 @@ def checkWorkingDir():
|
||||
|
||||
# Query user for creation permission of any missing subdirectories
|
||||
if len(subdirlist) >= 1:
|
||||
needed = ', '.join([str(d) for d in subdirlist])
|
||||
needed = ", ".join([str(d) for d in subdirlist])
|
||||
qm = PySide.QtGui.QMessageBox
|
||||
ret = qm.question(None,'', "Toolbit Working directory {} needs these sudirectories:\n {} \n Create them?".format(workingdir, needed), qm.Yes | qm.No)
|
||||
ret = qm.question(
|
||||
None,
|
||||
"",
|
||||
"Toolbit Working directory {} needs these sudirectories:\n {} \n Create them?".format(
|
||||
workingdir, needed
|
||||
),
|
||||
qm.Yes | qm.No,
|
||||
)
|
||||
|
||||
if ret == qm.No:
|
||||
return False
|
||||
@@ -115,27 +128,37 @@ def checkWorkingDir():
|
||||
subdir = "{}{}{}".format(workingdir, os.path.sep, dir)
|
||||
os.mkdir(subdir, mode)
|
||||
# Query user to copy example files into subdirectories created
|
||||
if dir != 'Shape':
|
||||
if dir != "Shape":
|
||||
qm = PySide.QtGui.QMessageBox
|
||||
ret = qm.question(None,'', "Copy example files to new {} directory?".format(dir), qm.Yes | qm.No)
|
||||
ret = qm.question(
|
||||
None,
|
||||
"",
|
||||
"Copy example files to new {} directory?".format(dir),
|
||||
qm.Yes | qm.No,
|
||||
)
|
||||
if ret == qm.Yes:
|
||||
src="{}{}{}".format(defaultdir, os.path.sep, dir)
|
||||
src = "{}{}{}".format(defaultdir, os.path.sep, dir)
|
||||
src_files = os.listdir(src)
|
||||
for file_name in src_files:
|
||||
full_file_name = os.path.join(src, file_name)
|
||||
if os.path.isfile(full_file_name):
|
||||
shutil.copy(full_file_name, subdir)
|
||||
|
||||
|
||||
# if no library is set, choose the first one in the Library directory
|
||||
if PathPreferences.lastFileToolLibrary() is None:
|
||||
libFiles = [f for f in glob.glob(PathPreferences.lastPathToolLibrary() + os.path.sep + '*.fctl')]
|
||||
libFiles = [
|
||||
f
|
||||
for f in glob.glob(
|
||||
PathPreferences.lastPathToolLibrary() + os.path.sep + "*.fctl"
|
||||
)
|
||||
]
|
||||
PathPreferences.setLastFileToolLibrary(libFiles[0])
|
||||
|
||||
return True
|
||||
|
||||
|
||||
class _TableView(PySide.QtGui.QTableView):
|
||||
'''Subclass of QTableView to support rearrange and copying of ToolBits'''
|
||||
"""Subclass of QTableView to support rearrange and copying of ToolBits"""
|
||||
|
||||
def __init__(self, parent):
|
||||
PySide.QtGui.QTableView.__init__(self, parent)
|
||||
@@ -169,9 +192,15 @@ class _TableView(PySide.QtGui.QTableView):
|
||||
for col in range(model.columnCount()):
|
||||
srcItem = model.item(srcRow, col)
|
||||
|
||||
model.setData(model.index(dstRow, col), srcItem.data(PySide.QtCore.Qt.EditRole), PySide.QtCore.Qt.EditRole)
|
||||
model.setData(
|
||||
model.index(dstRow, col),
|
||||
srcItem.data(PySide.QtCore.Qt.EditRole),
|
||||
PySide.QtCore.Qt.EditRole,
|
||||
)
|
||||
if col == 0:
|
||||
model.setData(model.index(dstRow, col), srcItem.data(_PathRole), _PathRole)
|
||||
model.setData(
|
||||
model.index(dstRow, col), srcItem.data(_PathRole), _PathRole
|
||||
)
|
||||
# Even a clone of a tool gets its own uuid so it can be identified when
|
||||
# rearranging the order or inserting/deleting rows
|
||||
model.setData(model.index(dstRow, col), UUID.uuid4(), _UuidRole)
|
||||
@@ -185,7 +214,7 @@ class _TableView(PySide.QtGui.QTableView):
|
||||
def dropEvent(self, event):
|
||||
PathLog.track()
|
||||
mime = event.mimeData()
|
||||
data = mime.data('application/x-qstandarditemmodeldatalist')
|
||||
data = mime.data("application/x-qstandarditemmodeldatalist")
|
||||
stream = PySide.QtCore.QDataStream(data)
|
||||
srcRows = []
|
||||
while not stream.atEnd():
|
||||
@@ -205,8 +234,7 @@ class _TableView(PySide.QtGui.QTableView):
|
||||
|
||||
|
||||
class ModelFactory(object):
|
||||
''' Helper class to generate qtdata models for toolbit libraries
|
||||
'''
|
||||
"""Helper class to generate qtdata models for toolbit libraries"""
|
||||
|
||||
def __init__(self, path=None):
|
||||
PathLog.track()
|
||||
@@ -221,35 +249,37 @@ class ModelFactory(object):
|
||||
with open(path) as fp:
|
||||
library = json.load(fp)
|
||||
|
||||
for toolBit in library['tools']:
|
||||
for toolBit in library["tools"]:
|
||||
try:
|
||||
nr = toolBit['nr']
|
||||
bit = PathToolBit.findToolBit(toolBit['path'], path)
|
||||
nr = toolBit["nr"]
|
||||
bit = PathToolBit.findToolBit(toolBit["path"], path)
|
||||
if bit:
|
||||
PathLog.track(bit)
|
||||
tool = PathToolBit.Declaration(bit)
|
||||
datamodel.appendRow(self._toolAdd(nr, tool, bit))
|
||||
else:
|
||||
PathLog.error("Could not find tool #{}: {}".format(nr, toolBit['path']))
|
||||
PathLog.error(
|
||||
"Could not find tool #{}: {}".format(nr, toolBit["path"])
|
||||
)
|
||||
except Exception as e:
|
||||
msg = "Error loading tool: {} : {}".format(toolBit['path'], e)
|
||||
msg = "Error loading tool: {} : {}".format(toolBit["path"], e)
|
||||
FreeCAD.Console.PrintError(msg)
|
||||
|
||||
def _toolAdd(self, nr, tool, path):
|
||||
|
||||
strShape = os.path.splitext(os.path.basename(tool['shape']))[0]
|
||||
strShape = os.path.splitext(os.path.basename(tool["shape"]))[0]
|
||||
# strDiam = tool['parameter']['Diameter']
|
||||
tooltip = "{}".format(strShape)
|
||||
|
||||
toolNr = PySide.QtGui.QStandardItem()
|
||||
toolNr.setData(nr, PySide.QtCore.Qt.EditRole)
|
||||
toolNr.setToolTip(tool['shape'])
|
||||
toolNr.setToolTip(tool["shape"])
|
||||
toolNr.setData(path, _PathRole)
|
||||
toolNr.setData(UUID.uuid4(), _UuidRole)
|
||||
toolNr.setToolTip(tooltip)
|
||||
|
||||
toolName = PySide.QtGui.QStandardItem()
|
||||
toolName.setData(tool['name'], PySide.QtCore.Qt.EditRole)
|
||||
toolName.setData(tool["name"], PySide.QtCore.Qt.EditRole)
|
||||
toolName.setEditable(False)
|
||||
toolName.setToolTip(tooltip)
|
||||
|
||||
@@ -260,9 +290,9 @@ class ModelFactory(object):
|
||||
return [toolNr, toolName, toolShape]
|
||||
|
||||
def newTool(self, datamodel, path):
|
||||
'''
|
||||
"""
|
||||
Adds a toolbit item to a model
|
||||
'''
|
||||
"""
|
||||
PathLog.track()
|
||||
|
||||
try:
|
||||
@@ -278,15 +308,15 @@ class ModelFactory(object):
|
||||
datamodel.appendRow(self._toolAdd(nr, tool, path))
|
||||
|
||||
def findLibraries(self, model):
|
||||
'''
|
||||
"""
|
||||
Finds all the fctl files in a location
|
||||
Returns a QStandardItemModel
|
||||
'''
|
||||
"""
|
||||
PathLog.track()
|
||||
path = PathPreferences.lastPathToolLibrary()
|
||||
|
||||
if os.path.isdir(path): # opening all tables in a directory
|
||||
libFiles = [f for f in glob.glob(path + os.path.sep + '*.fctl')]
|
||||
libFiles = [f for f in glob.glob(path + os.path.sep + "*.fctl")]
|
||||
libFiles.sort()
|
||||
for libFile in libFiles:
|
||||
loc, fnlong = os.path.split(libFile)
|
||||
@@ -294,17 +324,17 @@ class ModelFactory(object):
|
||||
libItem = PySide.QtGui.QStandardItem(fn)
|
||||
libItem.setToolTip(loc)
|
||||
libItem.setData(libFile, _PathRole)
|
||||
libItem.setIcon(PySide.QtGui.QPixmap(':/icons/Path_ToolTable.svg'))
|
||||
libItem.setIcon(PySide.QtGui.QPixmap(":/icons/Path_ToolTable.svg"))
|
||||
model.appendRow(libItem)
|
||||
|
||||
PathLog.debug('model rows: {}'.format(model.rowCount()))
|
||||
PathLog.debug("model rows: {}".format(model.rowCount()))
|
||||
return model
|
||||
|
||||
def libraryOpen(self, model, lib=""):
|
||||
'''
|
||||
"""
|
||||
opens the tools in library
|
||||
Returns a QStandardItemModel
|
||||
'''
|
||||
"""
|
||||
PathLog.track(lib)
|
||||
|
||||
if lib == "":
|
||||
@@ -316,23 +346,23 @@ class ModelFactory(object):
|
||||
if os.path.isfile(lib): # An individual library is wanted
|
||||
self.__libraryLoad(lib, model)
|
||||
|
||||
PathLog.debug('model rows: {}'.format(model.rowCount()))
|
||||
PathLog.debug("model rows: {}".format(model.rowCount()))
|
||||
return model
|
||||
|
||||
|
||||
class ToolBitSelector(object):
|
||||
'''Controller for displaying a library and creating ToolControllers'''
|
||||
"""Controller for displaying a library and creating ToolControllers"""
|
||||
|
||||
def __init__(self):
|
||||
checkWorkingDir()
|
||||
self.form = FreeCADGui.PySideUic.loadUi(':/panels/ToolBitSelector.ui')
|
||||
self.form = FreeCADGui.PySideUic.loadUi(":/panels/ToolBitSelector.ui")
|
||||
self.factory = ModelFactory()
|
||||
self.toolModel = PySide.QtGui.QStandardItemModel(0, len(self.columnNames()))
|
||||
self.setupUI()
|
||||
self.title = self.form.windowTitle()
|
||||
|
||||
def columnNames(self):
|
||||
return ['#', 'Tool']
|
||||
return ["#", "Tool"]
|
||||
|
||||
def currentLibrary(self, shortNameOnly):
|
||||
libfile = PathPreferences.lastFileToolLibrary()
|
||||
@@ -357,14 +387,19 @@ class ToolBitSelector(object):
|
||||
self.loadData()
|
||||
self.form.tools.setModel(self.toolModel)
|
||||
self.form.tools.selectionModel().selectionChanged.connect(self.enableButtons)
|
||||
self.form.tools.doubleClicked.connect(partial(self.selectedOrAllToolControllers))
|
||||
self.form.tools.doubleClicked.connect(
|
||||
partial(self.selectedOrAllToolControllers)
|
||||
)
|
||||
self.form.libraryEditorOpen.clicked.connect(self.libraryEditorOpen)
|
||||
self.form.addToolController.clicked.connect(self.selectedOrAllToolControllers)
|
||||
|
||||
def enableButtons(self):
|
||||
selected = (len(self.form.tools.selectedIndexes()) >= 1)
|
||||
selected = len(self.form.tools.selectedIndexes()) >= 1
|
||||
if selected:
|
||||
jobs = len([1 for j in FreeCAD.ActiveDocument.Objects if j.Name[:3] == "Job"]) >= 1
|
||||
jobs = (
|
||||
len([1 for j in FreeCAD.ActiveDocument.Objects if j.Name[:3] == "Job"])
|
||||
>= 1
|
||||
)
|
||||
self.form.addToolController.setEnabled(selected and jobs)
|
||||
|
||||
def libraryEditorOpen(self):
|
||||
@@ -373,17 +408,17 @@ class ToolBitSelector(object):
|
||||
self.loadData()
|
||||
|
||||
def selectedOrAllTools(self):
|
||||
'''
|
||||
"""
|
||||
Iterate the selection and add individual tools
|
||||
If a group is selected, iterate and add children
|
||||
'''
|
||||
"""
|
||||
|
||||
itemsToProcess = []
|
||||
for index in self.form.tools.selectedIndexes():
|
||||
item = index.model().itemFromIndex(index)
|
||||
|
||||
if item.hasChildren():
|
||||
for i in range(item.rowCount()-1):
|
||||
for i in range(item.rowCount() - 1):
|
||||
if item.child(i).column() == 0:
|
||||
itemsToProcess.append(item.child(i))
|
||||
|
||||
@@ -398,10 +433,10 @@ class ToolBitSelector(object):
|
||||
return tools
|
||||
|
||||
def selectedOrAllToolControllers(self, index=None):
|
||||
'''
|
||||
"""
|
||||
if no jobs, don't do anything, otherwise all TCs for all
|
||||
selected toolbits
|
||||
'''
|
||||
"""
|
||||
jobs = PathUtilsGui.PathUtils.GetJobs()
|
||||
if len(jobs) == 0:
|
||||
return
|
||||
@@ -417,12 +452,14 @@ class ToolBitSelector(object):
|
||||
tools = self.selectedOrAllTools()
|
||||
|
||||
for tool in tools:
|
||||
tc = PathToolControllerGui.Create("TC: {}".format(tool[1].Label), tool[1], tool[0])
|
||||
tc = PathToolControllerGui.Create(
|
||||
"TC: {}".format(tool[1].Label), tool[1], tool[0]
|
||||
)
|
||||
job.Proxy.addToolController(tc)
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
|
||||
def open(self, path=None):
|
||||
''' load library stored in path and bring up ui'''
|
||||
"""load library stored in path and bring up ui"""
|
||||
docs = FreeCADGui.getMainWindow().findChildren(PySide.QtGui.QDockWidget)
|
||||
for doc in docs:
|
||||
if doc.objectName() == "ToolSelector":
|
||||
@@ -434,13 +471,16 @@ class ToolBitSelector(object):
|
||||
return
|
||||
|
||||
mw = FreeCADGui.getMainWindow()
|
||||
mw.addDockWidget(PySide.QtCore.Qt.RightDockWidgetArea, self.form,
|
||||
PySide.QtCore.Qt.Orientation.Vertical)
|
||||
mw.addDockWidget(
|
||||
PySide.QtCore.Qt.RightDockWidgetArea,
|
||||
self.form,
|
||||
PySide.QtCore.Qt.Orientation.Vertical,
|
||||
)
|
||||
|
||||
|
||||
class ToolBitLibrary(object):
|
||||
'''ToolBitLibrary is the controller for
|
||||
displaying/selecting/creating/editing a collection of ToolBits.'''
|
||||
"""ToolBitLibrary is the controller for
|
||||
displaying/selecting/creating/editing a collection of ToolBits."""
|
||||
|
||||
def __init__(self):
|
||||
PathLog.track()
|
||||
@@ -449,9 +489,11 @@ class ToolBitLibrary(object):
|
||||
self.temptool = None
|
||||
self.toolModel = PySide.QtGui.QStandardItemModel(0, len(self.columnNames()))
|
||||
self.listModel = PySide.QtGui.QStandardItemModel()
|
||||
self.form = FreeCADGui.PySideUic.loadUi(':/panels/ToolBitLibraryEdit.ui')
|
||||
self.form = FreeCADGui.PySideUic.loadUi(":/panels/ToolBitLibraryEdit.ui")
|
||||
self.toolTableView = _TableView(self.form.toolTableGroup)
|
||||
self.form.toolTableGroup.layout().replaceWidget(self.form.toolTable, self.toolTableView)
|
||||
self.form.toolTableGroup.layout().replaceWidget(
|
||||
self.form.toolTable, self.toolTableView
|
||||
)
|
||||
self.form.toolTable.hide()
|
||||
self.setupUI()
|
||||
self.title = self.form.windowTitle()
|
||||
@@ -503,7 +545,9 @@ class ToolBitLibrary(object):
|
||||
|
||||
def toolDelete(self):
|
||||
PathLog.track()
|
||||
selectedRows = set([index.row() for index in self.toolTableView.selectedIndexes()])
|
||||
selectedRows = set(
|
||||
[index.row() for index in self.toolTableView.selectedIndexes()]
|
||||
)
|
||||
for row in sorted(list(selectedRows), key=lambda r: -r):
|
||||
self.toolModel.removeRows(row, 1)
|
||||
|
||||
@@ -512,7 +556,7 @@ class ToolBitLibrary(object):
|
||||
self.form.toolDelete.setEnabled(sel)
|
||||
|
||||
def tableSelected(self, index):
|
||||
''' loads the tools for the selected tool table '''
|
||||
"""loads the tools for the selected tool table"""
|
||||
PathLog.track()
|
||||
item = index.model().itemFromIndex(index)
|
||||
libpath = item.data(_PathRole)
|
||||
@@ -525,7 +569,9 @@ class ToolBitLibrary(object):
|
||||
|
||||
def libraryPath(self):
|
||||
PathLog.track()
|
||||
path = PySide.QtGui.QFileDialog.getExistingDirectory(self.form, 'Tool Library Path', PathPreferences.lastPathToolLibrary())
|
||||
path = PySide.QtGui.QFileDialog.getExistingDirectory(
|
||||
self.form, "Tool Library Path", PathPreferences.lastPathToolLibrary()
|
||||
)
|
||||
if len(path) == 0:
|
||||
return
|
||||
|
||||
@@ -588,10 +634,14 @@ class ToolBitLibrary(object):
|
||||
pass
|
||||
else:
|
||||
tbpath = item.data(_PathRole)
|
||||
self.temptool = PathToolBit.ToolBitFactory().CreateFrom(tbpath, 'temptool')
|
||||
self.editor = PathToolBitEdit.ToolBitEditor(self.temptool, self.form.toolTableGroup, loadBitBody=False)
|
||||
self.temptool = PathToolBit.ToolBitFactory().CreateFrom(tbpath, "temptool")
|
||||
self.editor = PathToolBitEdit.ToolBitEditor(
|
||||
self.temptool, self.form.toolTableGroup, loadBitBody=False
|
||||
)
|
||||
|
||||
QBtn = PySide.QtGui.QDialogButtonBox.Ok | PySide.QtGui.QDialogButtonBox.Cancel
|
||||
QBtn = (
|
||||
PySide.QtGui.QDialogButtonBox.Ok | PySide.QtGui.QDialogButtonBox.Cancel
|
||||
)
|
||||
buttonBox = PySide.QtGui.QDialogButtonBox(QBtn)
|
||||
buttonBox.accepted.connect(self.accept)
|
||||
buttonBox.rejected.connect(self.reject)
|
||||
@@ -603,24 +653,33 @@ class ToolBitLibrary(object):
|
||||
|
||||
def toolEditDone(self, success=True):
|
||||
FreeCAD.ActiveDocument.removeObject("temptool")
|
||||
print('all done')
|
||||
print("all done")
|
||||
|
||||
def libraryNew(self):
|
||||
TooltableTypeJSON = translate("PathToolLibraryManager", "Tooltable JSON (*.fctl)")
|
||||
TooltableTypeJSON = translate(
|
||||
"PathToolLibraryManager", "Tooltable JSON (*.fctl)"
|
||||
)
|
||||
|
||||
filename = PySide.QtGui.QFileDialog.getSaveFileName(self.form,
|
||||
translate("TooltableEditor", "Save toolbit library", None),
|
||||
PathPreferences.lastPathToolLibrary(), "{}".format(TooltableTypeJSON))
|
||||
filename = PySide.QtGui.QFileDialog.getSaveFileName(
|
||||
self.form,
|
||||
translate("TooltableEditor", "Save toolbit library", None),
|
||||
PathPreferences.lastPathToolLibrary(),
|
||||
"{}".format(TooltableTypeJSON),
|
||||
)
|
||||
|
||||
if not (filename and filename[0]):
|
||||
self.loadData()
|
||||
|
||||
path = filename[0] if filename[0].endswith('.fctl') else "{}.fctl".format(filename[0])
|
||||
path = (
|
||||
filename[0]
|
||||
if filename[0].endswith(".fctl")
|
||||
else "{}.fctl".format(filename[0])
|
||||
)
|
||||
library = {}
|
||||
tools = []
|
||||
library['version'] = 1
|
||||
library['tools'] = tools
|
||||
with open(path, 'w') as fp:
|
||||
library["version"] = 1
|
||||
library["tools"] = tools
|
||||
with open(path, "w") as fp:
|
||||
json.dump(library, fp, sort_keys=True, indent=2)
|
||||
|
||||
self.loadData()
|
||||
@@ -628,22 +687,26 @@ class ToolBitLibrary(object):
|
||||
def librarySave(self):
|
||||
library = {}
|
||||
tools = []
|
||||
library['version'] = 1
|
||||
library['tools'] = tools
|
||||
library["version"] = 1
|
||||
library["tools"] = tools
|
||||
for row in range(self.toolModel.rowCount()):
|
||||
toolNr = self.toolModel.data(self.toolModel.index(row, 0), PySide.QtCore.Qt.EditRole)
|
||||
toolNr = self.toolModel.data(
|
||||
self.toolModel.index(row, 0), PySide.QtCore.Qt.EditRole
|
||||
)
|
||||
toolPath = self.toolModel.data(self.toolModel.index(row, 0), _PathRole)
|
||||
if PathPreferences.toolsStoreAbsolutePaths():
|
||||
bitPath = toolPath
|
||||
else:
|
||||
# bitPath = PathToolBit.findRelativePathTool(toolPath)
|
||||
# Extract the name of the shape file
|
||||
__, filShp = os.path.split(toolPath) # __ is an ignored placeholder acknowledged by LGTM
|
||||
__, filShp = os.path.split(
|
||||
toolPath
|
||||
) # __ is an ignored placeholder acknowledged by LGTM
|
||||
bitPath = str(filShp)
|
||||
tools.append({'nr': toolNr, 'path': bitPath})
|
||||
tools.append({"nr": toolNr, "path": bitPath})
|
||||
|
||||
if self.path is not None:
|
||||
with open(self.path, 'w') as fp:
|
||||
with open(self.path, "w") as fp:
|
||||
json.dump(library, fp, sort_keys=True, indent=2)
|
||||
|
||||
def libraryOk(self):
|
||||
@@ -658,7 +721,7 @@ class ToolBitLibrary(object):
|
||||
return lib, loc
|
||||
|
||||
def columnNames(self):
|
||||
return ['Nr', 'Tool', 'Shape']
|
||||
return ["Nr", "Tool", "Shape"]
|
||||
|
||||
def loadData(self, path=None):
|
||||
PathLog.track(path)
|
||||
@@ -680,7 +743,7 @@ class ToolBitLibrary(object):
|
||||
self.path = path
|
||||
self.form.setWindowTitle("{}".format(PathPreferences.lastPathToolLibrary()))
|
||||
self.toolModel.setHorizontalHeaderLabels(self.columnNames())
|
||||
self.listModel.setHorizontalHeaderLabels(['Library'])
|
||||
self.listModel.setHorizontalHeaderLabels(["Library"])
|
||||
|
||||
# Select the current library in the list of tables
|
||||
curIndex = None
|
||||
@@ -723,19 +786,33 @@ class ToolBitLibrary(object):
|
||||
|
||||
def librarySaveAs(self, path):
|
||||
|
||||
TooltableTypeJSON = translate("PathToolLibraryManager", "Tooltable JSON (*.fctl)")
|
||||
TooltableTypeLinuxCNC = translate("PathToolLibraryManager", "LinuxCNC tooltable (*.tbl)")
|
||||
TooltableTypeJSON = translate(
|
||||
"PathToolLibraryManager", "Tooltable JSON (*.fctl)"
|
||||
)
|
||||
TooltableTypeLinuxCNC = translate(
|
||||
"PathToolLibraryManager", "LinuxCNC tooltable (*.tbl)"
|
||||
)
|
||||
|
||||
filename = PySide.QtGui.QFileDialog.getSaveFileName(self.form,
|
||||
translate("TooltableEditor", "Save toolbit library", None),
|
||||
PathPreferences.lastPathToolLibrary(), "{};;{}".format(TooltableTypeJSON,
|
||||
TooltableTypeLinuxCNC))
|
||||
filename = PySide.QtGui.QFileDialog.getSaveFileName(
|
||||
self.form,
|
||||
translate("TooltableEditor", "Save toolbit library", None),
|
||||
PathPreferences.lastPathToolLibrary(),
|
||||
"{};;{}".format(TooltableTypeJSON, TooltableTypeLinuxCNC),
|
||||
)
|
||||
if filename and filename[0]:
|
||||
if filename[1] == TooltableTypeLinuxCNC:
|
||||
path = filename[0] if filename[0].endswith('.tbl') else "{}.tbl".format(filename[0])
|
||||
path = (
|
||||
filename[0]
|
||||
if filename[0].endswith(".tbl")
|
||||
else "{}.tbl".format(filename[0])
|
||||
)
|
||||
self.libararySaveLinuxCNC(path)
|
||||
else:
|
||||
path = filename[0] if filename[0].endswith('.fctl') else "{}.fctl".format(filename[0])
|
||||
path = (
|
||||
filename[0]
|
||||
if filename[0].endswith(".fctl")
|
||||
else "{}.fctl".format(filename[0])
|
||||
)
|
||||
self.path = path
|
||||
self.librarySave()
|
||||
self.updateToolbar()
|
||||
@@ -743,11 +820,13 @@ class ToolBitLibrary(object):
|
||||
def libararySaveLinuxCNC(self, path):
|
||||
# linuxcnc line template
|
||||
LIN = "T{} P{} X{} Y{} Z{} A{} B{} C{} U{} V{} W{} D{} I{} J{} Q{}; {}"
|
||||
with open(path, 'w') as fp:
|
||||
with open(path, "w") as fp:
|
||||
fp.write(";\n")
|
||||
|
||||
for row in range(self.toolModel.rowCount()):
|
||||
toolNr = self.toolModel.data(self.toolModel.index(row, 0), PySide.QtCore.Qt.EditRole)
|
||||
toolNr = self.toolModel.data(
|
||||
self.toolModel.index(row, 0), PySide.QtCore.Qt.EditRole
|
||||
)
|
||||
toolPath = self.toolModel.data(self.toolModel.index(row, 0), _PathRole)
|
||||
|
||||
bit = PathToolBit.Factory.CreateFrom(toolPath)
|
||||
@@ -765,16 +844,39 @@ class ToolBitLibrary(object):
|
||||
voffset = bit.Voffset if hasattr(bit, "Voffset") else "0"
|
||||
woffset = bit.Woffset if hasattr(bit, "Woffset") else "0"
|
||||
|
||||
diameter = bit.Diameter.getUserPreferred()[0].split()[0] if hasattr(bit, "Diameter") else "0"
|
||||
diameter = (
|
||||
bit.Diameter.getUserPreferred()[0].split()[0]
|
||||
if hasattr(bit, "Diameter")
|
||||
else "0"
|
||||
)
|
||||
frontangle = bit.FrontAngle if hasattr(bit, "FrontAngle") else "0"
|
||||
backangle = bit.BackAngle if hasattr(bit, "BackAngle") else "0"
|
||||
orientation = bit.Orientation if hasattr(bit, "Orientation") else "0"
|
||||
orientation = (
|
||||
bit.Orientation if hasattr(bit, "Orientation") else "0"
|
||||
)
|
||||
remark = bit.Label
|
||||
|
||||
fp.write(LIN.format(toolNr, pocket, xoffset, yoffset,
|
||||
zoffset, aoffset, boffset, coffset, uoffset,
|
||||
voffset, woffset, diameter, frontangle, backangle,
|
||||
orientation, remark) + "\n")
|
||||
fp.write(
|
||||
LIN.format(
|
||||
toolNr,
|
||||
pocket,
|
||||
xoffset,
|
||||
yoffset,
|
||||
zoffset,
|
||||
aoffset,
|
||||
boffset,
|
||||
coffset,
|
||||
uoffset,
|
||||
voffset,
|
||||
woffset,
|
||||
diameter,
|
||||
frontangle,
|
||||
backangle,
|
||||
orientation,
|
||||
remark,
|
||||
)
|
||||
+ "\n"
|
||||
)
|
||||
|
||||
FreeCAD.ActiveDocument.removeObject(bit.Name)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user