diff --git a/src/Mod/CAM/Gui/Resources/Path.qrc b/src/Mod/CAM/Gui/Resources/Path.qrc
index 287d7a2a61..071ae97d00 100644
--- a/src/Mod/CAM/Gui/Resources/Path.qrc
+++ b/src/Mod/CAM/Gui/Resources/Path.qrc
@@ -124,6 +124,7 @@
panels/SetupOp.ui
panels/ToolBitEditor.ui
panels/ToolBitLibraryEdit.ui
+ panels/ToolControllerEdit.ui
panels/TaskPathCamoticsSim.ui
panels/TaskPathSimulator.ui
panels/TaskCAMSimulator.ui
diff --git a/src/Mod/CAM/Gui/Resources/panels/DlgToolControllerEdit.ui b/src/Mod/CAM/Gui/Resources/panels/DlgToolControllerEdit.ui
index 511aafc20e..ce26f9dc62 100644
--- a/src/Mod/CAM/Gui/Resources/panels/DlgToolControllerEdit.ui
+++ b/src/Mod/CAM/Gui/Resources/panels/DlgToolControllerEdit.ui
@@ -15,293 +15,8 @@
-
-
-
-
-
- 0
- 0
- 543
- 638
-
-
-
- Controller
-
-
-
-
-
-
- Controller Name / Tool Number
-
-
-
-
-
-
- false
-
-
-
- -
-
-
- 99999
-
-
-
-
-
-
- -
-
-
- QFrame::StyledPanel
-
-
- QFrame::Raised
-
-
-
-
-
-
- Horizontal feed
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
- 0.000000000000000
-
-
- 9999999.000000000000000
-
-
- mm/s
-
-
-
- -
-
-
- Vertical feed
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
- 0.000000000000000
-
-
- 9999999.000000000000000
-
-
- mm/s
-
-
-
- -
-
-
- Horizontal rapid
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
- 0.000000000000000
-
-
- 9999999.000000000000000
-
-
- mm/s
-
-
-
- -
-
-
- Vertical rapid
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
- 0.000000000000000
-
-
- 9999999.000000000000000
-
-
- mm/s
-
-
-
-
-
-
- -
-
-
- Spindle
-
-
-
- QFormLayout::AllNonFixedFieldsGrow
-
-
-
-
-
-
-
- Forward
-
-
- -
-
- Reverse
-
-
-
-
- -
-
-
- 0.000000000000000
-
-
- 100000.000000000000000
-
-
-
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
-
-
-
-
-
- 0
- 0
- 543
- 638
-
-
-
- Tool
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
-
-
- 0
-
-
- 0
-
-
- 0
-
-
- 0
-
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
- -
-
-
- QFrame::WinPanel
-
-
- Any modifications only affect this ToolController!
-
-
- Qt::AlignCenter
-
-
- true
-
-
-
-
-
+
+
-
@@ -316,22 +31,7 @@
-
-
- Gui::QuantitySpinBox
- QDoubleSpinBox
-
-
-
- tcName
- tcNumber
- horizFeed
- vertFeed
- horizRapid
- vertRapid
- spindleSpeed
- spindleDirection
buttonBox
diff --git a/src/Mod/CAM/Gui/Resources/panels/PageOpAdaptiveEdit.ui b/src/Mod/CAM/Gui/Resources/panels/PageOpAdaptiveEdit.ui
index 31d6ff4b93..667bc2755a 100644
--- a/src/Mod/CAM/Gui/Resources/panels/PageOpAdaptiveEdit.ui
+++ b/src/Mod/CAM/Gui/Resources/panels/PageOpAdaptiveEdit.ui
@@ -25,7 +25,7 @@
-
-
+
-
@@ -37,6 +37,13 @@
-
+ -
+
+
+ Edit Tool Controller
+
+
+
diff --git a/src/Mod/CAM/Gui/Resources/panels/PageOpCustomEdit.ui b/src/Mod/CAM/Gui/Resources/panels/PageOpCustomEdit.ui
index e7f084e0fc..ab8d05a783 100644
--- a/src/Mod/CAM/Gui/Resources/panels/PageOpCustomEdit.ui
+++ b/src/Mod/CAM/Gui/Resources/panels/PageOpCustomEdit.ui
@@ -53,6 +53,13 @@
-
+ -
+
+
+ Edit Tool Controller
+
+
+
diff --git a/src/Mod/CAM/Gui/Resources/panels/PageOpDeburrEdit.ui b/src/Mod/CAM/Gui/Resources/panels/PageOpDeburrEdit.ui
index 8b0ae3bdb8..0fe4be6b3d 100644
--- a/src/Mod/CAM/Gui/Resources/panels/PageOpDeburrEdit.ui
+++ b/src/Mod/CAM/Gui/Resources/panels/PageOpDeburrEdit.ui
@@ -29,7 +29,7 @@
QFrame::Raised
- -
+
-
@@ -54,14 +54,14 @@
- -
+
-
The tool and its settings to be used for this operation
- -
+
-
@@ -86,13 +86,20 @@
- -
+
-
The tool and its settings to be used for this operation
+ -
+
+
+ Edit Tool Controller
+
+
+
diff --git a/src/Mod/CAM/Gui/Resources/panels/PageOpDrillingEdit.ui b/src/Mod/CAM/Gui/Resources/panels/PageOpDrillingEdit.ui
index d8920da0f7..d6a0330d5f 100644
--- a/src/Mod/CAM/Gui/Resources/panels/PageOpDrillingEdit.ui
+++ b/src/Mod/CAM/Gui/Resources/panels/PageOpDrillingEdit.ui
@@ -56,8 +56,8 @@
The tool and its settings to be used for this operation
-
- -
+
+ -
Do not retract after every hole
@@ -67,6 +67,13 @@
+ -
+
+
+ Edit Tool Controller
+
+
+
diff --git a/src/Mod/CAM/Gui/Resources/panels/PageOpEngraveEdit.ui b/src/Mod/CAM/Gui/Resources/panels/PageOpEngraveEdit.ui
index 3296627d78..e2e5579a33 100644
--- a/src/Mod/CAM/Gui/Resources/panels/PageOpEngraveEdit.ui
+++ b/src/Mod/CAM/Gui/Resources/panels/PageOpEngraveEdit.ui
@@ -51,6 +51,13 @@
+ -
+
+
+ Edit Tool Controller
+
+
+
diff --git a/src/Mod/CAM/Gui/Resources/panels/PageOpHelixEdit.ui b/src/Mod/CAM/Gui/Resources/panels/PageOpHelixEdit.ui
index 02d656535a..574d8371b2 100644
--- a/src/Mod/CAM/Gui/Resources/panels/PageOpHelixEdit.ui
+++ b/src/Mod/CAM/Gui/Resources/panels/PageOpHelixEdit.ui
@@ -51,6 +51,13 @@
+ -
+
+
+ Edit Tool Controller
+
+
+
diff --git a/src/Mod/CAM/Gui/Resources/panels/PageOpPocketFullEdit.ui b/src/Mod/CAM/Gui/Resources/panels/PageOpPocketFullEdit.ui
index ecff4f3a4c..e08bdac8d1 100644
--- a/src/Mod/CAM/Gui/Resources/panels/PageOpPocketFullEdit.ui
+++ b/src/Mod/CAM/Gui/Resources/panels/PageOpPocketFullEdit.ui
@@ -51,6 +51,13 @@
+ -
+
+
+ Edit Tool Controller
+
+
+
diff --git a/src/Mod/CAM/Gui/Resources/panels/PageOpProbeEdit.ui b/src/Mod/CAM/Gui/Resources/panels/PageOpProbeEdit.ui
index d3dc72f8e9..9306803c0b 100644
--- a/src/Mod/CAM/Gui/Resources/panels/PageOpProbeEdit.ui
+++ b/src/Mod/CAM/Gui/Resources/panels/PageOpProbeEdit.ui
@@ -43,6 +43,13 @@
+ -
+
+
+ Edit Tool Controller
+
+
+
diff --git a/src/Mod/CAM/Gui/Resources/panels/PageOpProfileFullEdit.ui b/src/Mod/CAM/Gui/Resources/panels/PageOpProfileFullEdit.ui
index 6b215e43c1..f907d6397a 100644
--- a/src/Mod/CAM/Gui/Resources/panels/PageOpProfileFullEdit.ui
+++ b/src/Mod/CAM/Gui/Resources/panels/PageOpProfileFullEdit.ui
@@ -51,6 +51,13 @@
+ -
+
+
+ Edit Tool Controller
+
+
+
diff --git a/src/Mod/CAM/Gui/Resources/panels/PageOpSlotEdit.ui b/src/Mod/CAM/Gui/Resources/panels/PageOpSlotEdit.ui
index 85f7cd7aa8..b1ece310ef 100644
--- a/src/Mod/CAM/Gui/Resources/panels/PageOpSlotEdit.ui
+++ b/src/Mod/CAM/Gui/Resources/panels/PageOpSlotEdit.ui
@@ -25,7 +25,7 @@
QFrame::Raised
-
+
3
@@ -53,6 +53,13 @@
+ -
+
+
+ Edit Tool Controller
+
+
+
diff --git a/src/Mod/CAM/Gui/Resources/panels/PageOpSurfaceEdit.ui b/src/Mod/CAM/Gui/Resources/panels/PageOpSurfaceEdit.ui
index 9aea7bc7b4..4fe64dbbaf 100644
--- a/src/Mod/CAM/Gui/Resources/panels/PageOpSurfaceEdit.ui
+++ b/src/Mod/CAM/Gui/Resources/panels/PageOpSurfaceEdit.ui
@@ -22,7 +22,7 @@
QFrame::Raised
-
+
-
@@ -51,6 +51,13 @@
+ -
+
+
+ Edit Tool Controller
+
+
+
diff --git a/src/Mod/CAM/Gui/Resources/panels/PageOpTappingEdit.ui b/src/Mod/CAM/Gui/Resources/panels/PageOpTappingEdit.ui
index 242221bf33..133ed66cd6 100644
--- a/src/Mod/CAM/Gui/Resources/panels/PageOpTappingEdit.ui
+++ b/src/Mod/CAM/Gui/Resources/panels/PageOpTappingEdit.ui
@@ -111,6 +111,13 @@
+ -
+
+
+ Edit Tool Controller
+
+
+
diff --git a/src/Mod/CAM/Gui/Resources/panels/PageOpThreadMillingEdit.ui b/src/Mod/CAM/Gui/Resources/panels/PageOpThreadMillingEdit.ui
index 71f59ac8c0..7368d2c161 100644
--- a/src/Mod/CAM/Gui/Resources/panels/PageOpThreadMillingEdit.ui
+++ b/src/Mod/CAM/Gui/Resources/panels/PageOpThreadMillingEdit.ui
@@ -15,13 +15,34 @@
-
-
-
- Tool Controller
+
+
+ QFrame::StyledPanel
-
-
-
-
+
+ QFrame::Raised
+
+
+
-
+
+
+ Tool Controller
+
+
+
+ -
+
+
+ The tool and its settings to be used for this operation.
+
+
+
+ -
+
+
+ Edit Tool Controller
+
+
diff --git a/src/Mod/CAM/Gui/Resources/panels/PageOpVcarveEdit.ui b/src/Mod/CAM/Gui/Resources/panels/PageOpVcarveEdit.ui
index 3115241023..e403fa39bc 100644
--- a/src/Mod/CAM/Gui/Resources/panels/PageOpVcarveEdit.ui
+++ b/src/Mod/CAM/Gui/Resources/panels/PageOpVcarveEdit.ui
@@ -51,6 +51,13 @@
+ -
+
+
+ Edit Tool Controller
+
+
+
diff --git a/src/Mod/CAM/Gui/Resources/panels/PageOpWaterlineEdit.ui b/src/Mod/CAM/Gui/Resources/panels/PageOpWaterlineEdit.ui
index 1e7b8c6cf4..173f0d78b4 100644
--- a/src/Mod/CAM/Gui/Resources/panels/PageOpWaterlineEdit.ui
+++ b/src/Mod/CAM/Gui/Resources/panels/PageOpWaterlineEdit.ui
@@ -22,7 +22,7 @@
QFrame::Raised
-
+
-
@@ -47,6 +47,13 @@
+ -
+
+
+ Edit Tool Controller
+
+
+
diff --git a/src/Mod/CAM/Gui/Resources/panels/SurfaceEdit.ui b/src/Mod/CAM/Gui/Resources/panels/SurfaceEdit.ui
deleted file mode 100644
index 7bb41cbd01..0000000000
--- a/src/Mod/CAM/Gui/Resources/panels/SurfaceEdit.ui
+++ /dev/null
@@ -1,351 +0,0 @@
-
-
- TaskPanel
-
-
-
- 0
- 0
- 363
- 523
-
-
-
-
- 0
- 400
-
-
-
- Surface
-
-
- -
-
-
- 3
-
-
-
- true
-
-
-
- 0
- 0
- 347
- 391
-
-
-
-
- :/icons/CAM_BaseGeometry.svg:/icons/CAM_BaseGeometry.svg
-
-
- Base geometry
-
-
-
-
-
-
- Drag to reorder, then update
-
-
- QAbstractItemView::DragDrop
-
-
- Qt::MoveAction
-
-
- false
-
-
-
- -
-
-
- Add item selected in window
-
-
- Add
-
-
-
- -
-
-
- Remove item selected in list, then update
-
-
- Remove
-
-
-
- -
-
-
- Update the path with the removed and reordered items
-
-
- Update
-
-
-
- -
-
-
- All objects will be profiled using the same depth and speed settings
-
-
- Qt::AutoText
-
-
- true
-
-
-
-
-
-
-
-
- 0
- 0
- 347
- 391
-
-
-
-
- :/icons/CAM_Depths.svg:/icons/CAM_Depths.svg
-
-
- Depths
-
-
- -
-
-
- mm
-
-
-
- -
-
-
- Start depth
-
-
-
- -
-
-
- mm
-
-
-
- -
-
-
- Final depth
-
-
-
- -
-
-
- mm
-
-
-
- -
-
-
- Step down
-
-
-
- -
-
-
- mm
-
-
-
- -
-
-
- Finish step down
-
-
-
-
-
-
-
-
- 0
- 0
- 347
- 391
-
-
-
-
- :/icons/CAM_Heights.svg:/icons/CAM_Heights.svg
-
-
- Heights
-
-
-
- QFormLayout::AllNonFixedFieldsGrow
-
- -
-
-
- mm
-
-
-
- -
-
-
- Safe height
-
-
-
- -
-
-
- mm
-
-
-
- -
-
-
- Clearance height
-
-
-
-
-
-
-
-
- 0
- 0
- 347
- 391
-
-
-
-
- :/icons/CAM_OperationB.svg:/icons/CAM_OperationB.svg
-
-
- Operation
-
-
- -
-
-
- QFrame::StyledPanel
-
-
- QFrame::Raised
-
-
-
-
-
-
- Tool controller
-
-
-
- -
-
-
- -
-
-
- Coolant mode
-
-
-
- -
-
-
- The tool and its settings to be used for this operation.
-
-
-
-
-
-
- -
-
-
- QFrame::StyledPanel
-
-
- QFrame::Raised
-
-
-
-
-
-
- Algorithm
-
-
-
- -
-
-
-
-
- OCL dropcutter
-
-
- -
-
- OCL waterline
-
-
-
-
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 274
-
-
-
-
-
-
-
-
-
-
-
-
- Gui::InputField
- QLineEdit
-
-
-
-
-
-
-
-
-
diff --git a/src/Mod/CAM/Gui/Resources/panels/ToolControllerEdit.ui b/src/Mod/CAM/Gui/Resources/panels/ToolControllerEdit.ui
new file mode 100644
index 0000000000..bbb94b24b2
--- /dev/null
+++ b/src/Mod/CAM/Gui/Resources/panels/ToolControllerEdit.ui
@@ -0,0 +1,240 @@
+
+
+ Frame
+
+
+
+ 0
+ 0
+ 561
+ 739
+
+
+
+ QFrame::NoFrame
+
+
+ QFrame::Raised
+
+
+ -
+
+
+ -
+
+
+ Controller Name / Tool Number
+
+
+
-
+
+
+ false
+
+
+
+ -
+
+
+ Qt::StrongFocus
+
+
+ QAbstractSpinBox::NoButtons
+
+
+ 99999
+
+
+
+
+
+
+ -
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
-
+
+
+ Horizontal feed
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ 0.000000000000000
+
+
+ 9999999.000000000000000
+
+
+ mm/s
+
+
+
+ -
+
+
+ Vertical feed
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ 0.000000000000000
+
+
+ 9999999.000000000000000
+
+
+ mm/s
+
+
+
+ -
+
+
+ Horizontal rapid
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ 0.000000000000000
+
+
+ 9999999.000000000000000
+
+
+ mm/s
+
+
+
+ -
+
+
+ Vertical rapid
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ 0.000000000000000
+
+
+ 9999999.000000000000000
+
+
+ mm/s
+
+
+
+
+
+
+ -
+
+
+ Spindle
+
+
+
+ QFormLayout::AllNonFixedFieldsGrow
+
+
-
+
+
+ Qt::StrongFocus
+
+
-
+
+ Forward
+
+
+ -
+
+ Reverse
+
+
+
+
+ -
+
+
+ 0.000000000000000
+
+
+ 100000.000000000000000
+
+
+
+
+
+
+
+
+
+
+ Gui::QuantitySpinBox
+ QDoubleSpinBox
+
+
+
+
+ tcName
+ tcNumber
+ horizFeed
+ vertFeed
+ horizRapid
+ vertRapid
+ spindleSpeed
+ spindleDirection
+
+
+
+
diff --git a/src/Mod/CAM/Path/Main/Gui/Camotics.py b/src/Mod/CAM/Path/Main/Gui/Camotics.py
index 2be847ed63..3c28187ef0 100644
--- a/src/Mod/CAM/Path/Main/Gui/Camotics.py
+++ b/src/Mod/CAM/Path/Main/Gui/Camotics.py
@@ -28,6 +28,7 @@ import FreeCADGui
import Mesh
import Path
import PathScripts
+import PathScripts.PathUtils as PathUtils
import Path.Post.Command as PathPost
import camotics
import io
@@ -191,7 +192,7 @@ class CamoticsSimulation(QtCore.QObject):
self.SIM.set_tool(
t.ToolNumber,
metric=True,
- shape=self.SHAPEMAP.get(t.Tool.ShapeName, "Cylindrical"),
+ shape=self.SHAPEMAP.get(PathUtils.getToolShapeName(t.Tool), "Cylindrical"),
length=t.Tool.Length.Value,
diameter=t.Tool.Diameter.Value,
)
@@ -283,7 +284,9 @@ class CamoticsSimulation(QtCore.QObject):
if hasattr(t.Tool, "Camotics"):
toolitem["shape"] = t.Tool.Camotics
else:
- toolitem["shape"] = self.SHAPEMAP.get(t.Tool.ShapeName, "Cylindrical")
+ toolitem["shape"] = self.SHAPEMAP.get(
+ PathUtils.getToolShapeName(t.Tool), "Cylindrical"
+ )
toolitem["length"] = t.Tool.Length.Value
toolitem["diameter"] = t.Tool.Diameter.Value
diff --git a/src/Mod/CAM/Path/Op/Gui/Adaptive.py b/src/Mod/CAM/Path/Op/Gui/Adaptive.py
index d16b6ace33..58abd359ba 100644
--- a/src/Mod/CAM/Path/Op/Gui/Adaptive.py
+++ b/src/Mod/CAM/Path/Op/Gui/Adaptive.py
@@ -57,7 +57,7 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage):
signals = []
signals.append(self.form.Side.currentIndexChanged)
signals.append(self.form.OperationType.currentIndexChanged)
- signals.append(self.form.ToolController.currentIndexChanged)
+ signals.append(self.form.toolController.currentIndexChanged)
signals.append(self.form.stepOverPercent.valueChanged)
signals.append(self.form.Tolerance.valueChanged)
signals.append(self.form.HelixAngle.valueChanged)
@@ -113,7 +113,7 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage):
self.form.FinishingProfile.setChecked(obj.FinishingProfile)
self.form.useOutline.setChecked(obj.UseOutline)
self.form.orderCutsByRegion.setChecked(obj.OrderCutsByRegion)
- self.setupToolController(obj, self.form.ToolController)
+ self.setupToolController(obj, self.form.toolController)
self.setupCoolant(obj, self.form.coolantController)
self.form.StopButton.setChecked(obj.Stopped)
obj.setEditorMode("AdaptiveInputState", 2) # hide this property
@@ -155,7 +155,7 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage):
self.form.StopButton.setChecked(False) # reset the button
obj.StopProcessing = True
- self.updateToolController(obj, self.form.ToolController)
+ self.updateToolController(obj, self.form.toolController)
self.updateCoolant(obj, self.form.coolantController)
obj.setEditorMode("AdaptiveInputState", 2) # hide this property
obj.setEditorMode("AdaptiveOutputState", 2) # hide this property
diff --git a/src/Mod/CAM/Path/Op/Gui/Base.py b/src/Mod/CAM/Path/Op/Gui/Base.py
index 141b79bc75..2cda1f989e 100644
--- a/src/Mod/CAM/Path/Op/Gui/Base.py
+++ b/src/Mod/CAM/Path/Op/Gui/Base.py
@@ -30,12 +30,14 @@ import Path.Base.Util as PathUtil
import Path.Main.Job as PathJob
import Path.Op.Base as PathOp
import Path.Op.Gui.Selection as PathSelection
+import Path.Tool.Controller as PathToolController
+from Path.Tool.library.ui.dock import ToolBitLibraryDock
import PathGui
import PathScripts.PathUtils as PathUtils
import importlib
from PySide.QtCore import QT_TRANSLATE_NOOP
-from PySide import QtCore, QtGui
+from PySide import QtCore, QtGui, QtWidgets
__title__ = "CAM Operation UI base classes"
__author__ = "sliptonic (Brad Collette)"
@@ -212,9 +214,12 @@ class TaskPanelPage(object):
self.isdirty = False
self.parent = None
self.panelTitle = "Operation"
+ self.tcEditor = None
+ self.combo = None
if self._installTCUpdate():
PathJob.Notification.updateTC.connect(self.resetToolController)
+ self.form.toolController.currentIndexChanged.connect(self.tcComboChanged)
def show_error_message(self, title, message):
msg_box = QtGui.QMessageBox()
@@ -389,27 +394,141 @@ class TaskPanelPage(object):
"""populateCombobox(form, enumTups, comboBoxesPropertyMap) ... proxy for PathGuiUtil.populateCombobox()"""
PathGuiUtil.populateCombobox(form, enumTups, comboBoxesPropertyMap)
+ def tcComboChanged(self, newIndex):
+ if self.obj is not None and self.tcEditor:
+ if newIndex == self.combo.count() - 1:
+ # Special entry: new tool controller. Show the tool dock and reset combo
+ dock = ToolBitLibraryDock(self.job, True)
+ dock.open()
+ self.resetTCCombo()
+ elif newIndex == self.combo.count() - 2:
+ # Special entry: copy tool controller
+ self.copyToolController() # this function also rebuilds the combo
+ self.resetTCCombo()
+ else:
+ tc = PathUtils.findToolController(
+ self.obj, self.obj.Proxy, self.form.toolController.currentText()
+ )
+ self.obj.ToolController = tc
+ self.setupToolController()
+
+ def updateToolControllerEditorVisibility(self):
+ if self.form.editToolController.isChecked():
+ self.tcEditor.controller.show()
+ else:
+ self.tcEditor.controller.hide()
+
def resetToolController(self, job, tc):
if self.obj is not None:
self.obj.ToolController = tc
- combo = self.form.toolController
- self.setupToolController(self.obj, combo)
+ self.setupToolController()
- def setupToolController(self, obj, combo):
+ def copyToolController(self):
+ oldTc = self.tcEditor.obj
+ self.tcEditor.updateToolController()
+ tc = PathToolController.Create(
+ name=oldTc.Label, tool=oldTc.Tool, toolNumber=oldTc.ToolNumber
+ )
+ job = self.obj.Proxy.getJob(self.obj)
+ job.Proxy.addToolController(tc)
+
+ tc.HorizFeed = oldTc.HorizFeed
+ tc.VertFeed = oldTc.VertFeed
+ tc.HorizRapid = oldTc.HorizRapid
+ tc.VertRapid = oldTc.VertRapid
+ tc.SpindleSpeed = oldTc.SpindleSpeed
+ tc.SpindleDir = oldTc.SpindleDir
+ for attr, expr in oldTc.ExpressionEngine:
+ tc.setExpression(attr, expr)
+
+ self.obj.ToolController = tc
+ self.setupToolController()
+
+ def tcEditorChanged(self):
+ self.setDirty()
+ self.resetTCCombo()
+
+ def resetTCCombo(self):
+ controllers = PathUtils.getToolControllers(self.obj)
+
+ if self.obj.ToolController is None:
+ self.obj.ToolController = PathUtils.findToolController(self.obj, self.obj.Proxy)
+ if len(controllers) > 0 and not self.obj.Proxy.isToolSupported(
+ self.obj, self.obj.ToolController.Tool
+ ):
+ self.obj.ToolController = controllers[0]
+
+ tcName = self.obj.ToolController.Label if self.obj.ToolController else ""
+ labels = [c.Label for c in controllers]
+ labels.append(FreeCAD.Qt.translate("CAM_Operation", "Copy {0}…").format(tcName))
+ labels.append(FreeCAD.Qt.translate("CAM_Operation", "New tool controller…"))
+ self.combo.blockSignals(True)
+ self.combo.clear()
+ self.combo.addItems(labels)
+ self.combo.insertSeparator(len(controllers))
+ self.combo.blockSignals(False)
+
+ if self.obj.ToolController is not None:
+ self.selectInComboBox(self.obj.ToolController.Label, self.combo)
+
+ def setupToolController(self, obj=None, combo=None):
"""setupToolController(obj, combo) ...
helper function to setup obj's ToolController
in the given combo box."""
- controllers = PathUtils.getToolControllers(self.obj)
- labels = [c.Label for c in controllers]
- combo.blockSignals(True)
- combo.clear()
- combo.addItems(labels)
- combo.blockSignals(False)
+ obj = obj or self.obj
+ combo = combo or self.combo
+ self.obj, self.combo = obj, combo
- if obj.ToolController is None:
- obj.ToolController = PathUtils.findToolController(obj, obj.Proxy)
- if obj.ToolController is not None:
- self.selectInComboBox(obj.ToolController.Label, combo)
+ self.resetTCCombo()
+
+ if hasattr(self.form, "editToolController"):
+ layout = self.form.editToolController.parent().layout()
+ oldEditor = self.tcEditor
+
+ # Count the number of times the tool controller is used in other operations
+ # If it is used in other operations, we will offer the "copy tool controller" button
+ tcCount = 0
+ for job in PathUtils.GetJobs():
+ for op in job.Operations.Group:
+ if op == self.obj:
+ continue
+ elif hasattr(op, "ToolController") and op.ToolController == obj.ToolController:
+ tcCount += 1
+
+ self.tcEditor = Path.Tool.Gui.Controller.ToolControllerEditor(
+ obj.ToolController,
+ False,
+ self.tcEditorChanged,
+ True,
+ True,
+ )
+ self.tcEditor.setupUi()
+
+ labelStr = FreeCAD.Qt.translate(
+ "CAM_Operation", "This tool controller is used by {0} other operations."
+ ).format(tcCount)
+ self.tcEditor.controller.tcOperationCountLabel.setText(labelStr)
+
+ # add to layout -- requires a grid layout
+ if isinstance(layout, QtWidgets.QGridLayout):
+ layout.addWidget(
+ self.tcEditor.controller, layout.rowCount(), 0, 1, layout.columnCount()
+ )
+ else:
+ Path.Log.error(
+ "Panel uses a layout incompatible with editing tool controllers. Report a bug: it should be a QGridLayout"
+ )
+
+ self.updateToolControllerEditorVisibility()
+ self.tcEditor.updateUi()
+ self.form.editToolController.checkStateChanged.connect(
+ self.updateToolControllerEditorVisibility
+ )
+
+ if oldEditor:
+ oldEditor.updateToolController()
+ oldEditor.controller.hide()
+ layout.removeWidget(oldEditor.controller)
def updateToolController(self, obj, combo):
"""updateToolController(obj, combo) ...
@@ -418,6 +537,8 @@ class TaskPanelPage(object):
tc = PathUtils.findToolController(obj, obj.Proxy, combo.currentText())
if obj.ToolController != tc:
obj.ToolController = tc
+ if self.tcEditor:
+ self.tcEditor.updateToolController()
def setupCoolant(self, obj, combo):
"""setupCoolant(obj, combo) ...
diff --git a/src/Mod/CAM/Path/Op/Probe.py b/src/Mod/CAM/Path/Op/Probe.py
index d1523f4473..b8ae6edcea 100644
--- a/src/Mod/CAM/Path/Op/Probe.py
+++ b/src/Mod/CAM/Path/Op/Probe.py
@@ -134,7 +134,7 @@ class ObjectProbing(PathOp.ObjectOp):
def isToolSupported(self, obj, tool):
"""Probe operation requires a probe tool"""
- support = hasattr(tool, "ShapeName") and (tool.ShapeName == "probe")
+ support = PathUtils.getToolShapeName(tool) == "probe"
Path.Log.track(tool.Label, support)
return support
diff --git a/src/Mod/CAM/Path/Tool/Gui/Controller.py b/src/Mod/CAM/Path/Tool/Gui/Controller.py
index bc40b82154..f5712e1c71 100644
--- a/src/Mod/CAM/Path/Tool/Gui/Controller.py
+++ b/src/Mod/CAM/Path/Tool/Gui/Controller.py
@@ -188,80 +188,104 @@ class CommandPathToolController(object):
FreeCAD.ActiveDocument.recompute()
+class BlockScrollWheel(QtCore.QObject):
+ def eventFilter(self, obj, event):
+ if event.type() == QtCore.QEvent.Type.Wheel:
+ if not obj.hasFocus():
+ return True
+ return super().eventFilter(obj, event)
+
+
class ToolControllerEditor(object):
- def __init__(self, obj, asDialog):
+
+ def __init__(
+ self, obj, asDialog, notifyChanged=None, showCountLabel=False, disableToolNumber=False
+ ):
+ self.notifyChanged = notifyChanged
self.form = FreeCADGui.PySideUic.loadUi(":/panels/DlgToolControllerEdit.ui")
+ self.controller = FreeCADGui.PySideUic.loadUi(":/panels/ToolControllerEdit.ui")
+ self.form.tc_layout.addWidget(self.controller)
if not asDialog:
self.form.buttonBox.hide()
+ if not showCountLabel:
+ self.controller.tcOperationCountLabel.hide()
self.obj = obj
comboToPropertyMap = [("spindleDirection", "SpindleDir")]
enumTups = PathToolController.ToolController.propertyEnumerations(dataType="raw")
- PathGuiUtil.populateCombobox(self.form, enumTups, comboToPropertyMap)
- self.vertFeed = PathGuiUtil.QuantitySpinBox(self.form.vertFeed, obj, "VertFeed")
- self.horizFeed = PathGuiUtil.QuantitySpinBox(self.form.horizFeed, obj, "HorizFeed")
- self.vertRapid = PathGuiUtil.QuantitySpinBox(self.form.vertRapid, obj, "VertRapid")
- self.horizRapid = PathGuiUtil.QuantitySpinBox(self.form.horizRapid, obj, "HorizRapid")
+ PathGuiUtil.populateCombobox(self.controller, enumTups, comboToPropertyMap)
+ self.vertFeed = PathGuiUtil.QuantitySpinBox(self.controller.vertFeed, obj, "VertFeed")
+ self.horizFeed = PathGuiUtil.QuantitySpinBox(self.controller.horizFeed, obj, "HorizFeed")
+ self.vertRapid = PathGuiUtil.QuantitySpinBox(self.controller.vertRapid, obj, "VertRapid")
+ self.horizRapid = PathGuiUtil.QuantitySpinBox(self.controller.horizRapid, obj, "HorizRapid")
+
+ self.blockScrollWheel = BlockScrollWheel()
+ self.controller.tcNumber.installEventFilter(self.blockScrollWheel)
+ self.controller.spindleDirection.installEventFilter(self.blockScrollWheel)
+ self.controller.tcNumber.setReadOnly(disableToolNumber)
self.editor = None
- self.form.toolBox.widget(1).hide()
- self.form.toolBox.removeItem(1)
def selectInComboBox(self, name, combo):
"""selectInComboBox(name, combo) ...
helper function to select a specific value in a combo box."""
- blocker = QtCore.QSignalBlocker(combo)
- index = combo.currentIndex() # Save initial index
+ with QtCore.QSignalBlocker(combo):
+ index = combo.currentIndex() # Save initial index
- # Search using currentData and return if found
- newindex = combo.findData(name)
- if newindex >= 0:
- combo.setCurrentIndex(newindex)
- return
+ # Search using currentData and return if found
+ newindex = combo.findData(name)
+ if newindex >= 0:
+ combo.setCurrentIndex(newindex)
+ return
- # if not found, search using current text
- newindex = combo.findText(name, QtCore.Qt.MatchFixedString)
- if newindex >= 0:
- combo.setCurrentIndex(newindex)
- return
+ # if not found, search using current text
+ newindex = combo.findText(name, QtCore.Qt.MatchFixedString)
+ if newindex >= 0:
+ combo.setCurrentIndex(newindex)
+ return
- # not found, return unchanged
- combo.setCurrentIndex(index)
+ # not found, return unchanged
+ combo.setCurrentIndex(index)
return
def updateUi(self):
tc = self.obj
- self.form.tcName.setText(tc.Label)
- self.form.tcNumber.setValue(tc.ToolNumber)
- self.horizFeed.updateWidget()
- self.horizRapid.updateWidget()
- self.vertFeed.updateWidget()
- self.vertRapid.updateWidget()
- self.form.spindleSpeed.setValue(tc.SpindleSpeed)
- self.selectInComboBox(tc.SpindleDir, self.form.spindleDirection)
+ with (
+ QtCore.QSignalBlocker(self.controller.tcName),
+ QtCore.QSignalBlocker(self.controller.tcNumber),
+ QtCore.QSignalBlocker(self.horizFeed.widget),
+ QtCore.QSignalBlocker(self.horizRapid.widget),
+ QtCore.QSignalBlocker(self.vertFeed.widget),
+ QtCore.QSignalBlocker(self.vertRapid.widget),
+ QtCore.QSignalBlocker(self.controller.spindleSpeed),
+ QtCore.QSignalBlocker(self.controller.spindleDirection),
+ ):
+ self.controller.tcName.setText(tc.Label)
+ self.controller.tcNumber.setValue(tc.ToolNumber)
+ self.horizFeed.updateWidget()
+ self.horizRapid.updateWidget()
+ self.vertFeed.updateWidget()
+ self.vertRapid.updateWidget()
+ self.controller.spindleSpeed.setValue(tc.SpindleSpeed)
- # index = self.form.spindleDirection.findText(
- # tc.SpindleDir, QtCore.Qt.MatchFixedString
- # )
- # if index >= 0:
- # self.form.spindleDirection.setCurrentIndex(index)
+ self.selectInComboBox(tc.SpindleDir, self.controller.spindleDirection)
- if self.editor:
- self.editor.updateUI()
+ if self.editor:
+ self.editor.updateUI()
def updateToolController(self):
tc = self.obj
try:
- tc.Label = self.form.tcName.text()
- tc.ToolNumber = self.form.tcNumber.value()
+ tc.Label = self.controller.tcName.text()
+ tc.ToolNumber = self.controller.tcNumber.value()
self.horizFeed.updateProperty()
self.vertFeed.updateProperty()
self.horizRapid.updateProperty()
self.vertRapid.updateProperty()
- tc.SpindleSpeed = self.form.spindleSpeed.value()
- tc.SpindleDir = self.form.spindleDirection.currentData()
+ tc.SpindleSpeed = self.controller.spindleSpeed.value()
+ tc.SpindleDir = self.controller.spindleDirection.currentData()
if self.editor:
self.editor.updateTool()
@@ -270,23 +294,29 @@ class ToolControllerEditor(object):
except Exception as e:
Path.Log.error("Error updating TC: {}".format(e))
- def refresh(self):
+ def changed(self):
self.form.blockSignals(True)
+ self.controller.blockSignals(True)
self.updateToolController()
self.updateUi()
+ self.controller.blockSignals(False)
self.form.blockSignals(False)
+ if self.notifyChanged:
+ self.notifyChanged()
+
def setupUi(self):
if self.editor:
self.editor.setupUI()
- self.form.tcName.editingFinished.connect(self.refresh)
- self.form.horizFeed.editingFinished.connect(self.refresh)
- self.form.vertFeed.editingFinished.connect(self.refresh)
- self.form.horizRapid.editingFinished.connect(self.refresh)
- self.form.vertRapid.editingFinished.connect(self.refresh)
- self.form.spindleSpeed.editingFinished.connect(self.refresh)
- self.form.spindleDirection.currentIndexChanged.connect(self.refresh)
+ self.controller.tcName.textChanged.connect(self.changed)
+ self.controller.tcNumber.editingFinished.connect(self.changed)
+ self.vertFeed.widget.textChanged.connect(self.changed)
+ self.horizFeed.widget.textChanged.connect(self.changed)
+ self.vertRapid.widget.textChanged.connect(self.changed)
+ self.horizRapid.widget.textChanged.connect(self.changed)
+ self.controller.spindleSpeed.editingFinished.connect(self.changed)
+ self.controller.spindleDirection.currentIndexChanged.connect(self.changed)
class TaskPanel:
@@ -359,6 +389,9 @@ class DlgToolControllerEdit:
Path.Log.info("revert")
self.obj.Proxy.setFromTemplate(self.obj, restoreTC)
rc = True
+ else:
+ self.editor.updateToolController()
+ self.obj.Proxy.execute(self.obj)
return rc
diff --git a/src/Mod/CAM/Path/Tool/library/ui/cmd.py b/src/Mod/CAM/Path/Tool/library/ui/cmd.py
index a1f9f94f99..c1dc9d0798 100644
--- a/src/Mod/CAM/Path/Tool/library/ui/cmd.py
+++ b/src/Mod/CAM/Path/Tool/library/ui/cmd.py
@@ -48,8 +48,10 @@ class CommandToolBitLibraryDockOpen:
def GetResources(self):
return {
"Pixmap": "CAM_ToolTable",
- "MenuText": QT_TRANSLATE_NOOP("CAM_ToolBitDock", "Toolbit Dock"),
- "ToolTip": QT_TRANSLATE_NOOP("CAM_ToolBitDock", "Toggles the toolbit dock"),
+ "MenuText": QT_TRANSLATE_NOOP("CAM_ToolBitSelection", "Add toolbit…"),
+ "ToolTip": QT_TRANSLATE_NOOP(
+ "CAM_ToolBitSelection", "Opens the toolbit selection dialog"
+ ),
"Accel": "P, T",
"CmdType": "ForEdit",
}
diff --git a/src/Mod/CAM/Path/Tool/library/ui/dock.py b/src/Mod/CAM/Path/Tool/library/ui/dock.py
index 2667af7a64..6606bfeb44 100644
--- a/src/Mod/CAM/Path/Tool/library/ui/dock.py
+++ b/src/Mod/CAM/Path/Tool/library/ui/dock.py
@@ -28,7 +28,7 @@ import FreeCADGui
import Path
import Path.Tool.Gui.Controller as PathToolControllerGui
import PathScripts.PathUtilsGui as PathUtilsGui
-from PySide import QtGui, QtCore
+from PySide import QtGui, QtCore, QtWidgets
from functools import partial
from typing import List, Tuple
from ...camassets import cam_assets, ensure_assets_initialized
@@ -50,12 +50,20 @@ translate = FreeCAD.Qt.translate
class ToolBitLibraryDock(object):
"""Controller for displaying a library and creating ToolControllers"""
- def __init__(self):
+ def __init__(self, defaultJob=None, autoClose=False):
ensure_assets_initialized(cam_assets)
# Create the main form widget directly
- self.form = QtGui.QDockWidget()
+ self.defaultJob = defaultJob
+ self.autoClose = autoClose
+ self.form = QtWidgets.QDialog()
self.form.setObjectName("ToolSelector")
self.form.setWindowTitle(translate("CAM_ToolBit", "Tool Selector"))
+ self.form.setMinimumSize(600, 400)
+ self.form.resize(800, 600)
+ self.form.adjustSize()
+ self.form_layout = QtGui.QVBoxLayout(self.form)
+ self.form_layout.setContentsMargins(4, 4, 4, 4)
+ self.form_layout.setSpacing(4)
# Create the browser widget
self.browser_widget = LibraryBrowserWidget(asset_manager=cam_assets)
@@ -69,6 +77,8 @@ class ToolBitLibraryDock(object):
# Create a main widget and layout for the dock
main_widget = QtGui.QWidget()
main_layout = QtGui.QVBoxLayout(main_widget)
+ main_layout.setContentsMargins(4, 4, 4, 4)
+ main_layout.setSpacing(4)
# Add the browser widget to the layout
main_layout.addWidget(self.browser_widget)
@@ -88,7 +98,7 @@ class ToolBitLibraryDock(object):
main_layout.addLayout(button_layout)
# Set the main widget as the dock's widget
- self.form.setWidget(main_widget)
+ self.form.layout().addWidget(main_widget)
# Connect signals from the browser widget and buttons
self.browser_widget.toolSelected.connect(self._update_state)
@@ -152,11 +162,12 @@ class ToolBitLibraryDock(object):
translate("CAM_ToolBit", "Please create a Job first."),
)
return
- elif len(jobs) == 1:
- job = jobs[0]
+ elif self.defaultJob or len(jobs) == 1:
+ job = self.defaultJob or jobs[0]
else:
userinput = PathUtilsGui.PathUtilsUserInput()
job = userinput.chooseJob(jobs)
+ self.defaultJob = job
if job is None: # user may have canceled
return
@@ -169,21 +180,9 @@ class ToolBitLibraryDock(object):
job.Proxy.addToolController(tc)
FreeCAD.ActiveDocument.recompute()
+ if self.autoClose:
+ self.form.accept()
+
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)
- return
-
- mw = FreeCADGui.getMainWindow()
- mw.addDockWidget(
- QtCore.Qt.RightDockWidgetArea,
- self.form,
- QtCore.Qt.Orientation.Vertical,
- )
+ self.form.exec_()
diff --git a/src/Mod/CAM/PathScripts/PathUtils.py b/src/Mod/CAM/PathScripts/PathUtils.py
index 10a846456c..367d03c63e 100644
--- a/src/Mod/CAM/PathScripts/PathUtils.py
+++ b/src/Mod/CAM/PathScripts/PathUtils.py
@@ -357,6 +357,14 @@ def getToolControllers(obj, proxy=None):
return []
+def getToolShapeName(tool):
+ if hasattr(tool, "ShapeName"):
+ return tool.ShapeName.lower()
+ if hasattr(tool, "ShapeType"):
+ return tool.ShapeType.lower()
+ return ""
+
+
def findToolController(obj, proxy, name=None):
"""returns a tool controller with a given name.
If no name is specified, returns the first controller.