diff --git a/src/Mod/Path/Gui/Resources/panels/ToolBitEditor.ui b/src/Mod/Path/Gui/Resources/panels/ToolBitEditor.ui
index 42a5e98364..bceff42fcd 100644
--- a/src/Mod/Path/Gui/Resources/panels/ToolBitEditor.ui
+++ b/src/Mod/Path/Gui/Resources/panels/ToolBitEditor.ui
@@ -6,8 +6,8 @@
0
0
- 587
- 744
+ 401
+ 715
@@ -16,6 +16,12 @@
-
+
+
+ 0
+ 0
+
+
0
@@ -114,7 +120,7 @@
-
- 180°
+ 0 °
°
@@ -131,7 +137,7 @@
-
- 0.00
+ 0 mm
mm
diff --git a/src/Mod/Path/Gui/Resources/panels/ToolBitLibraryEdit.ui b/src/Mod/Path/Gui/Resources/panels/ToolBitLibraryEdit.ui
index 83301b6b0d..f97deb479e 100644
--- a/src/Mod/Path/Gui/Resources/panels/ToolBitLibraryEdit.ui
+++ b/src/Mod/Path/Gui/Resources/panels/ToolBitLibraryEdit.ui
@@ -11,297 +11,11 @@
- ToolBit Library
+ Library Manager
-
-
-
-
-
-
- 0
-
-
- 0
-
-
- 0
-
-
- 0
-
-
-
-
-
- 0
-
-
-
-
-
-
- 226
- 16777215
-
-
-
-
- 0
-
-
- 0
-
-
- 0
-
-
- 0
-
-
-
-
-
- 0
-
-
-
-
-
- Tool Libraries
-
-
-
- -
-
-
-
- 32
- 32
-
-
-
- <html><head/><body><p>Rename Tool Table</p></body></html>
-
-
-
-
-
-
- :/icons/edit-edit.svg:/icons/edit-edit.svg
-
-
-
- -
-
-
-
- 32
- 32
-
-
-
- <html><head/><body><p>Add New Tool Table</p></body></html>
-
-
-
-
-
-
- :/icons/list-add.svg:/icons/list-add.svg
-
-
-
- -
-
-
-
- 32
- 32
-
-
-
- <html><head/><body><p>Remove Tool Table from Disc</p></body></html>
-
-
-
-
-
-
- :/icons/list-remove.svg:/icons/list-remove.svg
-
-
-
-
-
- -
-
-
- QFrame::Box
-
-
-
-
-
-
- -
-
-
- 0
-
-
- 0
-
-
-
-
-
- true
-
-
- <html><head/><body><p>Table of Tool Bits of the library.</p></body></html>
-
-
- QFrame::Box
-
-
- QFrame::Sunken
-
-
- 1
-
-
- 0
-
-
- true
-
-
- QAbstractItemView::InternalMove
-
-
- Qt::MoveAction
-
-
- QAbstractItemView::SelectRows
-
-
- true
-
-
- false
-
-
-
- -
-
-
-
-
-
- Add Tool Controller(s) to Job
-
-
-
- :/icons/edit_OK.svg:/icons/edit_OK.svg
-
-
-
- -
-
-
- Qt::Horizontal
-
-
- QSizePolicy::Fixed
-
-
-
- 140
- 20
-
-
-
-
- -
-
-
- <html><head/><body><p>Close the Tool Bit Library Editor</p></body></html>
-
-
- Cancel
-
-
-
- :/icons/button_invalid.svg:/icons/button_invalid.svg
-
-
-
- -
-
-
- <html><head/><body><p>Save the current Library</p></body></html>
-
-
- Save Table
-
-
-
- :/icons/document-save.svg:/icons/document-save.svg
-
-
-
- -
-
-
- <html><head/><body><p>Save the library to a new file</p></body></html>
-
-
- Save Table As...
-
-
-
- :/icons/document-save-as.svg:/icons/document-save-as.svg
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
- 0
- 0
-
-
-
-
- 420
- 0
-
-
-
- true
-
-
-
- -
-
-
- <html><head/><body><p>Select the folder with the tool libraries to load.</p></body></html>
-
-
-
-
-
-
- :/icons/document-open.svg:/icons/document-open.svg
-
-
-
+
+ -
+
-
@@ -315,22 +29,45 @@
+ -
+
+
+ Create Toolbit
+
+
+
+ :/icons/Path-ToolBit.svg:/icons/Path-ToolBit.svg
+
+
+
-
+
+
+ 16777215
+ 16777215
+
+
<html><head/><body><p>Add existing Tool Bit to this library.</p><p><br/></p></body></html>
- Add Toolbit
+ Add Existing
-
- :/icons/list-add.svg:/icons/list-add.svg
+
+ :/icons/Path-ToolDuplicate.svg:/icons/Path-ToolDuplicate.svg
-
+
+
+ 16777215
+ 16777215
+
+
<html><head/><body><p>Delete selected Tool Bit(s) from the library.</p><p><br/></p></body></html>
@@ -343,17 +80,194 @@
+
+
+ -
+
+
+
-
+
+
-
+
+
+
+ 16777215
+ 16777215
+
+
+
+ <html><head/><body><p>Select a working path for the tool library editor.</p></body></html>
+
+
+
+
+
+
+ :/icons/document-open.svg:/icons/document-open.svg
+
+
+
+ -
+
+
+
+ 16777215
+ 16777215
+
+
+
+ <html><head/><body><p>Add New Tool Table</p></body></html>
+
+
+
+
+
+
+ :/icons/document-new.svg:/icons/document-new.svg
+
+
+
+ 24
+ 24
+
+
+
+
+ -
+
+
+ <html><head/><body><p>Save the selected library with a new name or export to another format</p></body></html>
+
+
+
+
+
+
+ :/icons/document-save.svg:/icons/document-save.svg
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QFrame::Box
+
+
+
+ -
+
+
+ true
+
+
+ <html><head/><body><p>Table of Tool Bits of the library.</p></body></html>
+
+
+ QFrame::Box
+
+
+ QFrame::Sunken
+
+
+ 1
+
+
+ 0
+
+
+ false
+
+
+ false
+
+
+ QAbstractItemView::DragOnly
+
+
+ Qt::IgnoreAction
+
+
+ QAbstractItemView::SingleSelection
+
+
+ QAbstractItemView::SelectRows
+
+
+ true
+
+
+ false
+
+
+ true
+
+
+
+
+
+
+ -
+
-
-
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Preferred
+
+
+
+ 65555555
+ 20
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
- <html><head/><body><p>Assign numbers to each Tool Bit according to its current position in the library. The first Tool Bit is assigned the ID 1.</p></body></html>
+ <html><head/><body><p>Save the current Library</p></body></html>
- Enumerate
+ Close
- :/icons/button_sort.svg:/icons/button_sort.svg
+ :/icons/edit_OK.svg:/icons/edit_OK.svg
@@ -363,6 +277,7 @@
+
diff --git a/src/Mod/Path/Gui/Resources/panels/ToolBitSelector.ui b/src/Mod/Path/Gui/Resources/panels/ToolBitSelector.ui
index 4dde97be5a..32e87cb8fb 100644
--- a/src/Mod/Path/Gui/Resources/panels/ToolBitSelector.ui
+++ b/src/Mod/Path/Gui/Resources/panels/ToolBitSelector.ui
@@ -1,119 +1,135 @@
- Dialog
-
+ ToolSelector
+
0
0
- 588
- 396
+ 350
+ 542
-
- Dialog
+
+
+ 0
+ 0
+
-
- -
-
-
+
+ Tool Selector
+
+
+
+
-
+
+
+
-
+
+
+ TextLabel
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+
+
+
+ :/icons/Path-ToolTable.svg:/icons/Path-ToolTable.svg
+
+
+
+ 16
+ 16
+
+
+
+
+
+
+
+ -
+
-
-
+
<html><head/><body><p>Available Tool Bits to choose from.</p></body></html>
QAbstractItemView::NoEditTriggers
-
-
- -
-
-
-
-
-
-
- <html><head/><body><p>Load an existing Tool Bit from a file.</p></body></html>
-
-
- Load...
-
-
-
- -
-
-
- <html><head/><body><p>Create a new Tool Bit based on an existing shape.</p></body></html>
-
-
- New
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
-
+
+ QAbstractItemView::ExtendedSelection
+
+
+ false
+
-
-
- -
-
-
- Qt::Horizontal
-
-
- QDialogButtonBox::Cancel|QDialogButtonBox::Ok
-
-
-
-
+
+ -
+
+
-
+
+
+ false
+
+
+ <html><head/><body><p>Create ToolControllers for the selected toolbits and add them to the Job</p></body></html>
+
+
+ Add To Job
+
+
+
+ :/icons/edit_OK.svg:/icons/edit_OK.svg
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
-
-
-
- buttonBox
- accepted()
- Dialog
- accept()
-
-
- 248
- 254
-
-
- 157
- 274
-
-
-
-
- buttonBox
- rejected()
- Dialog
- reject()
-
-
- 316
- 260
-
-
- 286
- 274
-
-
-
-
+
+
+
+
+
diff --git a/src/Mod/Path/InitGui.py b/src/Mod/Path/InitGui.py
index f40ff06ee6..cf0e8a36e6 100644
--- a/src/Mod/Path/InitGui.py
+++ b/src/Mod/Path/InitGui.py
@@ -76,20 +76,22 @@ class PathWorkbench (Workbench):
from PathScripts import PathToolBitCmd
from PathScripts import PathToolBitLibraryCmd
- if PathPreferences.experimentalFeaturesEnabled():
- toolbitcmdlist = PathToolBitCmd.CommandList + ["Separator"] + PathToolBitLibraryCmd.CommandList + ["Path_ToolController", "Separator"]
- self.toolbitctxmenu = ["Path_ToolBitLibraryLoad", "Path_ToolController"]
- else:
- toolbitcmdlist = []
- self.toolbitctxmenu = []
+
+
+ #if PathPreferences.experimentalFeaturesEnabled():
+ # #toolbitcmdlist = PathToolBitCmd.CommandList + ["Separator"] + PathToolBitLibraryCmd.CommandList + ["Path_ToolController", "Separator"]
+ # toolbitcmdlist = PathToolBitLibraryCmd.MenuList
+ # self.toolbitctxmenu = ["Path_ToolBitLibraryLoad", "Path_ToolController"]
+ #else:
+ # toolbitcmdlist = []
+ # self.toolbitctxmenu = []
import PathCommands
PathGuiInit.Startup()
# build commands list
projcmdlist = ["Path_Job", "Path_Post"]
- toolcmdlist = ["Path_Inspect", "Path_Simulator",
- "Path_ToolLibraryEdit", "Path_SelectLoop",
+ toolcmdlist = ["Path_Inspect", "Path_Simulator", "Path_SelectLoop",
"Path_OpActiveToggle"]
prepcmdlist = ["Path_Fixture", "Path_Comment", "Path_Stop",
"Path_Custom", "Path_Probe"]
@@ -107,6 +109,16 @@ class PathWorkbench (Workbench):
# modcmdmore = ["Path_Hop",]
# remotecmdlist = ["Path_Remote"]
+
+ if PathPreferences.toolsReallyUseLegacyTools():
+ toolcmdlist.append("Path_ToolLibraryEdit")
+ toolbitcmdlist = []
+ else:
+ toolcmdlist.extend(PathToolBitLibraryCmd.BarList)
+ toolbitcmdlist = PathToolBitLibraryCmd.MenuList
+
+
+
engravecmdgroup = ['Path_EngraveTools']
FreeCADGui.addCommand('Path_EngraveTools', PathCommandGroup(engravecmdlist, QtCore.QT_TRANSLATE_NOOP("Path", 'Engraving Operations')))
@@ -134,7 +146,7 @@ class PathWorkbench (Workbench):
self.appendToolbar(QtCore.QT_TRANSLATE_NOOP("Path", "Helpful Tools"), extracmdlist)
self.appendMenu([QtCore.QT_TRANSLATE_NOOP("Path", "&Path")], projcmdlist + ["Path_ExportTemplate", "Separator"] +
- toolbitcmdlist + toolcmdlist + ["Separator"] + twodopcmdlist + engravecmdlist + ["Separator"] +
+ toolcmdlist + toolbitcmdlist + ["Separator"] + twodopcmdlist + engravecmdlist + ["Separator"] +
threedopcmdlist + ["Separator"])
self.appendMenu([QtCore.QT_TRANSLATE_NOOP("Path", "&Path"), QtCore.QT_TRANSLATE_NOOP(
"Path", "Path Dressup")], dressupcmdlist)
diff --git a/src/Mod/Path/PathScripts/PathPreferences.py b/src/Mod/Path/PathScripts/PathPreferences.py
index ad6d2d5585..096c6ef349 100644
--- a/src/Mod/Path/PathScripts/PathPreferences.py
+++ b/src/Mod/Path/PathScripts/PathPreferences.py
@@ -1,5 +1,7 @@
# -*- coding: utf-8 -*-
+
# ***************************************************************************
+# * *
# * Copyright (c) 2014 Yorik van Havre *
# * *
# * 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)
diff --git a/src/Mod/Path/PathScripts/PathToolBit.py b/src/Mod/Path/PathScripts/PathToolBit.py
index d04473923d..efafe2c3a3 100644
--- a/src/Mod/Path/PathScripts/PathToolBit.py
+++ b/src/Mod/Path/PathScripts/PathToolBit.py
@@ -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()
diff --git a/src/Mod/Path/PathScripts/PathToolBitEdit.py b/src/Mod/Path/PathScripts/PathToolBitEdit.py
index a8e76cf20e..c3e0120149 100644
--- a/src/Mod/Path/PathScripts/PathToolBitEdit.py
+++ b/src/Mod/Path/PathScripts/PathToolBitEdit.py
@@ -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)
+
diff --git a/src/Mod/Path/PathScripts/PathToolBitGui.py b/src/Mod/Path/PathScripts/PathToolBitGui.py
index 9702dfe469..9242dfc033 100644
--- a/src/Mod/Path/PathScripts/PathToolBitGui.py
+++ b/src/Mod/Path/PathScripts/PathToolBitGui.py
@@ -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.'''
diff --git a/src/Mod/Path/PathScripts/PathToolBitLibraryCmd.py b/src/Mod/Path/PathScripts/PathToolBitLibraryCmd.py
index 10ad578196..fcff3facaa 100644
--- a/src/Mod/Path/PathScripts/PathToolBitLibraryCmd.py
+++ b/src/Mod/Path/PathScripts/PathToolBitLibraryCmd.py
@@ -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")
diff --git a/src/Mod/Path/PathScripts/PathToolBitLibraryGui.py b/src/Mod/Path/PathScripts/PathToolBitLibraryGui.py
index 2dbb4c0ce9..07a826ee16 100644
--- a/src/Mod/Path/PathScripts/PathToolBitLibraryGui.py
+++ b/src/Mod/Path/PathScripts/PathToolBitLibraryGui.py
@@ -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()))