diff --git a/src/Mod/Path/Gui/Resources/panels/ToolBitEditor.ui b/src/Mod/Path/Gui/Resources/panels/ToolBitEditor.ui
index 1ffb408a8a..42a5e98364 100644
--- a/src/Mod/Path/Gui/Resources/panels/ToolBitEditor.ui
+++ b/src/Mod/Path/Gui/Resources/panels/ToolBitEditor.ui
@@ -15,20 +15,12 @@
-
-
+
0
-
-
-
- 0
- 0
- 559
- 626
-
-
-
+
+
Shape
@@ -61,7 +53,7 @@
-
- Type
+ Shape File
@@ -180,16 +172,8 @@
-
-
-
- 0
- 0
- 559
- 626
-
-
-
+
+
Attributes
@@ -228,6 +212,8 @@
-
+
+
+
diff --git a/src/Mod/Path/Gui/Resources/panels/ToolBitLibraryEdit.ui b/src/Mod/Path/Gui/Resources/panels/ToolBitLibraryEdit.ui
index b5cfdae83c..f9cdfec269 100644
--- a/src/Mod/Path/Gui/Resources/panels/ToolBitLibraryEdit.ui
+++ b/src/Mod/Path/Gui/Resources/panels/ToolBitLibraryEdit.ui
@@ -6,17 +6,17 @@
0
0
- 958
- 508
+ 954
+ 587
ToolBit Library
-
- -
-
-
+
+
-
+
+
0
@@ -30,247 +30,339 @@
0
-
-
-
- <html><head/><body><p>Create a new library with an empty list of Tool Bits.</p></body></html>
+
+
+ 0
-
- ...
-
-
-
- :/icons/document-new.svg:/icons/document-new.svg
-
-
-
- -
-
-
- <html><head/><body><p>Open an existing Tool Bit library.</p></body></html>
-
-
- ...
-
-
-
- :/icons/document-open.svg:/icons/document-open.svg
-
-
-
- -
-
-
- <html><head/><body><p>Save Tool Bit library.</p></body></html>
-
-
- ...
-
-
-
- :/icons/document-save.svg:/icons/document-save.svg
-
-
-
- -
-
-
- <html><head/><body><p>Save Tool Bit library under new name.</p></body></html>
-
-
- ...
-
-
-
- :/icons/document-save-as.svg:/icons/document-save-as.svg
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
- <html><head/><body><p>Edit Tool Bit library editor settings.</p></body></html>
-
-
- ...
-
-
-
- :/icons/preferences-system.svg:/icons/preferences-system.svg
-
-
+
-
+
+
+
+ 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
-
-
-
-
-
- true
-
-
- <html><head/><body><p>Table of Tool Bits of the library.</p></body></html>
-
-
- true
-
-
- QAbstractItemView::InternalMove
-
-
- Qt::MoveAction
-
-
- QAbstractItemView::SelectRows
-
-
- true
-
-
- false
-
-
-
- -
-
-
-
- 0
-
-
- 0
-
-
- 0
-
-
- 0
-
-
-
-
-
- <html><head/><body><p>Add another Tool Bit to this library.</p><p><br/></p></body></html>
-
-
- Add ...
-
-
-
- :/icons/list-add.svg:/icons/list-add.svg
-
-
-
- -
-
-
- <html><head/><body><p>Delete selected Tool Bit(s) from the library.</p><p><br/></p></body></html>
-
-
- Delete
-
-
-
- :/icons/list-remove.svg:/icons/list-remove.svg
-
-
-
- -
-
-
- <html><head/><body><p>Assigned 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>
-
-
- Enumerate
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 115
-
-
-
-
-
-
-
-
-
-
- -
-
-
- Qt::Horizontal
-
-
- QDialogButtonBox::Cancel|QDialogButtonBox::Ok
-
-
+
-
+
+
-
+
+
+
+ 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
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 20
+ 20
+
+
+
+
+ -
+
+
+ <html><head/><body><p>Add existing Tool Bit to this library.</p><p><br/></p></body></html>
+
+
+ Add Toolbit
+
+
+
+ :/icons/list-add.svg:/icons/list-add.svg
+
+
+
+ -
+
+
+ <html><head/><body><p>Delete selected Tool Bit(s) from the library.</p><p><br/></p></body></html>
+
+
+ Remove
+
+
+
+ :/icons/list-remove.svg:/icons/list-remove.svg
+
+
+
+ -
+
+
+ <html><head/><body><p>Assigne 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>
+
+
+ Enumerate
+
+
+
+ :/icons/button_sort.svg:/icons/button_sort.svg
+
+
+
+
-
-
- buttonBox
- accepted()
- Dialog
- accept()
-
-
- 248
- 254
-
-
- 157
- 274
-
-
-
-
- buttonBox
- rejected()
- Dialog
- reject()
-
-
- 316
- 260
-
-
- 286
- 274
-
-
-
-
+
diff --git a/src/Mod/Path/Gui/Resources/preferences/PathJob.ui b/src/Mod/Path/Gui/Resources/preferences/PathJob.ui
index 4b458788e5..9e1b6f7fcc 100644
--- a/src/Mod/Path/Gui/Resources/preferences/PathJob.ui
+++ b/src/Mod/Path/Gui/Resources/preferences/PathJob.ui
@@ -24,8 +24,8 @@
0
0
- 467
- 448
+ 424
+ 537
@@ -142,8 +142,8 @@
0
0
- 665
- 449
+ 424
+ 537
@@ -348,8 +348,8 @@
0
0
- 431
- 718
+ 407
+ 570
@@ -625,8 +625,8 @@
0
0
- 412
- 461
+ 424
+ 537
@@ -653,6 +653,13 @@
+ -
+
+
+ Remember last library
+
+
+
-
diff --git a/src/Mod/Path/PathScripts/PathPreferences.py b/src/Mod/Path/PathScripts/PathPreferences.py
index 0525a3b3f5..65eeefad59 100644
--- a/src/Mod/Path/PathScripts/PathPreferences.py
+++ b/src/Mod/Path/PathScripts/PathPreferences.py
@@ -44,9 +44,11 @@ PostProcessorOutputPolicy = "PostProcessorOutputPolicy"
LastPathToolBit = "LastPathToolBit"
LastPathToolLibrary = "LastPathToolLibrary"
LastPathToolShape = "LastPathToolShape"
+LastPathToolTable ="LastPathToolTable"
UseLegacyTools = "UseLegacyTools"
UseAbsoluteToolPaths = "UseAbsoluteToolPaths"
+OpenLastLibrary = "OpenLastLibrary"
# Linear tolerance to use when generating Paths, eg when tessellating geometry
GeometryTolerance = "GeometryTolerance"
@@ -83,7 +85,6 @@ def allEnabledPostProcessors(include = None):
return l
return enabled
-
def defaultPostProcessor():
pref = preferences()
return pref.GetString(PostProcessorDefault, "")
@@ -158,10 +159,14 @@ def toolsReallyUseLegacyTools():
def toolsStoreAbsolutePaths():
return preferences().GetBool(UseAbsoluteToolPaths, False)
-def setToolsSettings(legacy, relative):
+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)
@@ -190,7 +195,6 @@ def setPostProcessorDefaults(processor, args, blacklist):
pref.SetString(PostProcessorDefaultArgs, args)
pref.SetString(PostProcessorBlacklist, "%s" % (blacklist))
-
def setOutputFileDefaults(fileName, policy):
pref = preferences()
pref.SetString(PostProcessorOutputFile, fileName)
@@ -206,11 +210,13 @@ def defaultOutputPolicy():
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)
@@ -219,16 +225,24 @@ def experimentalFeaturesEnabled():
def lastPathToolBit():
return preferences().GetString(LastPathToolBit, pathDefaultToolsPath('Bit'))
+
def setLastPathToolBit(path):
return preferences().SetString(LastPathToolBit, path)
def lastPathToolLibrary():
return preferences().GetString(LastPathToolLibrary, pathDefaultToolsPath('Library'))
+
def setLastPathToolLibrary(path):
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/PathPreferencesPathJob.py b/src/Mod/Path/PathScripts/PathPreferencesPathJob.py
index 0782efd67b..a6d1a392e1 100644
--- a/src/Mod/Path/PathScripts/PathPreferencesPathJob.py
+++ b/src/Mod/Path/PathScripts/PathPreferencesPathJob.py
@@ -109,7 +109,9 @@ class JobPreferencesPage:
PathPreferences.setDefaultStockTemplate('')
def saveToolsSettings(self):
- PathPreferences.setToolsSettings(self.form.toolsUseLegacy.isChecked(), self.form.toolsAbsolutePaths.isChecked())
+ PathPreferences.setToolsSettings(self.form.toolsUseLegacy.isChecked(),
+ self.form.toolsAbsolutePaths.isChecked(),
+ self.form.toolsOpenLastLibrary.isChecked())
def selectComboEntry(self, widget, text):
index = widget.findText(text, QtCore.Qt.MatchFixedString)
diff --git a/src/Mod/Path/PathScripts/PathSetupSheetOpPrototype.py b/src/Mod/Path/PathScripts/PathSetupSheetOpPrototype.py
index d089dd7f7a..a162bb4e04 100644
--- a/src/Mod/Path/PathScripts/PathSetupSheetOpPrototype.py
+++ b/src/Mod/Path/PathScripts/PathSetupSheetOpPrototype.py
@@ -142,6 +142,13 @@ class PropertyString(Property):
def typeString(self):
return "String"
+class PropertyMap(Property):
+ def typeString(self):
+ return "Map"
+
+ def displayString(self, value):
+ return str(value)
+
class OpPrototype(object):
PropertyType = {
@@ -159,6 +166,7 @@ class OpPrototype(object):
'App::PropertyLink': Property,
'App::PropertyLinkList': Property,
'App::PropertyLinkSubListGlobal': Property,
+ 'App::PropertyMap': PropertyMap,
'App::PropertyPercent': PropertyPercent,
'App::PropertyString': PropertyString,
'App::PropertyStringList': Property,
diff --git a/src/Mod/Path/PathScripts/PathToolBit.py b/src/Mod/Path/PathScripts/PathToolBit.py
index 7863e31df7..1286349fd4 100644
--- a/src/Mod/Path/PathScripts/PathToolBit.py
+++ b/src/Mod/Path/PathScripts/PathToolBit.py
@@ -44,8 +44,8 @@ __author__ = "sliptonic (Brad Collette)"
__url__ = "http://www.freecadweb.org"
__doc__ = "Class to deal with and represent a tool bit."
-#PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
-#PathLog.trackModule()
+# PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
+# PathLog.trackModule()
def translate(context, text, disambig=None):
return PySide.QtCore.QCoreApplication.translate(context, text, disambig)
@@ -198,6 +198,7 @@ class ToolBit(object):
def onDelete(self, obj, arg2=None):
PathLog.track(obj.Label)
self.unloadBitBody(obj)
+ obj.Document.removeObject(obj.Name)
def _updateBitShape(self, obj, properties=None):
if not obj.BitBody is None:
@@ -233,6 +234,7 @@ class ToolBit(object):
return (doc, docOpened)
def _removeBitBody(self, obj):
+ print('in _removebitbody')
if obj.BitBody:
obj.BitBody.removeObjectsFromDocument()
obj.Document.removeObject(obj.BitBody.Name)
@@ -305,6 +307,7 @@ class ToolBit(object):
return None
def saveToFile(self, obj, path, setFile=True):
+ print('were saving now')
try:
with open(path, 'w') as fp:
json.dump(self.shapeAttrs(obj), fp, indent=' ')
@@ -329,7 +332,12 @@ class ToolBit(object):
attrs['parameter'] = params
params = {}
for name in self.propertyNamesAttribute(obj):
- params[name] = PathUtil.getPropertyValueString(obj, name)
+ #print(f"shapeattr {name}")
+ if name == "UserAttributes":
+ for key, value in obj.UserAttributes.items():
+ params[key] = value
+ else:
+ params[name] = PathUtil.getPropertyValueString(obj, name)
attrs['attribute'] = params
return attrs
@@ -346,6 +354,7 @@ class AttributePrototype(PathSetupSheetOpPrototype.OpPrototype):
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'))
class ToolBitFactory(object):
@@ -361,11 +370,25 @@ class ToolBitFactory(object):
obj.Proxy.unloadBitBody(obj)
params = attrs['attribute']
proto = AttributePrototype()
+ uservals = {}
for pname in params:
- prop = proto.getProperty(pname)
- val = prop.valueFromString(params[pname])
- print("prop[%s] = %s (%s)" % (pname, params[pname], type(val)))
- prop.setupProperty(obj, pname, PropertyGroupAttribute, prop.valueFromString(params[pname]))
+ #print(f"pname: {pname}")
+ try:
+ prop = proto.getProperty(pname)
+ val = prop.valueFromString(params[pname])
+ prop.setupProperty(obj, pname, PropertyGroupAttribute, prop.valueFromString(params[pname]))
+ except:
+ # 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]))
+
+ if len(uservals.items()) > 0:
+ 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]))
return obj
def CreateFrom(self, path, name='ToolBit'):
diff --git a/src/Mod/Path/PathScripts/PathToolBitEdit.py b/src/Mod/Path/PathScripts/PathToolBitEdit.py
index fdea4e672a..d6928b8bf5 100644
--- a/src/Mod/Path/PathScripts/PathToolBitEdit.py
+++ b/src/Mod/Path/PathScripts/PathToolBitEdit.py
@@ -84,32 +84,59 @@ class ToolBitEditor(object):
self.proto = PathToolBit.AttributePrototype()
self.props = sorted(self.proto.properties)
self.delegate = PathSetupSheetGui.Delegate(self.form)
- self.model = QtGui.QStandardItemModel(len(self.props), 3, self.form)
+ self.model = QtGui.QStandardItemModel(len(self.props)-1, 3, self.form)
self.model.setHorizontalHeaderLabels(['Set', 'Property', 'Value'])
+
for i, name in enumerate(self.props):
+ print(f"propname: {name}")
+
prop = self.proto.getProperty(name)
isset = hasattr(tool, name)
+
if isset:
prop.setValue(getattr(tool, name))
- self.model.setData(self.model.index(i, 0), isset, QtCore.Qt.EditRole)
- self.model.setData(self.model.index(i, 1), name, QtCore.Qt.EditRole)
- self.model.setData(self.model.index(i, 2), prop, PathSetupSheetGui.Delegate.PropertyRole)
- self.model.setData(self.model.index(i, 2), prop.displayString(), QtCore.Qt.DisplayRole)
+ if name == "UserAttributes":
+ continue
- self.model.item(i, 0).setCheckable(True)
- self.model.item(i, 0).setText('')
- self.model.item(i, 1).setEditable(False)
- self.model.item(i, 1).setToolTip(prop.info)
- self.model.item(i, 2).setToolTip(prop.info)
-
- if isset:
- self.model.item(i, 0).setCheckState(QtCore.Qt.Checked)
else:
- self.model.item(i, 0).setCheckState(QtCore.Qt.Unchecked)
- self.model.item(i, 1).setEnabled(False)
- self.model.item(i, 2).setEnabled(False)
+
+ self.model.setData(self.model.index(i, 0), isset, QtCore.Qt.EditRole)
+ self.model.setData(self.model.index(i, 1), name, QtCore.Qt.EditRole)
+ self.model.setData(self.model.index(i, 2), prop, PathSetupSheetGui.Delegate.PropertyRole)
+ self.model.setData(self.model.index(i, 2), prop.displayString(), QtCore.Qt.DisplayRole)
+
+ self.model.item(i, 0).setCheckable(True)
+ self.model.item(i, 0).setText('')
+ self.model.item(i, 1).setEditable(False)
+ self.model.item(i, 1).setToolTip(prop.info)
+ self.model.item(i, 2).setToolTip(prop.info)
+
+ if isset:
+ self.model.item(i, 0).setCheckState(QtCore.Qt.Checked)
+ else:
+ self.model.item(i, 0).setCheckState(QtCore.Qt.Unchecked)
+ self.model.item(i, 1).setEnabled(False)
+ self.model.item(i, 2).setEnabled(False)
+
+ if hasattr(tool, "UserAttributes"):
+ for key, value in tool.UserAttributes.items():
+ print(key, value)
+ c1 = QtGui.QStandardItem()
+ c1.setCheckable(False)
+ c1.setEditable(False)
+ c1.setCheckState(QtCore.Qt.CheckState.Checked)
+
+ c1.setText('')
+ c2 = QtGui.QStandardItem(key)
+ c2.setEditable(False)
+ c3 = QtGui.QStandardItem(value)
+ c3.setEditable(False)
+
+ self.model.appendRow([c1, c2, c3])
+ #QtGui.QStandardItem([True, key, value]))
+
self.form.attrTable.setModel(self.model)
self.form.attrTable.setItemDelegateForColumn(2, self.delegate)
diff --git a/src/Mod/Path/PathScripts/PathToolBitLibraryCmd.py b/src/Mod/Path/PathScripts/PathToolBitLibraryCmd.py
index ae5573013b..e418192b60 100644
--- a/src/Mod/Path/PathScripts/PathToolBitLibraryCmd.py
+++ b/src/Mod/Path/PathScripts/PathToolBitLibraryCmd.py
@@ -25,6 +25,7 @@
import FreeCAD
import FreeCADGui
import PySide.QtCore as QtCore
+import PathScripts.PathPreferences as PathPreferences
class CommandToolBitLibraryOpen:
'''
@@ -45,7 +46,13 @@ class CommandToolBitLibraryOpen:
def Activated(self):
import PathScripts.PathToolBitLibraryGui as PathToolBitLibraryGui
library = PathToolBitLibraryGui.ToolBitLibrary()
- library.open()
+
+ lastlib = PathPreferences.lastPathToolLibrary()
+
+ if PathPreferences.toolsOpenLastLibrary():
+ library.open(lastlib)
+ else:
+ library.open()
class CommandToolBitLibraryLoad:
'''
@@ -83,7 +90,8 @@ class CommandToolBitLibraryLoad:
import PathScripts.PathToolControllerGui as PathToolControllerGui
library = PathToolBitLibraryGui.ToolBitLibrary()
- if 1 == library.open(dialog=True) and job:
+
+ 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)
diff --git a/src/Mod/Path/PathScripts/PathToolBitLibraryGui.py b/src/Mod/Path/PathScripts/PathToolBitLibraryGui.py
index 17b12638a2..455183cf04 100644
--- a/src/Mod/Path/PathScripts/PathToolBitLibraryGui.py
+++ b/src/Mod/Path/PathScripts/PathToolBitLibraryGui.py
@@ -3,6 +3,7 @@
# ***************************************************************************
# * *
# * Copyright (c) 2019 sliptonic *
+# * Copyright (c) 2020 Schildkroet *
# * *
# * This program is free software; you can redistribute it and/or modify *
# * it under the terms of the GNU Lesser General Public License (LGPL) *
@@ -23,16 +24,22 @@
# ***************************************************************************
+import FreeCAD
import FreeCADGui
import PathScripts.PathLog as PathLog
import PathScripts.PathPreferences as PathPreferences
import PathScripts.PathToolBit as PathToolBit
import PathScripts.PathToolBitGui as PathToolBitGui
+import PathScripts.PathToolBitEdit as PathToolBitEdit
+import PathScripts.PathToolControllerGui as PathToolControllerGui
+import PathScripts.PathUtilsGui as PathUtilsGui
+from PySide import QtCore, QtGui
import PySide
import json
import os
import traceback
import uuid as UUID
+from functools import partial
#PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
#PathLog.trackModule(PathLog.thisModule())
@@ -40,6 +47,9 @@ import uuid as UUID
_UuidRole = PySide.QtCore.Qt.UserRole + 1
_PathRole = PySide.QtCore.Qt.UserRole + 2
+def translate(context, text, disambig=None):
+ return PySide.QtCore.QCoreApplication.translate(context, text, disambig)
+
class _TableView(PySide.QtGui.QTableView):
'''Subclass of QTableView to support rearrange and copying of ToolBits'''
@@ -134,8 +144,13 @@ class ToolBitLibrary(object):
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()
@@ -187,11 +202,30 @@ class ToolBitLibrary(object):
tools.append((toolNr, PathToolBit.Factory.CreateFrom(toolPath)))
return tools
+ def selectedOrAllToolControllers(self):
+ tools = self.selectedOrAllTools()
+
+ 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()
+
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()
@@ -200,19 +234,30 @@ class ToolBitLibrary(object):
def toolSelect(self, selected, deselected):
# pylint: disable=unused-argument
- self.form.toolDelete.setEnabled(len(self.toolTableView.selectedIndexes()) > 0)
+ 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)
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:
- fullPath = PathToolBit.findLibrary(path)
- if fullPath:
- self.libraryLoad(fullPath)
- else:
- self.libraryOpen()
+ self.libraryOpen(path, filedialog=False)
elif dialog:
- self.libraryOpen()
+ self.libraryOpen(None, True)
+ else:
+ self.libraryOpen(None, False)
return self.form.exec_()
def updateToolbar(self):
@@ -221,21 +266,78 @@ class ToolBitLibrary(object):
else:
self.form.librarySave.setEnabled(False)
- def libraryOpen(self):
+ def libraryOpen(self, path = None, filedialog=True):
+ import glob
PathLog.track()
- foo = PySide.QtGui.QFileDialog.getOpenFileName(self.form, 'Tool Library', PathPreferences.lastPathToolLibrary(), '*.fctl')
- if foo and foo[0]:
- path = foo[0]
- PathPreferences.setLastPathToolLibrary(os.path.dirname(path))
- self.libraryLoad(path)
+
+ # Load default search path
+ path = PathPreferences.lastPathToolLibrary()
+
+ 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
+
+ # Clear view
+ self.form.TableList.clear()
+ self.LibFiles.clear()
+ self.form.lineLibPath.clear()
+ self.form.lineLibPath.insert(path)
+
+ # Find all tool tables in directory
+ for file in glob.glob(path + '/*.fctl'):
+ self.LibFiles.append(file)
+
+ self.LibFiles.sort()
+
+ # 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'))
+ #listItem.toolMoved.connect(self.reloadReset)
+ listWidgetItem.setSizeHint(QtCore.QSize(0,40))
+ self.form.TableList.addItem(listWidgetItem)
+ self.form.TableList.setItemWidget(listWidgetItem, listItem)
+
+ 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'])
@@ -245,7 +347,9 @@ class ToolBitLibrary(object):
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 ''))
@@ -254,6 +358,29 @@ class ToolBitLibrary(object):
def libraryNew(self):
self.libraryLoad(None)
+ self.librarySaveAs()
+
+ 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)
+
+ #def createToolBit(self):
+ # tool = PathToolBit.ToolBitFactory().Create()
+
+ # #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_())
def librarySave(self):
library = {}
@@ -271,18 +398,94 @@ class ToolBitLibrary(object):
with open(self.path, 'w') as fp:
json.dump(library, fp, sort_keys=True, indent=2)
+ def libararySaveLinuxCNC(self, path):
+ 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)
+
+ bit = PathToolBit.Factory.CreateFrom(toolPath)
+ if bit:
+ PathLog.track(bit)
+
+ pocket = bit.Pocket if hasattr(bit, "Pocket") else ""
+ xoffset = bit.Xoffset if hasattr(bit, "Xoffset") else "0"
+ yoffset = bit.Yoffset if hasattr(bit, "Yoffset") else "0"
+ zoffset = bit.Zoffset if hasattr(bit, "Zoffset") else "0"
+ aoffset = bit.Aoffset if hasattr(bit, "Aoffset") else "0"
+ boffset = bit.Boffset if hasattr(bit, "Boffset") else "0"
+ coffset = bit.Coffset if hasattr(bit, "Coffset") else "0"
+ uoffset = bit.Uoffset if hasattr(bit, "Uoffset") else "0"
+ voffset = bit.Voffset if hasattr(bit, "Voffset") else "0"
+ woffset = bit.Woffset if hasattr(bit, "Woffset") else "0"
+
+ diameter = bit.Diameter if hasattr(bit, "Diameter") else "0"
+ frontangle = bit.FrontAngle if hasattr(bit, "FrontAngle") else "0"
+ backangle = bit.BackAngle if hasattr(bit, "BackAngle") else "0"
+ orientation = bit.Orientation if hasattr(bit, "Orientation") else "0"
+ remark = bit.Label
+
+ fp.write(f"T{toolNr} "\
+ f"P{pocket} "\
+ f"X{xoffset} "\
+ f"Y{yoffset} "\
+ f"Z{zoffset} "\
+ f"A{aoffset} "\
+ f"B{boffset} "\
+ f"C{coffset} "\
+ f"U{uoffset} "\
+ f"V{voffset} "\
+ f"W{woffset} "\
+ f"D{diameter} "\
+ f"I{frontangle} "\
+ f"J{backangle} "\
+ f"Q{orientation} ;"\
+ f"{remark}\n")
+
+ FreeCAD.ActiveDocument.removeObject(bit.Name)
+
+ else:
+ PathLog.error("Could not find tool #{}: {}".format(nr, library['tools'][nr]))
+
def librarySaveAs(self):
- foo = PySide.QtGui.QFileDialog.getSaveFileName(self.form, 'Tool Library', PathPreferences.lastPathToolLibrary(), '*.fctl')
- if foo and foo[0]:
- path = foo[0] if foo[0].endswith('.fctl') else "{}.fctl".format(foo[0])
- PathPreferences.setLastPathToolLibrary(os.path.dirname(path))
- self.path = path
- self.librarySave()
- self.updateToolbar()
+ 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)
@@ -291,16 +494,73 @@ class ToolBitLibrary(object):
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.libraryNew.clicked.connect(self.libraryNew)
- self.form.libraryOpen.clicked.connect(self.libraryOpen)
+ 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.tlm = TLM
+ 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()
+
+ #if not currentToolTable == thisToolTable:
+ # e.accept()
+ #else:
+ # e.ignore()
+
+ def dropEvent(self, e):
+ selectedTools = e.source().selectedIndexes()
+ print("Drop: {}, {}".format(selectedTools, selectedTools[1].data()))
+ #if selectedTools:
+ #toolData = selectedTools[1].data()
+
+ #if toolData:
+ #self.tlm.moveToTable(int(toolData), self.getTableName())
+ #self.toolMoved.emit()