Basic workflow. No editing
concept dock work most functions working. made linuxcnc export work Fixed some defaults on new install fixed display label in dock
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * Copyright (c) 2014 Yorik van Havre <yorik@uncreated.net> *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
@@ -42,15 +44,19 @@ PostProcessorOutputPolicy = "PostProcessorOutputPolicy"
|
||||
LastPathToolBit = "LastPathToolBit"
|
||||
LastPathToolLibrary = "LastPathToolLibrary"
|
||||
LastPathToolShape = "LastPathToolShape"
|
||||
LastPathToolTable ="LastPathToolTable"
|
||||
LastPathToolTable = "LastPathToolTable"
|
||||
|
||||
LastFileToolBit = "LastFileToolBit"
|
||||
LastFileToolLibrary = "LastFileToolLibrary"
|
||||
LastFileToolShape = "LastFileToolShape"
|
||||
|
||||
UseLegacyTools = "UseLegacyTools"
|
||||
UseAbsoluteToolPaths = "UseAbsoluteToolPaths"
|
||||
OpenLastLibrary = "OpenLastLibrary"
|
||||
|
||||
# Linear tolerance to use when generating Paths, eg when tessellating geometry
|
||||
GeometryTolerance = "GeometryTolerance"
|
||||
LibAreaCurveAccuracy = "LibAreaCurveAccuarcy"
|
||||
GeometryTolerance = "GeometryTolerance"
|
||||
LibAreaCurveAccuracy = "LibAreaCurveAccuarcy"
|
||||
|
||||
EnableExperimentalFeatures = "EnableExperimentalFeatures"
|
||||
|
||||
@@ -58,58 +64,70 @@ EnableExperimentalFeatures = "EnableExperimentalFeatures"
|
||||
def preferences():
|
||||
return FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Path")
|
||||
|
||||
|
||||
def pathScriptsSourcePath():
|
||||
return os.path.join(FreeCAD.getHomePath(), "Mod/Path/PathScripts/")
|
||||
|
||||
|
||||
def pathDefaultToolsPath(sub=None):
|
||||
if sub:
|
||||
return os.path.join(FreeCAD.getHomePath(), "Mod/Path/Tools/", sub)
|
||||
return os.path.join(FreeCAD.getHomePath(), "Mod/Path/Tools/")
|
||||
|
||||
|
||||
def allAvailablePostProcessors():
|
||||
allposts = []
|
||||
for path in searchPathsPost():
|
||||
posts = [ str(os.path.split(os.path.splitext(p)[0])[1][:-5]) for p in glob.glob(path + '/*_post.py')]
|
||||
posts = [str(os.path.split(os.path.splitext(p)[0])[1][:-5]) for p in glob.glob(path + '/*_post.py')]
|
||||
allposts.extend(posts)
|
||||
allposts.sort()
|
||||
return allposts
|
||||
|
||||
def allEnabledPostProcessors(include = None):
|
||||
|
||||
def allEnabledPostProcessors(include=None):
|
||||
blacklist = postProcessorBlacklist()
|
||||
enabled = [processor for processor in allAvailablePostProcessors() if not processor in blacklist]
|
||||
enabled = [processor for processor in allAvailablePostProcessors() if processor not in blacklist]
|
||||
if include:
|
||||
l = list(set(include + enabled))
|
||||
l.sort()
|
||||
return l
|
||||
postlist = list(set(include + enabled))
|
||||
postlist.sort()
|
||||
return postlist
|
||||
return enabled
|
||||
|
||||
|
||||
def defaultPostProcessor():
|
||||
pref = preferences()
|
||||
return pref.GetString(PostProcessorDefault, "")
|
||||
|
||||
|
||||
def defaultPostProcessorArgs():
|
||||
pref = preferences()
|
||||
return pref.GetString(PostProcessorDefaultArgs, "")
|
||||
|
||||
|
||||
def defaultGeometryTolerance():
|
||||
return preferences().GetFloat(GeometryTolerance, 0.01)
|
||||
|
||||
|
||||
def defaultLibAreaCurveAccuracy():
|
||||
return preferences().GetFloat(LibAreaCurveAccuracy, 0.01)
|
||||
|
||||
|
||||
def defaultFilePath():
|
||||
return preferences().GetString(DefaultFilePath)
|
||||
|
||||
|
||||
def filePath():
|
||||
path = defaultFilePath()
|
||||
if not path:
|
||||
path = macroFilePath()
|
||||
return path
|
||||
|
||||
|
||||
def macroFilePath():
|
||||
grp = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macro")
|
||||
return grp.GetString("MacroPath", FreeCAD.getUserMacroDir())
|
||||
|
||||
|
||||
def searchPaths():
|
||||
paths = []
|
||||
p = defaultFilePath()
|
||||
@@ -118,6 +136,7 @@ def searchPaths():
|
||||
paths.append(macroFilePath())
|
||||
return paths
|
||||
|
||||
|
||||
def searchPathsPost():
|
||||
paths = []
|
||||
p = defaultFilePath()
|
||||
@@ -128,6 +147,7 @@ def searchPathsPost():
|
||||
paths.append(pathScriptsSourcePath())
|
||||
return paths
|
||||
|
||||
|
||||
def searchPathsTool(sub='Bit'):
|
||||
paths = []
|
||||
|
||||
@@ -148,30 +168,37 @@ def searchPathsTool(sub='Bit'):
|
||||
appendPath(os.path.join(FreeCAD.getHomePath(), "Mod/Path/"), sub)
|
||||
return paths
|
||||
|
||||
|
||||
def toolsUseLegacyTools():
|
||||
return preferences().GetBool(UseLegacyTools, True)
|
||||
return preferences().GetBool(UseLegacyTools, False)
|
||||
|
||||
|
||||
def toolsReallyUseLegacyTools():
|
||||
return toolsUseLegacyTools() or not experimentalFeaturesEnabled()
|
||||
return toolsUseLegacyTools()
|
||||
|
||||
|
||||
def toolsStoreAbsolutePaths():
|
||||
return preferences().GetBool(UseAbsoluteToolPaths, False)
|
||||
|
||||
|
||||
def toolsOpenLastLibrary():
|
||||
return preferences().GetBool(OpenLastLibrary, False)
|
||||
|
||||
|
||||
def setToolsSettings(legacy, relative, lastlibrary):
|
||||
pref = preferences()
|
||||
pref.SetBool(UseLegacyTools, legacy)
|
||||
pref.SetBool(UseAbsoluteToolPaths, relative)
|
||||
pref.SetBool(OpenLastLibrary, lastlibrary)
|
||||
|
||||
|
||||
def defaultJobTemplate():
|
||||
template = preferences().GetString(DefaultJobTemplate)
|
||||
if 'xml' not in template:
|
||||
return template
|
||||
return ''
|
||||
|
||||
|
||||
def setJobDefaults(fileName, jobTemplate, geometryTolerance, curveAccuracy):
|
||||
PathLog.track("(%s='%s', %s, %s, %s)" % (DefaultFilePath, fileName, jobTemplate, geometryTolerance, curveAccuracy))
|
||||
pref = preferences()
|
||||
@@ -180,12 +207,14 @@ def setJobDefaults(fileName, jobTemplate, geometryTolerance, curveAccuracy):
|
||||
pref.SetFloat(GeometryTolerance, geometryTolerance)
|
||||
pref.SetFloat(LibAreaCurveAccuracy, curveAccuracy)
|
||||
|
||||
|
||||
def postProcessorBlacklist():
|
||||
pref = preferences()
|
||||
blacklist = pref.GetString(PostProcessorBlacklist, "")
|
||||
if not blacklist:
|
||||
return []
|
||||
return eval(blacklist) # pylint: disable=eval-used
|
||||
return eval(blacklist) # pylint: disable=eval-used
|
||||
|
||||
|
||||
def setPostProcessorDefaults(processor, args, blacklist):
|
||||
pref = preferences()
|
||||
@@ -193,54 +222,99 @@ def setPostProcessorDefaults(processor, args, blacklist):
|
||||
pref.SetString(PostProcessorDefaultArgs, args)
|
||||
pref.SetString(PostProcessorBlacklist, "%s" % (blacklist))
|
||||
|
||||
|
||||
def setOutputFileDefaults(fileName, policy):
|
||||
pref = preferences()
|
||||
pref.SetString(PostProcessorOutputFile, fileName)
|
||||
pref.SetString(PostProcessorOutputPolicy, policy)
|
||||
|
||||
|
||||
def defaultOutputFile():
|
||||
pref = preferences()
|
||||
return pref.GetString(PostProcessorOutputFile, "")
|
||||
|
||||
|
||||
def defaultOutputPolicy():
|
||||
pref = preferences()
|
||||
return pref.GetString(PostProcessorOutputPolicy, "")
|
||||
|
||||
|
||||
def defaultStockTemplate():
|
||||
return preferences().GetString(DefaultStockTemplate, "")
|
||||
|
||||
|
||||
def setDefaultStockTemplate(template):
|
||||
preferences().SetString(DefaultStockTemplate, template)
|
||||
|
||||
|
||||
def defaultTaskPanelLayout():
|
||||
return preferences().GetInt(DefaultTaskPanelLayout, 0)
|
||||
|
||||
|
||||
def setDefaultTaskPanelLayout(style):
|
||||
preferences().SetInt(DefaultTaskPanelLayout, style)
|
||||
|
||||
|
||||
def experimentalFeaturesEnabled():
|
||||
return preferences().GetBool(EnableExperimentalFeatures, False)
|
||||
|
||||
|
||||
def lastFileToolLibrary():
|
||||
filename = preferences().GetString(LastFileToolLibrary)
|
||||
if filename.endswith('.fctl') and os.path.isfile(filename):
|
||||
return filename
|
||||
|
||||
libpath = preferences().GetString(LastPathToolLibrary, pathDefaultToolsPath('Library'))
|
||||
libFiles = [f for f in glob.glob(libpath + '/*.fctl')]
|
||||
libFiles.sort()
|
||||
if len(libFiles) >= 1:
|
||||
filename = libFiles[0]
|
||||
setLastFileToolLibrary(filename)
|
||||
PathLog.track(filename)
|
||||
return filename
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def setLastFileToolLibrary(path):
|
||||
PathLog.track(path)
|
||||
if os.path.isfile(path): # keep the path and file in sync
|
||||
preferences().SetString(LastPathToolLibrary, os.path.split(path)[0])
|
||||
return preferences().SetString(LastFileToolLibrary, path)
|
||||
|
||||
|
||||
def lastPathToolBit():
|
||||
return preferences().GetString(LastPathToolBit, pathDefaultToolsPath('Bit'))
|
||||
|
||||
|
||||
def setLastPathToolBit(path):
|
||||
return preferences().SetString(LastPathToolBit, path)
|
||||
|
||||
|
||||
def lastPathToolLibrary():
|
||||
PathLog.track()
|
||||
return preferences().GetString(LastPathToolLibrary, pathDefaultToolsPath('Library'))
|
||||
|
||||
|
||||
def setLastPathToolLibrary(path):
|
||||
PathLog.track(path)
|
||||
curLib = lastFileToolLibrary()
|
||||
if os.path.split(curLib)[0] != path:
|
||||
setLastFileToolLibrary('') # a path is known but not specific file
|
||||
return preferences().SetString(LastPathToolLibrary, path)
|
||||
|
||||
|
||||
def lastPathToolShape():
|
||||
return preferences().GetString(LastPathToolShape, pathDefaultToolsPath('Shape'))
|
||||
|
||||
|
||||
def setLastPathToolShape(path):
|
||||
return preferences().SetString(LastPathToolShape, path)
|
||||
|
||||
|
||||
def lastPathToolTable():
|
||||
return preferences().GetString(LastPathToolTable, "")
|
||||
|
||||
|
||||
def setLastPathToolTable(table):
|
||||
return preferences().SetString(LastPathToolTable, table)
|
||||
|
||||
@@ -45,16 +45,17 @@ __doc__ = "Class to deal with and represent a tool bit."
|
||||
# PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
|
||||
# PathLog.trackModule()
|
||||
|
||||
|
||||
def translate(context, text, disambig=None):
|
||||
return PySide.QtCore.QCoreApplication.translate(context, text, disambig)
|
||||
|
||||
|
||||
ParameterTypeConstraint = {
|
||||
'Angle': 'App::PropertyAngle',
|
||||
'Distance': 'App::PropertyLength',
|
||||
'DistanceX': 'App::PropertyLength',
|
||||
'DistanceY': 'App::PropertyLength',
|
||||
'Radius': 'App::PropertyLength'
|
||||
}
|
||||
'Radius': 'App::PropertyLength'}
|
||||
|
||||
|
||||
def _findTool(path, typ, dbg=False):
|
||||
@@ -83,20 +84,27 @@ def _findTool(path, typ, dbg=False):
|
||||
|
||||
return searchFor(path, '')
|
||||
|
||||
|
||||
def findShape(path):
|
||||
'''findShape(path) ... search for path, full and partially in all known shape directories.'''
|
||||
'''
|
||||
findShape(path) ... search for path, full and partially
|
||||
in all known shape directories.
|
||||
'''
|
||||
return _findTool(path, 'Shape')
|
||||
|
||||
|
||||
def findBit(path):
|
||||
if path.endswith('.fctb'):
|
||||
return _findTool(path, 'Bit')
|
||||
return _findTool("{}.fctb".format(path), 'Bit')
|
||||
|
||||
|
||||
def findLibrary(path, dbg=False):
|
||||
if path.endswith('.fctl'):
|
||||
return _findTool(path, 'Library', dbg)
|
||||
return _findTool("{}.fctl".format(path), 'Library', dbg)
|
||||
|
||||
|
||||
def _findRelativePath(path, typ):
|
||||
relative = path
|
||||
for p in PathPreferences.searchPathsTool(typ):
|
||||
@@ -108,15 +116,19 @@ def _findRelativePath(path, typ):
|
||||
relative = p
|
||||
return relative
|
||||
|
||||
|
||||
def findRelativePathShape(path):
|
||||
return _findRelativePath(path, 'Shape')
|
||||
|
||||
|
||||
def findRelativePathTool(path):
|
||||
return _findRelativePath(path, 'Bit')
|
||||
|
||||
|
||||
def findRelativePathLibrary(path):
|
||||
return _findRelativePath(path, 'Library')
|
||||
|
||||
|
||||
def updateConstraint(sketch, name, value):
|
||||
for i, constraint in enumerate(sketch.Constraints):
|
||||
if constraint.Name.split(';')[0] == name:
|
||||
@@ -128,7 +140,9 @@ def updateConstraint(sketch, name, value):
|
||||
|
||||
if constr is not None:
|
||||
if not PathGeom.isRoughly(constraint.Value, value.Value):
|
||||
PathLog.track(name, constraint.Type, 'update', i, "(%.2f -> %.2f)" % (constraint.Value, value.Value))
|
||||
PathLog.track(name, constraint.Type,
|
||||
'update', i, "(%.2f -> %.2f)"
|
||||
% (constraint.Value, value.Value))
|
||||
sketch.delConstraint(i)
|
||||
sketch.recompute()
|
||||
n = sketch.addConstraint(constr)
|
||||
@@ -141,15 +155,21 @@ def updateConstraint(sketch, name, value):
|
||||
PropertyGroupBit = 'Bit'
|
||||
PropertyGroupAttribute = 'Attribute'
|
||||
|
||||
|
||||
class ToolBit(object):
|
||||
|
||||
def __init__(self, obj, shapeFile):
|
||||
PathLog.track(obj.Label, shapeFile)
|
||||
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::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'))
|
||||
if shapeFile is None:
|
||||
obj.BitShape = 'endmill.fcstd'
|
||||
self._setupBitShape(obj)
|
||||
@@ -184,14 +204,14 @@ class ToolBit(object):
|
||||
for prop in self.propertyNamesBit(obj):
|
||||
obj.setEditorMode(prop, 1)
|
||||
# I currently don't see why these need to be read-only
|
||||
#for prop in self.propertyNamesAttribute(obj):
|
||||
# for prop in self.propertyNamesAttribute(obj):
|
||||
# obj.setEditorMode(prop, 1)
|
||||
|
||||
def onChanged(self, obj, prop):
|
||||
PathLog.track(obj.Label, prop)
|
||||
if prop == 'BitShape' and not 'Restore' in obj.State:
|
||||
if prop == 'BitShape' and 'Restore' not in obj.State:
|
||||
self._setupBitShape(obj)
|
||||
#elif obj.getGroupOfProperty(prop) == PropertyGroupBit:
|
||||
# elif obj.getGroupOfProperty(prop) == PropertyGroupBit:
|
||||
# self._updateBitShape(obj, [prop])
|
||||
|
||||
def onDelete(self, obj, arg2=None):
|
||||
@@ -200,7 +220,7 @@ class ToolBit(object):
|
||||
obj.Document.removeObject(obj.Name)
|
||||
|
||||
def _updateBitShape(self, obj, properties=None):
|
||||
if not obj.BitBody is None:
|
||||
if obj.BitBody is not None:
|
||||
if not properties:
|
||||
properties = self.propertyNamesBit(obj)
|
||||
for prop in properties:
|
||||
@@ -286,7 +306,7 @@ class ToolBit(object):
|
||||
prop = parts[0]
|
||||
desc = ''
|
||||
if len(parts) > 1:
|
||||
desc = parts[1]
|
||||
desc = parts[1]
|
||||
obj.addProperty(typ, prop, PropertyGroupBit, desc)
|
||||
obj.setEditorMode(prop, 1)
|
||||
value = constraint.Value
|
||||
@@ -315,12 +335,13 @@ class ToolBit(object):
|
||||
obj.File = path
|
||||
return True
|
||||
except (OSError, IOError) as e:
|
||||
PathLog.error("Could not save tool %s to %s (%s)" % (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['version'] = 2 # Path.Tool is version 1
|
||||
attrs['name'] = obj.Label
|
||||
if PathPreferences.toolsStoreAbsolutePaths():
|
||||
attrs['shape'] = obj.BitShape
|
||||
@@ -332,7 +353,6 @@ class ToolBit(object):
|
||||
attrs['parameter'] = params
|
||||
params = {}
|
||||
for name in self.propertyNamesAttribute(obj):
|
||||
#print(f"shapeattr {name}")
|
||||
if name == "UserAttributes":
|
||||
for key, value in obj.UserAttributes.items():
|
||||
params[key] = value
|
||||
@@ -341,20 +361,33 @@ class ToolBit(object):
|
||||
attrs['attribute'] = params
|
||||
return attrs
|
||||
|
||||
|
||||
def Declaration(path):
|
||||
with open(path, 'r') as fp:
|
||||
return json.load(fp)
|
||||
|
||||
|
||||
class AttributePrototype(PathSetupSheetOpPrototype.OpPrototype):
|
||||
|
||||
def __init__(self):
|
||||
PathSetupSheetOpPrototype.OpPrototype.__init__(self, 'ToolBitAttribute')
|
||||
self.addProperty('App::PropertyEnumeration', 'Material', PropertyGroupAttribute, translate('PathToolBit', 'Tool bit material'))
|
||||
self.Material = ['Carbide', 'CastAlloy', 'Ceramics', 'Diamond', 'HighCarbonToolSteel', 'HighSpeedSteel', 'Sialon']
|
||||
self.addProperty('App::PropertyDistance', 'LengthOffset', PropertyGroupAttribute, translate('PathToolBit', 'Length offset in Z direction'))
|
||||
self.addProperty('App::PropertyInteger', 'Flutes', PropertyGroupAttribute, translate('PathToolBit', 'The number of flutes'))
|
||||
self.addProperty('App::PropertyDistance', 'ChipLoad', PropertyGroupAttribute, translate('PathToolBit', 'Chipload as per manufacturer'))
|
||||
self.addProperty('App::PropertyMap', 'UserAttributes', PropertyGroupAttribute, translate('PathTooolBit', 'User Defined Values'))
|
||||
self.addProperty('App::PropertyEnumeration', 'Material',
|
||||
PropertyGroupAttribute,
|
||||
translate('PathToolBit', 'Tool bit material'))
|
||||
self.Material = ['Carbide', 'CastAlloy', 'Ceramics', 'Diamond',
|
||||
'HighCarbonToolSteel', 'HighSpeedSteel', 'Sialon']
|
||||
self.addProperty('App::PropertyDistance', 'LengthOffset',
|
||||
PropertyGroupAttribute, translate('PathToolBit',
|
||||
'Length offset in Z direction'))
|
||||
self.addProperty('App::PropertyInteger', 'Flutes',
|
||||
PropertyGroupAttribute, translate('PathToolBit',
|
||||
'The number of flutes'))
|
||||
self.addProperty('App::PropertyDistance', 'ChipLoad',
|
||||
PropertyGroupAttribute, translate('PathToolBit',
|
||||
'Chipload as per manufacturer'))
|
||||
self.addProperty('App::PropertyMap', 'UserAttributes',
|
||||
PropertyGroupAttribute, translate('PathToolBit',
|
||||
'User Defined Values'))
|
||||
|
||||
|
||||
class ToolBitFactory(object):
|
||||
@@ -372,23 +405,24 @@ class ToolBitFactory(object):
|
||||
proto = AttributePrototype()
|
||||
uservals = {}
|
||||
for pname in params:
|
||||
#print(f"pname: {pname}")
|
||||
# print(f"pname: {pname}")
|
||||
try:
|
||||
prop = proto.getProperty(pname)
|
||||
val = prop.valueFromString(params[pname])
|
||||
# val = prop.valueFromString(params[pname])
|
||||
prop.setupProperty(obj, pname, PropertyGroupAttribute, prop.valueFromString(params[pname]))
|
||||
except:
|
||||
except Exception:
|
||||
# prop = obj.addProperty('App::PropertyString', pname, "Attribute", translate('PathTooolBit', 'User Defined Value'))
|
||||
# setattr(obj, pname, params[pname])
|
||||
prop = proto.getProperty("UserAttributes")
|
||||
uservals.update({pname: params[pname]})
|
||||
#prop.setupProperty(obj, pname, "UserAttributes", prop.valueFromString(params[pname]))
|
||||
# prop.setupProperty(obj, pname, "UserAttributes", prop.valueFromString(params[pname]))
|
||||
|
||||
if len(uservals.items()) > 0:
|
||||
prop.setupProperty(obj, "UserAttributes", PropertyGroupAttribute, uservals)
|
||||
prop.setupProperty(obj, "UserAttributes",
|
||||
PropertyGroupAttribute, uservals)
|
||||
|
||||
# print("prop[%s] = %s (%s)" % (pname, params[pname], type(val)))
|
||||
#prop.setupProperty(obj, pname, PropertyGroupAttribute, prop.valueFromString(params[pname]))
|
||||
# prop.setupProperty(obj, pname, PropertyGroupAttribute, prop.valueFromString(params[pname]))
|
||||
return obj
|
||||
|
||||
def CreateFrom(self, path, name='ToolBit'):
|
||||
@@ -406,4 +440,5 @@ class ToolBitFactory(object):
|
||||
obj.Proxy = ToolBit(obj, shapeFile)
|
||||
return obj
|
||||
|
||||
|
||||
Factory = ToolBitFactory()
|
||||
|
||||
@@ -45,13 +45,15 @@ class ToolBitEditor(object):
|
||||
The controller embeds the UI to the parentWidget which has to have a layout attached to it.
|
||||
'''
|
||||
|
||||
def __init__(self, tool, parentWidget=None):
|
||||
def __init__(self, tool, parentWidget=None, ondone=None):
|
||||
self.form = FreeCADGui.PySideUic.loadUi(":/panels/ToolBitEditor.ui")
|
||||
|
||||
if parentWidget:
|
||||
self.form.setParent(parentWidget)
|
||||
parentWidget.layout().addWidget(self.form)
|
||||
|
||||
self.ondone = ondone
|
||||
|
||||
self.tool = tool
|
||||
if not tool.BitShape:
|
||||
self.tool.BitShape = 'endmill.fcstd'
|
||||
@@ -210,6 +212,9 @@ class ToolBitEditor(object):
|
||||
self.form.shapePath.setText(foo[0])
|
||||
self.updateShape()
|
||||
|
||||
def ok(self):
|
||||
self.form.close()
|
||||
|
||||
def setupUI(self):
|
||||
PathLog.track()
|
||||
self.updateUI()
|
||||
@@ -217,3 +222,8 @@ class ToolBitEditor(object):
|
||||
self.form.toolName.editingFinished.connect(self.refresh)
|
||||
self.form.shapePath.editingFinished.connect(self.updateShape)
|
||||
self.form.shapeSet.clicked.connect(self.selectShape)
|
||||
self.form.buttonBox.accepted.connect(self.ok)
|
||||
self.form.buttonBox.rejected.connect(self.ok)
|
||||
if self.ondone is not None:
|
||||
self.form.buttonBox.rejected.connect(self.ondone)
|
||||
|
||||
|
||||
@@ -280,6 +280,23 @@ def GetToolFiles(parent = None):
|
||||
return foo[0]
|
||||
return []
|
||||
|
||||
def GetToolShapeFile(parent = None):
|
||||
if parent is None:
|
||||
parent = QtGui.QApplication.activeWindow()
|
||||
|
||||
location = PathPreferences.lastPathToolShape()
|
||||
if os.path.isfile(location):
|
||||
location = os.path.split(location)[0]
|
||||
elif not os.path.isdir(location):
|
||||
location = PathPreferences.filePath()
|
||||
|
||||
fname = QtGui.QFileDialog.getOpenFileName(parent, 'Select Tool Shape', location, '*.fcstd')
|
||||
if fname and fname[0]:
|
||||
if fname != location:
|
||||
PathPreferences.setLastPathToolShape(location)
|
||||
return fname[0]
|
||||
else:
|
||||
return None
|
||||
|
||||
def LoadTool(parent = None):
|
||||
'''LoadTool(parent=None) ... Open a file dialog to load a tool from a file.'''
|
||||
|
||||
@@ -25,9 +25,10 @@ import FreeCADGui
|
||||
import PySide.QtCore as QtCore
|
||||
import PathScripts.PathPreferences as PathPreferences
|
||||
|
||||
class CommandToolBitLibraryOpen:
|
||||
|
||||
class CommandToolBitSelectorOpen:
|
||||
'''
|
||||
Command to ToolBitLibrary editor.
|
||||
Command to toggle the ToolBitSelector Dock
|
||||
'''
|
||||
|
||||
def __init__(self):
|
||||
@@ -35,11 +36,40 @@ class CommandToolBitLibraryOpen:
|
||||
|
||||
def GetResources(self):
|
||||
return {'Pixmap': 'Path-ToolTable',
|
||||
'MenuText': QtCore.QT_TRANSLATE_NOOP("PathToolBitLibrary", "Open ToolBit Library editor"),
|
||||
'MenuText': QtCore.QT_TRANSLATE_NOOP("PathToolBitLibrary", "ToolBit Dock"),
|
||||
'ToolTip': QtCore.QT_TRANSLATE_NOOP("PathToolBitLibrary", "Toggle the Toolbit Dock"),
|
||||
'Accel': "P, T"}
|
||||
|
||||
def IsActive(self):
|
||||
return FreeCAD.ActiveDocument is not None
|
||||
|
||||
def Activated(self):
|
||||
import PathScripts.PathToolBitLibraryGui as PathToolBitLibraryGui
|
||||
dock = PathToolBitLibraryGui.ToolBitSelector()
|
||||
|
||||
lastlib = PathPreferences.lastPathToolLibrary()
|
||||
|
||||
if PathPreferences.toolsOpenLastLibrary():
|
||||
dock.open(lastlib)
|
||||
else:
|
||||
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")}
|
||||
|
||||
def IsActive(self):
|
||||
return True
|
||||
return FreeCAD.ActiveDocument is not None
|
||||
|
||||
def Activated(self):
|
||||
import PathScripts.PathToolBitLibraryGui as PathToolBitLibraryGui
|
||||
@@ -52,55 +82,56 @@ class CommandToolBitLibraryOpen:
|
||||
else:
|
||||
library.open()
|
||||
|
||||
class CommandToolBitLibraryLoad:
|
||||
'''
|
||||
Command used to load an entire ToolBitLibrary (or part of it) from a file into a job.
|
||||
'''
|
||||
# class CommandToolBitLibraryLoad:
|
||||
# '''
|
||||
# Command used to load an entire ToolBitLibrary (or part of it) from a file into a job.
|
||||
# '''
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
# def __init__(self):
|
||||
# pass
|
||||
|
||||
def GetResources(self):
|
||||
return {'Pixmap': 'Path-ToolTable',
|
||||
'MenuText': QtCore.QT_TRANSLATE_NOOP("PathToolBitLibrary", "Load ToolBit Library"),
|
||||
'ToolTip': QtCore.QT_TRANSLATE_NOOP("PathToolBitLibrary", "Load an entire ToolBit library or part of it into a job")}
|
||||
# def GetResources(self):
|
||||
# return {'Pixmap': 'Path-ToolTable',
|
||||
# 'MenuText': QtCore.QT_TRANSLATE_NOOP("PathToolBitLibrary", "Load ToolBit Library"),
|
||||
# 'ToolTip': QtCore.QT_TRANSLATE_NOOP("PathToolBitLibrary", "Load an entire ToolBit library or part of it into a job")}
|
||||
|
||||
def selectedJob(self):
|
||||
if FreeCAD.ActiveDocument:
|
||||
sel = FreeCADGui.Selection.getSelectionEx()
|
||||
if sel and sel[0].Object.Name[:3] == 'Job':
|
||||
return sel[0].Object
|
||||
jobs = [o for o in FreeCAD.ActiveDocument.Objects if o.Name[:3] == 'Job']
|
||||
if 1 == len(jobs):
|
||||
return jobs[0]
|
||||
return None
|
||||
# def selectedJob(self):
|
||||
# if FreeCAD.ActiveDocument:
|
||||
# sel = FreeCADGui.Selection.getSelectionEx()
|
||||
# if sel and sel[0].Object.Name[:3] == 'Job':
|
||||
# return sel[0].Object
|
||||
# jobs = [o for o in FreeCAD.ActiveDocument.Objects if o.Name[:3] == 'Job']
|
||||
# if 1 == len(jobs):
|
||||
# return jobs[0]
|
||||
# return None
|
||||
|
||||
def IsActive(self):
|
||||
return not self.selectedJob() is None
|
||||
# def IsActive(self):
|
||||
# return not self.selectedJob() is None
|
||||
|
||||
def Activated(self):
|
||||
job = self.selectedJob()
|
||||
self.Execute(job)
|
||||
# def Activated(self):
|
||||
# job = self.selectedJob()
|
||||
# self.Execute(job)
|
||||
|
||||
@classmethod
|
||||
def Execute(cls, job):
|
||||
import PathScripts.PathToolBitLibraryGui as PathToolBitLibraryGui
|
||||
import PathScripts.PathToolControllerGui as PathToolControllerGui
|
||||
# @classmethod
|
||||
# def Execute(cls, job):
|
||||
# import PathScripts.PathToolBitLibraryGui as PathToolBitLibraryGui
|
||||
# import PathScripts.PathToolControllerGui as PathToolControllerGui
|
||||
|
||||
library = PathToolBitLibraryGui.ToolBitLibrary()
|
||||
# library = PathToolBitLibraryGui.ToolBitLibrary()
|
||||
|
||||
if 1 == library.open() and job:
|
||||
for nr, tool in library.selectedOrAllTools():
|
||||
tc = PathToolControllerGui.Create("TC: {}".format(tool.Label), tool, nr)
|
||||
job.Proxy.addToolController(tc)
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
return True
|
||||
return False
|
||||
# if 1 == library.open() and job:
|
||||
# for nr, tool in library.selectedOrAllTools():
|
||||
# tc = PathToolControllerGui.Create("TC: {}".format(tool.Label), tool, nr)
|
||||
# job.Proxy.addToolController(tc)
|
||||
# FreeCAD.ActiveDocument.recompute()
|
||||
# return True
|
||||
# return False
|
||||
|
||||
if FreeCAD.GuiUp:
|
||||
FreeCADGui.addCommand('Path_ToolBitLibraryOpen', CommandToolBitLibraryOpen())
|
||||
FreeCADGui.addCommand('Path_ToolBitLibraryLoad', CommandToolBitLibraryLoad())
|
||||
FreeCADGui.addCommand('Path_ToolBitDock', CommandToolBitSelectorOpen())
|
||||
|
||||
CommandList = ['Path_ToolBitLibraryOpen', 'Path_ToolBitLibraryLoad']
|
||||
BarList = ['Path_ToolBitDock']
|
||||
MenuList = ['Path_ToolBitLibraryOpen', 'Path_ToolBitDock']
|
||||
|
||||
FreeCAD.Console.PrintLog("Loading PathToolBitLibraryCmd... done\n")
|
||||
|
||||
@@ -35,12 +35,13 @@ from PySide import QtCore, QtGui
|
||||
import PySide
|
||||
import json
|
||||
import os
|
||||
import glob
|
||||
import traceback
|
||||
import uuid as UUID
|
||||
from functools import partial
|
||||
|
||||
# PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
|
||||
# PathLog.trackModule(PathLog.thisModule())
|
||||
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
|
||||
PathLog.trackModule(PathLog.thisModule())
|
||||
|
||||
_UuidRole = PySide.QtCore.Qt.UserRole + 1
|
||||
_PathRole = PySide.QtCore.Qt.UserRole + 2
|
||||
@@ -55,11 +56,11 @@ class _TableView(PySide.QtGui.QTableView):
|
||||
|
||||
def __init__(self, parent):
|
||||
PySide.QtGui.QTableView.__init__(self, parent)
|
||||
self.setDragEnabled(True)
|
||||
self.setAcceptDrops(True)
|
||||
self.setDropIndicatorShown(True)
|
||||
self.setDragDropMode(PySide.QtGui.QAbstractItemView.InternalMove)
|
||||
self.setDefaultDropAction(PySide.QtCore.Qt.MoveAction)
|
||||
self.setDragEnabled(False)
|
||||
self.setAcceptDrops(False)
|
||||
self.setDropIndicatorShown(False)
|
||||
self.setDragDropMode(PySide.QtGui.QAbstractItemView.DragOnly)
|
||||
self.setDefaultDropAction(PySide.QtCore.Qt.IgnoreAction)
|
||||
self.setSortingEnabled(True)
|
||||
self.setSelectionBehavior(PySide.QtGui.QAbstractItemView.SelectRows)
|
||||
self.verticalHeader().hide()
|
||||
@@ -68,18 +69,18 @@ class _TableView(PySide.QtGui.QTableView):
|
||||
return [PySide.QtCore.Qt.CopyAction, PySide.QtCore.Qt.MoveAction]
|
||||
|
||||
def _uuidOfRow(self, row):
|
||||
model = self.model()
|
||||
model = self.toolModel()
|
||||
return model.data(model.index(row, 0), _UuidRole)
|
||||
|
||||
def _rowWithUuid(self, uuid):
|
||||
model = self.model()
|
||||
model = self.toolModel()
|
||||
for row in range(model.rowCount()):
|
||||
if self._uuidOfRow(row) == uuid:
|
||||
return row
|
||||
return None
|
||||
|
||||
def _copyTool(self, uuid_, dstRow):
|
||||
model = self.model()
|
||||
model = self.toolModel()
|
||||
model.insertRow(dstRow)
|
||||
srcRow = self._rowWithUuid(uuid_)
|
||||
for col in range(model.columnCount()):
|
||||
@@ -108,23 +109,9 @@ class _TableView(PySide.QtGui.QTableView):
|
||||
# pylint: disable=unused-variable
|
||||
row = stream.readInt32()
|
||||
srcRows.append(row)
|
||||
# col = stream.readInt32()
|
||||
# PathLog.track(row, col)
|
||||
# cnt = stream.readInt32()
|
||||
# for i in range(cnt):
|
||||
# key = stream.readInt32()
|
||||
# val = stream.readQVariant()
|
||||
# PathLog.track(' ', i, key, val, type(val))
|
||||
# I have no idea what these three integers are,
|
||||
# or if they even are three integers,
|
||||
# but it seems to work out this way.
|
||||
# i0 = stream.readInt32()
|
||||
# i1 = stream.readInt32()
|
||||
# i2 = stream.readInt32()
|
||||
# PathLog.track(' ', i0, i1, i2)
|
||||
|
||||
# get the uuids of all srcRows
|
||||
model = self.model()
|
||||
model = self.toolModel()
|
||||
srcUuids = [self._uuidOfRow(row) for row in set(srcRows)]
|
||||
destRow = self.rowAt(event.pos().y())
|
||||
|
||||
@@ -134,264 +121,378 @@ class _TableView(PySide.QtGui.QTableView):
|
||||
model.removeRow(self._rowWithUuid(uuid))
|
||||
|
||||
|
||||
class ToolBitLibrary(object):
|
||||
'''ToolBitLibrary is the controller for displaying/selecting/creating/editing a collection of ToolBits.'''
|
||||
class ModelFactory(object):
|
||||
''' Helper class to generate qtdata models for toolbit libraries
|
||||
'''
|
||||
|
||||
def __init__(self, path=None):
|
||||
self.path = path
|
||||
PathLog.track()
|
||||
self.path = ""
|
||||
# self.currentLib = ""
|
||||
|
||||
|
||||
def __libraryLoad(self, path, datamodel):
|
||||
PathLog.track(path)
|
||||
PathPreferences.setLastFileToolLibrary(path)
|
||||
# self.currenLib = path
|
||||
|
||||
with open(path) as fp:
|
||||
library = json.load(fp)
|
||||
|
||||
for toolBit in library['tools']:
|
||||
nr = toolBit['nr']
|
||||
bit = PathToolBit.findBit(toolBit['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']))
|
||||
|
||||
def _toolAdd(self, nr, tool, path):
|
||||
|
||||
strShape = os.path.splitext(os.path.basename(tool['shape']))[0]
|
||||
strDiam = tool['parameter']['Diameter']
|
||||
tooltip = "{}: {}".format(strShape, strDiam)
|
||||
|
||||
toolNr = PySide.QtGui.QStandardItem()
|
||||
toolNr.setData(nr, PySide.QtCore.Qt.EditRole)
|
||||
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.setEditable(False)
|
||||
toolName.setToolTip(tooltip)
|
||||
|
||||
toolShape = PySide.QtGui.QStandardItem()
|
||||
toolShape.setData(strShape, PySide.QtCore.Qt.EditRole)
|
||||
toolShape.setEditable(False)
|
||||
|
||||
toolDiameter = PySide.QtGui.QStandardItem()
|
||||
toolDiameter.setData(strDiam, PySide.QtCore.Qt.EditRole)
|
||||
toolDiameter.setEditable(False)
|
||||
|
||||
return [toolNr, toolName, toolShape, toolDiameter]
|
||||
|
||||
def newTool(self, datamodel, path):
|
||||
'''
|
||||
Adds a toolbit item to a model
|
||||
'''
|
||||
PathLog.track()
|
||||
|
||||
try:
|
||||
nr = 0
|
||||
for row in range(datamodel.rowCount()):
|
||||
itemNr = int(datamodel.item(row, 0).data(PySide.QtCore.Qt.EditRole))
|
||||
nr = max(nr, itemNr)
|
||||
nr += 1
|
||||
tool = PathToolBit.Declaration(path)
|
||||
except Exception:
|
||||
PathLog.error(traceback.print_exc())
|
||||
|
||||
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 + '/*.fctl')]
|
||||
libFiles.sort()
|
||||
for libFile in libFiles:
|
||||
loc, fnlong = os.path.split(libFile)
|
||||
fn, ext = os.path.splitext(fnlong)
|
||||
libItem = QtGui.QStandardItem(fn)
|
||||
libItem.setToolTip(loc)
|
||||
libItem.setData(libFile, _PathRole)
|
||||
libItem.setIcon(QtGui.QPixmap(':/icons/Path-ToolTable.svg'))
|
||||
model.appendRow(libItem)
|
||||
|
||||
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 == "":
|
||||
lib = PathPreferences.lastFileToolLibrary()
|
||||
|
||||
if os.path.isfile(lib): # An individual library is wanted
|
||||
self.__libraryLoad(lib, model)
|
||||
|
||||
PathLog.debug('model rows: {}'.format(model.rowCount()))
|
||||
return model
|
||||
|
||||
|
||||
class ToolBitSelector(object):
|
||||
'''Controller for displaying a library and creating ToolControllers'''
|
||||
|
||||
def __init__(self):
|
||||
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']
|
||||
|
||||
def curLib(self):
|
||||
libfile = os.path.split(PathPreferences.lastFileToolLibrary())[1]
|
||||
libName = os.path.splitext(libfile)[0]
|
||||
return libName
|
||||
|
||||
def loadData(self):
|
||||
PathLog.track()
|
||||
self.toolModel.clear()
|
||||
self.toolModel.setHorizontalHeaderLabels(self.columnNames())
|
||||
self.form.lblLibrary.setText(self.curLib())
|
||||
self.factory.libraryOpen(self.toolModel)
|
||||
self.toolModel.takeColumn(3)
|
||||
self.toolModel.takeColumn(2)
|
||||
|
||||
def setupUI(self):
|
||||
PathLog.track()
|
||||
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.libraryEditorOpen.clicked.connect(self.libraryEditorOpen)
|
||||
self.form.addToolController.clicked.connect(self.selectedOrAllToolControllers)
|
||||
|
||||
def enableButtons(self):
|
||||
selected = (len(self.form.tools.selectedIndexes()) >= 1)
|
||||
if selected:
|
||||
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):
|
||||
library = ToolBitLibrary()
|
||||
library.open()
|
||||
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):
|
||||
if item.child(i).column() == 0:
|
||||
itemsToProcess.append(item.child(i))
|
||||
|
||||
elif item.column() == 0:
|
||||
itemsToProcess.append(item)
|
||||
|
||||
tools = []
|
||||
for item in itemsToProcess:
|
||||
toolNr = int(item.data(PySide.QtCore.Qt.EditRole))
|
||||
toolPath = item.data(_PathRole)
|
||||
tools.append((toolNr, PathToolBit.Factory.CreateFrom(toolPath)))
|
||||
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
|
||||
elif len(jobs) == 1:
|
||||
job = jobs[0]
|
||||
else:
|
||||
userinput = PathUtilsGui.PathUtilsUserInput()
|
||||
job = userinput.chooseJob(jobs)
|
||||
|
||||
if job is None: # user may have canceled
|
||||
return
|
||||
|
||||
tools = self.selectedOrAllTools()
|
||||
|
||||
for tool in tools:
|
||||
tc = PathToolControllerGui.Create(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'''
|
||||
docs = FreeCADGui.getMainWindow().findChildren(QtGui.QDockWidget)
|
||||
for doc in docs:
|
||||
if doc.objectName() == "ToolSelector":
|
||||
if doc.isVisible():
|
||||
doc.deleteLater()
|
||||
return
|
||||
else:
|
||||
doc.setVisible(True)
|
||||
|
||||
mw = FreeCADGui.getMainWindow()
|
||||
mw.addDockWidget(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.'''
|
||||
|
||||
def __init__(self):
|
||||
PathLog.track()
|
||||
self.factory = ModelFactory()
|
||||
self.toolModel = PySide.QtGui.QStandardItemModel(0, len(self.columnNames()))
|
||||
self.listModel = PySide.QtGui.QStandardItemModel()
|
||||
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.toolTable.hide()
|
||||
self.setupUI()
|
||||
self.title = self.form.windowTitle()
|
||||
self.LibFiles = []
|
||||
if path:
|
||||
self.libraryLoad(path)
|
||||
|
||||
self.form.addToolController.setEnabled(False)
|
||||
self.form.ButtonRemoveToolTable.setEnabled(False)
|
||||
self.form.ButtonRenameToolTable.setEnabled(False)
|
||||
|
||||
def _toolAdd(self, nr, tool, path):
|
||||
toolNr = PySide.QtGui.QStandardItem()
|
||||
toolNr.setData(nr, PySide.QtCore.Qt.EditRole)
|
||||
toolNr.setData(path, _PathRole)
|
||||
toolNr.setData(UUID.uuid4(), _UuidRole)
|
||||
|
||||
toolName = PySide.QtGui.QStandardItem()
|
||||
toolName.setData(tool['name'], PySide.QtCore.Qt.EditRole)
|
||||
toolName.setEditable(False)
|
||||
|
||||
toolShape = PySide.QtGui.QStandardItem()
|
||||
toolShape.setData(os.path.splitext(os.path.basename(tool['shape']))[0], PySide.QtCore.Qt.EditRole)
|
||||
toolShape.setEditable(False)
|
||||
|
||||
toolDiameter = PySide.QtGui.QStandardItem()
|
||||
toolDiameter.setData(tool['parameter']['Diameter'], PySide.QtCore.Qt.EditRole)
|
||||
toolDiameter.setEditable(False)
|
||||
|
||||
self.model.appendRow([toolNr, toolName, toolShape, toolDiameter])
|
||||
|
||||
def toolAdd(self):
|
||||
def toolBitNew(self):
|
||||
PathLog.track()
|
||||
# pylint: disable=broad-except
|
||||
try:
|
||||
nr = 0
|
||||
for row in range(self.model.rowCount()):
|
||||
itemNr = int(self.model.item(row, 0).data(PySide.QtCore.Qt.EditRole))
|
||||
nr = max(nr, itemNr)
|
||||
nr += 1
|
||||
|
||||
for i, foo in enumerate(PathToolBitGui.GetToolFiles(self.form)):
|
||||
tool = PathToolBit.Declaration(foo)
|
||||
self._toolAdd(nr + i, tool, foo)
|
||||
self.toolTableView.resizeColumnsToContents()
|
||||
except Exception:
|
||||
PathLog.error('something happened')
|
||||
PathLog.error(traceback.print_exc())
|
||||
# select the shape file
|
||||
shapefile = PathToolBitGui.GetToolShapeFile()
|
||||
if shapefile is None: # user canceled
|
||||
return
|
||||
|
||||
def selectedOrAllTools(self):
|
||||
selectedRows = set([index.row() for index in self.toolTableView.selectedIndexes()])
|
||||
if not selectedRows:
|
||||
selectedRows = list(range(self.model.rowCount()))
|
||||
tools = []
|
||||
for row in selectedRows:
|
||||
item = self.model.item(row, 0)
|
||||
toolNr = int(item.data(PySide.QtCore.Qt.EditRole))
|
||||
toolPath = item.data(_PathRole)
|
||||
tools.append((toolNr, PathToolBit.Factory.CreateFrom(toolPath)))
|
||||
return tools
|
||||
|
||||
def selectedOrAllToolControllers(self):
|
||||
tools = self.selectedOrAllTools()
|
||||
filename = PathToolBitGui.GetNewToolFile()
|
||||
if filename == None:
|
||||
return
|
||||
|
||||
userinput = PathUtilsGui.PathUtilsUserInput()
|
||||
job = userinput.chooseJob(PathUtilsGui.PathUtils.GetJobs())
|
||||
for tool in tools:
|
||||
print(tool)
|
||||
tc = PathToolControllerGui.Create(tool[1].Label, tool[1], tool[0])
|
||||
job.Proxy.addToolController(tc)
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
# Parse out the name of the file and write the structure
|
||||
loc, fil = os.path.split(filename)
|
||||
fname = os.path.splitext(fil)[0]
|
||||
fullpath = "{}/{}.fctb".format(loc, fname)
|
||||
PathLog.debug(fullpath)
|
||||
|
||||
f = PathToolBit.ToolBitFactory()
|
||||
newtool = f.Create(name=fname)
|
||||
newtool.BitShape = shapefile
|
||||
newtool.Label = fname
|
||||
newtool.Proxy.saveToFile(newtool, fullpath)
|
||||
|
||||
# add it to the model
|
||||
self.factory.newTool(self.toolModel, fullpath)
|
||||
|
||||
def toolBitExisting(self):
|
||||
|
||||
filenames = PathToolBitGui.GetToolFiles()
|
||||
|
||||
if len(filenames) == 0:
|
||||
return
|
||||
|
||||
for f in filenames:
|
||||
|
||||
loc, fil = os.path.split(f)
|
||||
fname = os.path.splitext(fil)[0]
|
||||
fullpath = "{}/{}.fctb".format(loc, fname)
|
||||
|
||||
self.factory.newTool(self.toolModel, fullpath)
|
||||
|
||||
def toolDelete(self):
|
||||
PathLog.track()
|
||||
selectedRows = set([index.row() for index in self.toolTableView.selectedIndexes()])
|
||||
for row in sorted(list(selectedRows), key=lambda r: -r):
|
||||
self.model.removeRows(row, 1)
|
||||
|
||||
def libraryDelete(self):
|
||||
PathLog.track()
|
||||
reply = QtGui.QMessageBox.question(self.form, 'Warning', "Delete " + os.path.basename(self.path) + "?", QtGui.QMessageBox.Yes | QtGui.QMessageBox.Cancel)
|
||||
if reply == QtGui.QMessageBox.Yes and len(self.path) > 0:
|
||||
os.remove(self.path)
|
||||
PathPreferences.setLastPathToolTable("")
|
||||
self.libraryOpen(filedialog=False)
|
||||
|
||||
def toolEnumerate(self):
|
||||
PathLog.track()
|
||||
for row in range(self.model.rowCount()):
|
||||
self.model.setData(self.model.index(row, 0), row + 1, PySide.QtCore.Qt.EditRole)
|
||||
self.toolModel.removeRows(row, 1)
|
||||
|
||||
def toolSelect(self, selected, deselected):
|
||||
# pylint: disable=unused-argument
|
||||
sel = len(self.toolTableView.selectedIndexes()) > 0
|
||||
self.form.toolDelete.setEnabled(sel)
|
||||
|
||||
if sel:
|
||||
self.form.addToolController.setEnabled(True)
|
||||
else:
|
||||
self.form.addToolController.setEnabled(False)
|
||||
|
||||
def tableSelected(self, index):
|
||||
''' loads the tools for the selected tool table '''
|
||||
name = self.form.TableList.itemWidget(self.form.TableList.itemFromIndex(index)).getTableName()
|
||||
self.libraryLoad(PathPreferences.lastPathToolLibrary() + '/' + name)
|
||||
self.form.ButtonRemoveToolTable.setEnabled(True)
|
||||
self.form.ButtonRenameToolTable.setEnabled(True)
|
||||
PathLog.track()
|
||||
item = index.model().itemFromIndex(index)
|
||||
libpath = item.data(_PathRole)
|
||||
self.loadData(libpath)
|
||||
self.path = libpath
|
||||
|
||||
def open(self, path=None, dialog=False):
|
||||
'''open(path=None, dialog=False) ... load library stored in path and bring up ui.
|
||||
Returns 1 if user pressed OK, 0 otherwise.'''
|
||||
if path:
|
||||
self.libraryOpen(path, filedialog=False)
|
||||
elif dialog:
|
||||
self.libraryOpen(None, True)
|
||||
else:
|
||||
self.libraryOpen(None, False)
|
||||
def open(self):
|
||||
PathLog.track()
|
||||
return self.form.exec_()
|
||||
|
||||
def updateToolbar(self):
|
||||
if self.path:
|
||||
self.form.librarySave.setEnabled(True)
|
||||
else:
|
||||
self.form.librarySave.setEnabled(False)
|
||||
|
||||
def libraryOpen(self, path=None, filedialog=True):
|
||||
import glob
|
||||
def libraryPath(self):
|
||||
PathLog.track()
|
||||
path = PySide.QtGui.QFileDialog.getExistingDirectory(self.form, 'Tool Library Path', PathPreferences.lastPathToolLibrary())
|
||||
if len(path) == 0:
|
||||
return
|
||||
|
||||
# Load default search path
|
||||
path = PathPreferences.lastPathToolLibrary()
|
||||
PathPreferences.setLastPathToolLibrary(path)
|
||||
self.loadData()
|
||||
|
||||
if filedialog or len(path) == 0:
|
||||
path = PySide.QtGui.QFileDialog.getExistingDirectory(self.form, 'Tool Library Path', PathPreferences.lastPathToolLibrary())
|
||||
if len(path) > 0:
|
||||
PathPreferences.setLastPathToolLibrary(path)
|
||||
else:
|
||||
return
|
||||
def toolEdit(self, selected):
|
||||
item = self.toolModel.item(selected.row(), 0)
|
||||
if selected.column() == 0: # editing Nr
|
||||
pass
|
||||
else:
|
||||
tbpath = item.data(_PathRole)
|
||||
|
||||
# Clear view
|
||||
self.form.TableList.clear()
|
||||
self.LibFiles.clear()
|
||||
self.form.lineLibPath.clear()
|
||||
self.form.lineLibPath.insert(path)
|
||||
temptool = PathToolBit.ToolBitFactory().CreateFrom(tbpath, 'temptool')
|
||||
self.editor = PathToolBitEdit.ToolBitEditor(temptool,
|
||||
self.form.toolTableGroup, ondone=self.toolEditDone)
|
||||
|
||||
# Find all tool tables in directory
|
||||
for file in glob.glob(path + '/*.fctl'):
|
||||
self.LibFiles.append(file)
|
||||
QBtn = QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel
|
||||
|
||||
self.LibFiles.sort()
|
||||
buttonBox = QtGui.QDialogButtonBox(QBtn)
|
||||
# self.buttonBox.accepted.connect(self.accept)
|
||||
# self.buttonBox.rejected.connect(self.reject)
|
||||
|
||||
# Add all tables to list
|
||||
for table in self.LibFiles:
|
||||
listWidgetItem = QtGui.QListWidgetItem()
|
||||
listItem = ToolTableListWidgetItem()
|
||||
listItem.setTableName(os.path.basename(table))
|
||||
listItem.setIcon(QtGui.QPixmap(':/icons/Path-ToolTable.svg'))
|
||||
listWidgetItem.setSizeHint(QtCore.QSize(0, 40))
|
||||
self.form.TableList.addItem(listWidgetItem)
|
||||
self.form.TableList.setItemWidget(listWidgetItem, listItem)
|
||||
layout = self.editor.form.layout() #QVBoxLayout()
|
||||
layout.addWidget(buttonBox)
|
||||
#self.setLayout(self.layout)
|
||||
|
||||
self.path = []
|
||||
self.form.ButtonRemoveToolTable.setEnabled(False)
|
||||
self.form.ButtonRenameToolTable.setEnabled(False)
|
||||
|
||||
self.toolTableView.setUpdatesEnabled(False)
|
||||
self.model.clear()
|
||||
self.model.setHorizontalHeaderLabels(self.columnNames())
|
||||
self.toolTableView.resizeColumnsToContents()
|
||||
self.toolTableView.setUpdatesEnabled(True)
|
||||
|
||||
# Search last selected table
|
||||
if len(self.LibFiles) > 0:
|
||||
for idx in range(len(self.LibFiles)):
|
||||
if PathPreferences.lastPathToolTable() == os.path.basename(self.LibFiles[idx]):
|
||||
break
|
||||
# Not found, select first entry
|
||||
if idx >= len(self.LibFiles):
|
||||
idx = 0
|
||||
|
||||
# Load selected table
|
||||
self.libraryLoad(self.LibFiles[idx])
|
||||
self.form.TableList.setCurrentRow(idx)
|
||||
self.form.ButtonRemoveToolTable.setEnabled(True)
|
||||
self.form.ButtonRenameToolTable.setEnabled(True)
|
||||
|
||||
def libraryLoad(self, path):
|
||||
self.toolTableView.setUpdatesEnabled(False)
|
||||
self.model.clear()
|
||||
self.model.setHorizontalHeaderLabels(self.columnNames())
|
||||
|
||||
if path:
|
||||
with open(path) as fp:
|
||||
PathPreferences.setLastPathToolTable(os.path.basename(path))
|
||||
library = json.load(fp)
|
||||
|
||||
for toolBit in library['tools']:
|
||||
nr = toolBit['nr']
|
||||
bit = PathToolBit.findBit(toolBit['path'])
|
||||
if bit:
|
||||
PathLog.track(bit)
|
||||
tool = PathToolBit.Declaration(bit)
|
||||
self._toolAdd(nr, tool, bit)
|
||||
else:
|
||||
PathLog.error("Could not find tool #{}: {}".format(nr, library['tools'][nr]))
|
||||
|
||||
self.toolTableView.resizeColumnsToContents()
|
||||
|
||||
self.toolTableView.setUpdatesEnabled(True)
|
||||
|
||||
self.form.setWindowTitle("{} - {}".format(self.title, os.path.basename(path) if path else ''))
|
||||
self.path = path
|
||||
self.updateToolbar()
|
||||
def toolEditDone(self, success=True):
|
||||
FreeCAD.ActiveDocument.removeObject("temptool")
|
||||
print('all done')
|
||||
|
||||
def libraryNew(self):
|
||||
self.libraryLoad(None)
|
||||
self.librarySaveAs()
|
||||
TooltableTypeJSON = translate("PathToolLibraryManager", "Tooltable JSON (*.fctl)")
|
||||
|
||||
def renameLibrary(self):
|
||||
name = self.form.TableList.itemWidget(self.form.TableList.currentItem()).getTableName()
|
||||
newName, ok = QtGui.QInputDialog.getText(None, translate(
|
||||
"TooltableEditor", "Rename Tooltable"), translate(
|
||||
"TooltableEditor", "Enter Name:"), QtGui.QLineEdit.Normal, name)
|
||||
if ok and newName:
|
||||
os.rename(PathPreferences.lastPathToolLibrary() + '/' + name, PathPreferences.lastPathToolLibrary() + '/' + newName)
|
||||
self.libraryOpen(filedialog=False)
|
||||
filename = PySide.QtGui.QFileDialog.getSaveFileName(self.form,
|
||||
translate("TooltableEditor", "Save toolbit library", None),
|
||||
PathPreferences.lastPathToolLibrary(), "{}".format(TooltableTypeJSON))
|
||||
|
||||
# def createToolBit(self):
|
||||
# tool = PathToolBit.ToolBitFactory().Create()
|
||||
if not (filename and filename[0]):
|
||||
self.loadData()
|
||||
|
||||
# #self.dialog = PySide.QtGui.QDialog(self.form)
|
||||
# #layout = PySide.QtGui.QVBoxLayout(self.dialog)
|
||||
# self.editor = PathToolBitEdit.ToolBitEditor(tool, self.form.toolTableGroup)
|
||||
# self.editor.setupUI()
|
||||
# self.buttons = PySide.QtGui.QDialogButtonBox(
|
||||
# PySide.QtGui.QDialogButtonBox.Ok | PySide.QtGui.QDialogButtonBox.Cancel,
|
||||
# PySide.QtCore.Qt.Horizontal, self.dialog)
|
||||
# layout.addWidget(self.buttons)
|
||||
# #self.buttons.accepted.connect(accept)
|
||||
# #self.buttons.rejected.connect(reject)
|
||||
# print(self.dialog.exec_())
|
||||
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:
|
||||
json.dump(library, fp, sort_keys=True, indent=2)
|
||||
|
||||
self.loadData()
|
||||
|
||||
def librarySave(self):
|
||||
library = {}
|
||||
tools = []
|
||||
library['version'] = 1
|
||||
library['tools'] = tools
|
||||
for row in range(self.model.rowCount()):
|
||||
toolNr = self.model.data(self.model.index(row, 0), PySide.QtCore.Qt.EditRole)
|
||||
toolPath = self.model.data(self.model.index(row, 0), _PathRole)
|
||||
for row in range(self.toolModel.rowCount()):
|
||||
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():
|
||||
tools.append({'nr': toolNr, 'path': toolPath})
|
||||
else:
|
||||
@@ -400,13 +501,112 @@ class ToolBitLibrary(object):
|
||||
with open(self.path, 'w') as fp:
|
||||
json.dump(library, fp, sort_keys=True, indent=2)
|
||||
|
||||
def libraryOk(self):
|
||||
self.librarySave()
|
||||
self.form.close()
|
||||
|
||||
def libPaths(self):
|
||||
lib = PathPreferences.lastFileToolLibrary()
|
||||
loc = PathPreferences.lastPathToolLibrary()
|
||||
#loc = os.path.split(lib)[0]
|
||||
|
||||
PathLog.track("lib: {} loc: {}".format(lib, loc))
|
||||
return lib, loc
|
||||
|
||||
def columnNames(self):
|
||||
return ['Nr', 'Tool', 'Shape', 'Diameter']
|
||||
|
||||
def loadData(self, path=None):
|
||||
PathLog.track(path)
|
||||
self.toolTableView.setUpdatesEnabled(False)
|
||||
self.form.TableList.setUpdatesEnabled(False)
|
||||
|
||||
|
||||
if path is None:
|
||||
path, loc = self.libPaths()
|
||||
|
||||
self.toolModel.clear()
|
||||
self.listModel.clear()
|
||||
self.factory.libraryOpen(self.toolModel, lib=path)
|
||||
self.factory.findLibraries(self.listModel)
|
||||
|
||||
else:
|
||||
self.toolModel.clear()
|
||||
self.factory.libraryOpen(self.toolModel, lib=path)
|
||||
|
||||
self.path = path
|
||||
self.form.setWindowTitle("{}".format(PathPreferences.lastPathToolLibrary()))
|
||||
self.toolModel.setHorizontalHeaderLabels(self.columnNames())
|
||||
self.listModel.setHorizontalHeaderLabels(['Library'])
|
||||
|
||||
|
||||
# Select the current library in the list of tables
|
||||
curIndex = None
|
||||
for i in range(self.listModel.rowCount()):
|
||||
item = self.listModel.item(i)
|
||||
if item.data(_PathRole) == path:
|
||||
curIndex = self.listModel.indexFromItem(item)
|
||||
|
||||
if curIndex:
|
||||
sm = self.form.TableList.selectionModel()
|
||||
sm.select(curIndex, QtCore.QItemSelectionModel.Select)
|
||||
|
||||
self.toolTableView.setUpdatesEnabled(True)
|
||||
self.form.TableList.setUpdatesEnabled(True)
|
||||
|
||||
def setupUI(self):
|
||||
PathLog.track()
|
||||
self.form.TableList.setModel(self.listModel)
|
||||
self.toolTableView.setModel(self.toolModel)
|
||||
|
||||
self.loadData()
|
||||
|
||||
self.toolTableView.resizeColumnsToContents()
|
||||
self.toolTableView.selectionModel().selectionChanged.connect(self.toolSelect)
|
||||
self.toolTableView.doubleClicked.connect(self.toolEdit)
|
||||
|
||||
self.form.TableList.clicked.connect(self.tableSelected)
|
||||
|
||||
self.form.toolAdd.clicked.connect(self.toolBitExisting)
|
||||
self.form.toolDelete.clicked.connect(self.toolDelete)
|
||||
self.form.toolCreate.clicked.connect(self.toolBitNew)
|
||||
|
||||
self.form.addToolTable.clicked.connect(self.libraryNew)
|
||||
|
||||
self.form.libraryOpen.clicked.connect(self.libraryPath)
|
||||
self.form.librarySave.clicked.connect(self.libraryOk)
|
||||
self.form.libraryExport.clicked.connect(self.librarySaveAs)
|
||||
|
||||
self.toolSelect([], [])
|
||||
|
||||
def librarySaveAs(self, path):
|
||||
|
||||
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))
|
||||
if filename and filename[0]:
|
||||
if filename[1] == TooltableTypeLinuxCNC:
|
||||
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])
|
||||
self.path = path
|
||||
self.librarySave()
|
||||
self.updateToolbar()
|
||||
|
||||
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:
|
||||
fp.write(";\n")
|
||||
|
||||
for row in range(self.model.rowCount()):
|
||||
toolNr = self.model.data(self.model.index(row, 0), PySide.QtCore.Qt.EditRole)
|
||||
toolPath = self.model.data(self.model.index(row, 0), _PathRole)
|
||||
for row in range(self.toolModel.rowCount()):
|
||||
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)
|
||||
if bit:
|
||||
@@ -429,129 +629,12 @@ class ToolBitLibrary(object):
|
||||
orientation = bit.Orientation if hasattr(bit, "Orientation") else "0"
|
||||
remark = bit.Label
|
||||
|
||||
fp.write("T%s P%s X%s Y%s Z%s A%s B%s C%s U%s V%s W%s D%s I%s J%s Q%s ; %s\n" %
|
||||
(toolNr,
|
||||
pocket,
|
||||
xoffset,
|
||||
yoffset,
|
||||
zoffset,
|
||||
aoffset,
|
||||
boffset,
|
||||
coffset,
|
||||
uoffset,
|
||||
voffset,
|
||||
woffset,
|
||||
diameter,
|
||||
frontangle,
|
||||
backangle,
|
||||
orientation,
|
||||
remark))
|
||||
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)
|
||||
|
||||
else:
|
||||
PathLog.error("Could not find tool #{} ".format(toolNr))
|
||||
|
||||
def librarySaveAs(self):
|
||||
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, \
|
||||
# 'Tool Library', PathPreferences.lastPathToolLibrary(), '*.fctl')
|
||||
if filename and filename[0]:
|
||||
if filename[1] == TooltableTypeLinuxCNC:
|
||||
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])
|
||||
PathPreferences.setLastPathToolLibrary(os.path.dirname(path))
|
||||
self.path = path
|
||||
self.librarySave()
|
||||
self.updateToolbar()
|
||||
PathPreferences.setLastPathToolTable(os.path.basename(path))
|
||||
self.libraryOpen(None, False)
|
||||
|
||||
def libraryCancel(self):
|
||||
self.form.close()
|
||||
|
||||
def columnNames(self):
|
||||
return ['Nr', 'Tool', 'Shape', 'Diameter']
|
||||
|
||||
def toolEdit(self, selected):
|
||||
print('here')
|
||||
print(selected)
|
||||
if selected.column() == 0:
|
||||
print('nope')
|
||||
else:
|
||||
print('yep')
|
||||
|
||||
def setupUI(self):
|
||||
PathLog.track('+')
|
||||
self.model = PySide.QtGui.QStandardItemModel(0, len(self.columnNames()), self.toolTableView)
|
||||
self.model.setHorizontalHeaderLabels(self.columnNames())
|
||||
|
||||
self.toolTableView.setModel(self.model)
|
||||
self.toolTableView.resizeColumnsToContents()
|
||||
self.toolTableView.selectionModel().selectionChanged.connect(self.toolSelect)
|
||||
self.toolTableView.doubleClicked.connect(self.toolEdit)
|
||||
|
||||
self.form.toolAdd.clicked.connect(self.toolAdd)
|
||||
self.form.toolDelete.clicked.connect(self.toolDelete)
|
||||
self.form.toolEnumerate.clicked.connect(self.toolEnumerate)
|
||||
# self.form.createToolBit.clicked.connect(self.createToolBit)
|
||||
|
||||
self.form.ButtonAddToolTable.clicked.connect(self.libraryNew)
|
||||
self.form.ButtonRemoveToolTable.clicked.connect(self.libraryDelete)
|
||||
self.form.ButtonRenameToolTable.clicked.connect(self.renameLibrary)
|
||||
|
||||
# self.form.libraryNew.clicked.connect(self.libraryNew)
|
||||
self.form.libraryOpen.clicked.connect(partial(self.libraryOpen, filedialog=True))
|
||||
self.form.librarySave.clicked.connect(self.librarySave)
|
||||
self.form.librarySaveAs.clicked.connect(self.librarySaveAs)
|
||||
self.form.libraryCancel.clicked.connect(self.libraryCancel)
|
||||
|
||||
self.form.addToolController.clicked.connect(self.selectedOrAllToolControllers)
|
||||
|
||||
self.form.TableList.clicked.connect(self.tableSelected)
|
||||
|
||||
self.toolSelect([], [])
|
||||
self.updateToolbar()
|
||||
PathLog.track('-')
|
||||
|
||||
|
||||
class ToolTableListWidgetItem(QtGui.QWidget):
|
||||
toolMoved = QtCore.Signal()
|
||||
|
||||
def __init__(self):
|
||||
super(ToolTableListWidgetItem, self).__init__()
|
||||
|
||||
self.setAcceptDrops(True)
|
||||
|
||||
self.mainLayout = QtGui.QHBoxLayout()
|
||||
self.iconQLabel = QtGui.QLabel()
|
||||
self.tableNameLabel = QtGui.QLabel()
|
||||
self.mainLayout.addWidget(self.iconQLabel, 0)
|
||||
self.mainLayout.addWidget(self.tableNameLabel, 1)
|
||||
self.setLayout(self.mainLayout)
|
||||
|
||||
def setTableName(self, text):
|
||||
self.tableNameLabel.setText(text)
|
||||
|
||||
def getTableName(self):
|
||||
return self.tableNameLabel.text()
|
||||
|
||||
def setIcon(self, icon):
|
||||
icon = icon.scaled(22, 22)
|
||||
self.iconQLabel.setPixmap(icon)
|
||||
|
||||
# def dragEnterEvent(self, e):
|
||||
# currentToolTable = self.tlm.getCurrentTableName()
|
||||
# thisToolTable = self.getTableName()
|
||||
|
||||
def dropEvent(self, e):
|
||||
selectedTools = e.source().selectedIndexes()
|
||||
print("Drop: {}, {}".format(selectedTools, selectedTools[1].data()))
|
||||
|
||||
Reference in New Issue
Block a user