diff --git a/src/Mod/Path/CMakeLists.txt b/src/Mod/Path/CMakeLists.txt
index 0f87dd5849..37a60d27d3 100644
--- a/src/Mod/Path/CMakeLists.txt
+++ b/src/Mod/Path/CMakeLists.txt
@@ -60,6 +60,7 @@ SET(PathScripts_SRCS
PathScripts/PathInspect.py
PathScripts/PathJob.py
PathScripts/PathJobCmd.py
+ PathScripts/PathJobDlg.py
PathScripts/PathJobGui.py
PathScripts/PathLog.py
PathScripts/PathMillFace.py
diff --git a/src/Mod/Path/Gui/Resources/panels/DlgJobCreate.ui b/src/Mod/Path/Gui/Resources/panels/DlgJobCreate.ui
index 818ea2cb83..35f6c6500a 100644
--- a/src/Mod/Path/Gui/Resources/panels/DlgJobCreate.ui
+++ b/src/Mod/Path/Gui/Resources/panels/DlgJobCreate.ui
@@ -67,16 +67,6 @@
-
-
- Base Models
-
-
- -
-
-
-
-
diff --git a/src/Mod/Path/PathScripts/PathJob.py b/src/Mod/Path/PathScripts/PathJob.py
index 482b3f41d9..f0cd09aedb 100644
--- a/src/Mod/Path/PathScripts/PathJob.py
+++ b/src/Mod/Path/PathScripts/PathJob.py
@@ -66,7 +66,7 @@ def isArchPanelSheet(obj):
return hasattr(obj, 'Proxy') and isinstance(obj.Proxy, ArchPanel.PanelSheet)
def isResourceClone(obj, propLink, resourceName):
- if hasattr(propLink, 'PathResource') and resourceName == propLink.PathResource:
+ if hasattr(propLink, 'PathResource') and (resourceName is None or resourceName == propLink.PathResource):
return True
return False
@@ -175,7 +175,7 @@ class ObjectJob:
# base doesn't depend on anything inside job
for base in obj.Model.Group:
- PathLog.debug("taking down base " % base.Label)
+ PathLog.debug("taking down base %s" % base.Label)
if isResourceClone(obj, base, 'Model'):
PathUtil.clearExpressionEngine(base)
doc.removeObject(base.Name)
diff --git a/src/Mod/Path/PathScripts/PathJobCmd.py b/src/Mod/Path/PathScripts/PathJobCmd.py
index 7cb6c8f0c3..655a4bf130 100644
--- a/src/Mod/Path/PathScripts/PathJobCmd.py
+++ b/src/Mod/Path/PathScripts/PathJobCmd.py
@@ -25,13 +25,12 @@
import FreeCAD
import FreeCADGui
import PathScripts.PathJob as PathJob
+import PathScripts.PathJobDlg as PathJobDlg
import PathScripts.PathLog as PathLog
import PathScripts.PathPreferences as PathPreferences
import PathScripts.PathStock as PathStock
import PathScripts.PathUtil as PathUtil
-import glob
import json
-import os
from PySide import QtCore, QtGui
@@ -39,69 +38,11 @@ from PySide import QtCore, QtGui
def translate(context, text, disambig=None):
return QtCore.QCoreApplication.translate(context, text, disambig)
-class DlgJobCreate:
- DataObject = QtCore.Qt.ItemDataRole.UserRole
-
- def __init__(self, parent=None):
- self.dialog = FreeCADGui.PySideUic.loadUi(":/panels/DlgJobCreate.ui")
- self.items = []
-
- sel = FreeCADGui.Selection.getSelection()
- if sel:
- selected = [s.Label for s in sel]
- else:
- selected = None
- index = 0
- for base in sorted(PathJob.ObjectJob.baseCandidates(), key=lambda o: o.Label):
- item = QtGui.QListWidgetItem(base.Label)
- item.setData(self.DataObject, base)
- item.setCheckState(QtCore.Qt.CheckState.Checked if base.Label in selected else QtCore.Qt.CheckState.Unchecked)
- if PathUtil.isSolid(base):
- self.dialog.solidList.addItem(item)
- else:
- self.dialog.twoDList.addItem(item)
- self.items.append(item)
-
- templateFiles = []
- for path in PathPreferences.searchPaths():
- templateFiles.extend(self.templateFilesIn(path))
-
- template = {}
- for tFile in templateFiles:
- name = os.path.split(os.path.splitext(tFile)[0])[1][4:]
- if name in template:
- basename = name
- i = 0
- while name in template:
- i = i + 1
- name = basename + " (%s)" % i
- PathLog.track(name, tFile)
- template[name] = tFile
- selectTemplate = PathPreferences.defaultJobTemplate()
- index = 0
- self.dialog.jobTemplate.addItem('', '')
- for name in sorted(template.keys()):
- if template[name] == selectTemplate:
- index = self.dialog.jobTemplate.count()
- self.dialog.jobTemplate.addItem(name, template[name])
- self.dialog.jobTemplate.setCurrentIndex(index)
-
- def templateFilesIn(self, path):
- '''templateFilesIn(path) ... answer all file in the given directory which fit the job template naming convention.
- PathJob template files are name job_*.json'''
- PathLog.track(path)
- return glob.glob(path + '/job_*.json')
-
- def getModels(self):
- '''answer the base models selected for the job'''
- return [item.data(self.DataObject) for item in self.items if item.checkState() == QtCore.Qt.CheckState.Checked]
-
- def getTemplate(self):
- '''answer the file name of the template to be assigned'''
- return self.dialog.jobTemplate.itemData(self.dialog.jobTemplate.currentIndex())
-
- def exec_(self):
- return self.dialog.exec_()
+if False:
+ PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
+ PathLog.trackModule(PathLog.thisModule())
+else:
+ PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
class CommandJobCreate:
'''
@@ -120,7 +61,9 @@ class CommandJobCreate:
return FreeCAD.ActiveDocument is not None
def Activated(self):
- dialog = DlgJobCreate()
+ dialog = PathJobDlg.JobCreate()
+ dialog.setupTemplate()
+ dialog.setupModel()
if dialog.exec_() == 1:
models = dialog.getModels()
if models:
@@ -280,7 +223,7 @@ class CommandJobTemplateExport:
def Activated(self):
job = self.GetJob()
- dialog = DlgJobTemplateExport(job)
+ dialog = PathJobDlg.JobTemplateExport(job)
if dialog.exec_() == 1:
self.SaveDialog(job, dialog)
diff --git a/src/Mod/Path/PathScripts/PathJobDlg.py b/src/Mod/Path/PathScripts/PathJobDlg.py
new file mode 100644
index 0000000000..8f3b2fa26b
--- /dev/null
+++ b/src/Mod/Path/PathScripts/PathJobDlg.py
@@ -0,0 +1,211 @@
+# -*- coding: utf-8 -*-
+
+# ***************************************************************************
+# * *
+# * Copyright (c) 2018 sliptonic *
+# * *
+# * This program is free software; you can redistribute it and/or modify *
+# * it under the terms of the GNU Lesser General Public License (LGPL) *
+# * as published by the Free Software Foundation; either version 2 of *
+# * the License, or (at your option) any later version. *
+# * for detail see the LICENCE text file. *
+# * *
+# * This program is distributed in the hope that it will be useful, *
+# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+# * GNU Library General Public License for more details. *
+# * *
+# * You should have received a copy of the GNU Library General Public *
+# * License along with this program; if not, write to the Free Software *
+# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+# * USA *
+# * *
+# ***************************************************************************
+
+import FreeCAD
+import FreeCADGui
+import PathScripts.PathJob as PathJob
+import PathScripts.PathLog as PathLog
+import PathScripts.PathPreferences as PathPreferences
+import PathScripts.PathStock as PathStock
+import PathScripts.PathUtil as PathUtil
+import glob
+import os
+
+from PySide import QtCore, QtGui
+
+# Qt tanslation handling
+def translate(context, text, disambig=None):
+ return QtCore.QCoreApplication.translate(context, text, disambig)
+
+if False:
+ PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
+ PathLog.trackModule(PathLog.thisModule())
+else:
+ PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
+
+class JobCreate:
+ DataObject = QtCore.Qt.ItemDataRole.UserRole
+
+ def __init__(self, parent=None, sel=None):
+ self.dialog = FreeCADGui.PySideUic.loadUi(":/panels/DlgJobCreate.ui")
+ self.items = []
+ self.dialog.templateGroup.hide()
+ self.dialog.modelGroup.hide()
+
+ def setupTitle(self, title):
+ self.dialog.setWindowTitle(title)
+
+ def setupModel(self, job = None):
+ if job:
+ sel = [PathUtil.getPublicObject(job.Proxy.baseObject(job, obj)) for obj in job.Model.Group]
+ xxx = job.Model.Group + [job.Stock]
+ else:
+ sel = FreeCADGui.Selection.getSelection()
+ xxx = []
+
+ if sel:
+ selected = [s.Label for s in sel]
+ else:
+ selected = []
+
+ index = 0
+ for base in sorted(PathJob.ObjectJob.baseCandidates(), key=lambda o: o.Label):
+ if not base in xxx and not PathJob.isResourceClone(job, base, None):
+ item = QtGui.QListWidgetItem(base.Label)
+ item.setData(self.DataObject, base)
+ item.setCheckState(QtCore.Qt.CheckState.Checked if base.Label in selected else QtCore.Qt.CheckState.Unchecked)
+ if PathUtil.isSolid(base):
+ self.dialog.solidList.addItem(item)
+ else:
+ self.dialog.twoDList.addItem(item)
+ self.items.append(item)
+ self.dialog.modelGroup.show()
+
+
+ def setupTemplate(self):
+ templateFiles = []
+ for path in PathPreferences.searchPaths():
+ templateFiles.extend(self.templateFilesIn(path))
+
+ template = {}
+ for tFile in templateFiles:
+ name = os.path.split(os.path.splitext(tFile)[0])[1][4:]
+ if name in template:
+ basename = name
+ i = 0
+ while name in template:
+ i = i + 1
+ name = basename + " (%s)" % i
+ PathLog.track(name, tFile)
+ template[name] = tFile
+ selectTemplate = PathPreferences.defaultJobTemplate()
+ index = 0
+ self.dialog.jobTemplate.addItem('', '')
+ for name in sorted(template.keys()):
+ if template[name] == selectTemplate:
+ index = self.dialog.jobTemplate.count()
+ self.dialog.jobTemplate.addItem(name, template[name])
+ self.dialog.jobTemplate.setCurrentIndex(index)
+ self.dialog.templateGroup.show()
+
+ def templateFilesIn(self, path):
+ '''templateFilesIn(path) ... answer all file in the given directory which fit the job template naming convention.
+ PathJob template files are name job_*.json'''
+ PathLog.track(path)
+ return glob.glob(path + '/job_*.json')
+
+ def getModels(self):
+ '''answer the base models selected for the job'''
+ return [item.data(self.DataObject) for item in self.items if item.checkState() == QtCore.Qt.CheckState.Checked]
+
+ def getTemplate(self):
+ '''answer the file name of the template to be assigned'''
+ return self.dialog.jobTemplate.itemData(self.dialog.jobTemplate.currentIndex())
+
+ def exec_(self):
+ return self.dialog.exec_()
+
+
+class JobTemplateExport:
+ DataObject = QtCore.Qt.ItemDataRole.UserRole
+
+ def __init__(self, job, parent=None):
+ self.job = job
+ self.dialog = FreeCADGui.PySideUic.loadUi(":/panels/DlgJobTemplateExport.ui")
+
+ if job.PostProcessor:
+ ppHint = "%s %s %s" % (job.PostProcessor, job.PostProcessorArgs, job.PostProcessorOutputFile)
+ self.dialog.postProcessingHint.setText(ppHint)
+ else:
+ self.dialog.postProcessingGroup.setEnabled(False)
+ self.dialog.postProcessingGroup.setChecked(False)
+
+ if job.Stock and not PathJob.isResourceClone(job, 'Stock', 'Stock'):
+ stockType = PathStock.StockType.FromStock(job.Stock)
+ if stockType == PathStock.StockType.FromBase:
+ seHint = translate('PathJob', "Base -/+ %.2f/%.2f %.2f/%.2f %.2f/%.2f") % (job.Stock.ExtXneg, job.Stock.ExtXpos, job.Stock.ExtYneg, job.Stock.ExtYpos, job.Stock.ExtZneg, job.Stock.ExtZpos)
+ self.dialog.stockPlacement.setChecked(False)
+ elif stockType == PathStock.StockType.CreateBox:
+ seHint = translate('PathJob', "Box: %.2f x %.2f x %.2f") % (job.Stock.Length, job.Stock.Width, job.Stock.Height)
+ elif stockType == PathStock.StockType.CreateCylinder:
+ seHint = translate('PathJob', "Cylinder: %.2f x %.2f") % (job.Stock.Radius, job.Stock.Height)
+ else:
+ seHint = '-'
+ PathLog.error(translate('PathJob', 'Unsupported stock type'))
+ self.dialog.stockExtentHint.setText(seHint)
+ spHint = "%s" % job.Stock.Placement
+ self.dialog.stockPlacementHint.setText(spHint)
+
+ rapidChanged = not job.SetupSheet.Proxy.hasDefaultToolRapids()
+ depthsChanged = not job.SetupSheet.Proxy.hasDefaultOperationDepths()
+ heightsChanged = not job.SetupSheet.Proxy.hasDefaultOperationHeights()
+ settingsChanged = rapidChanged or depthsChanged or heightsChanged
+ self.dialog.settingsGroup.setChecked(settingsChanged)
+ self.dialog.settingToolRapid.setChecked(rapidChanged)
+ self.dialog.settingOperationDepths.setChecked(depthsChanged)
+ self.dialog.settingOperationHeights.setChecked(heightsChanged)
+
+ for tc in sorted(job.ToolController, key=lambda o: o.Label):
+ item = QtGui.QListWidgetItem(tc.Label)
+ item.setData(self.DataObject, tc)
+ item.setCheckState(QtCore.Qt.CheckState.Checked)
+ self.dialog.toolsList.addItem(item)
+
+ self.dialog.toolsGroup.clicked.connect(self.checkUncheckTools)
+
+ def checkUncheckTools(self):
+ state = QtCore.Qt.CheckState.Checked if self.dialog.toolsGroup.isChecked() else QtCore.Qt.CheckState.Unchecked
+ for i in range(self.dialog.toolsList.count()):
+ self.dialog.toolsList.item(i).setCheckState(state)
+
+ def includePostProcessing(self):
+ return self.dialog.postProcessingGroup.isChecked()
+
+ def includeToolControllers(self):
+ tcs = []
+ for i in range(self.dialog.toolsList.count()):
+ item = self.dialog.toolsList.item(i)
+ if item.checkState() == QtCore.Qt.CheckState.Checked:
+ tcs.append(item.data(self.DataObject))
+ return tcs
+
+ def includeStock(self):
+ return self.dialog.stockGroup.isChecked()
+ def includeStockExtent(self):
+ return self.dialog.stockExtent.isChecked()
+ def includeStockPlacement(self):
+ return self.dialog.stockPlacement.isChecked()
+
+ def includeSettings(self):
+ return self.dialog.settingsGroup.isChecked()
+ def includeSettingToolRapid(self):
+ return self.dialog.settingToolRapid.isChecked()
+ def includeSettingOperationHeights(self):
+ return self.dialog.settingOperationHeights.isChecked()
+ def includeSettingOperationDepths(self):
+ return self.dialog.settingOperationDepths.isChecked()
+
+ def exec_(self):
+ return self.dialog.exec_()
+
diff --git a/src/Mod/Path/PathScripts/PathJobGui.py b/src/Mod/Path/PathScripts/PathJobGui.py
index b0ba1e49e0..2b3ab22573 100644
--- a/src/Mod/Path/PathScripts/PathJobGui.py
+++ b/src/Mod/Path/PathScripts/PathJobGui.py
@@ -27,7 +27,7 @@ import DraftVecUtils
import FreeCAD
import FreeCADGui
import PathScripts.PathJob as PathJob
-import PathScripts.PathJobCmd as PathJobCmd
+import PathScripts.PathJobDlg as PathJobDlg
import PathScripts.PathGeom as PathGeom
import PathScripts.PathGui as PathGui
import PathScripts.PathLog as PathLog
@@ -171,37 +171,13 @@ class ViewProvider:
def updateData(self, obj, prop):
PathLog.track(obj.Label, prop)
# make sure the resource view providers are setup properly
- if prop == 'Model':
+ if prop == 'Model' and self.obj.Model:
for base in self.obj.Model.Group:
if base.ViewObject and base.ViewObject.Proxy and not PathJob.isArchPanelSheet(base):
base.ViewObject.Proxy.onEdit(_OpenCloseResourceEditor)
if prop == 'Stock' and self.obj.Stock and self.obj.Stock.ViewObject and self.obj.Stock.ViewObject.Proxy:
self.obj.Stock.ViewObject.Proxy.onEdit(_OpenCloseResourceEditor)
- def baseObjectViewObject(self, obj):
- return [PathUtil.getPublicObject(base).ViewObject for base in self.obj.Proxy.baseObjects(obj)]
-
- def baseObjectSaveVisibility(self, obj):
- baseVO = self.baseObjectViewObject(self.obj)
- baseOrigVisibility = []
- for vo in baseVO:
- baseOrigVisibility = vo.Visibility
- vo.Visibility = False
- self.baseOrigVisibility = baseOrigVisibility
-
- for base in obj.Model.Group:
- if base.ViewObject:
- base.ViewObject.Visibility = True
-
- def baseObjectRestoreVisibility(self, obj):
- baseVO = self.baseObjectViewObject(self.obj)
- if self.baseOrigVisibility:
- for vo, visibility in zip(baseVO, self.baseOrigVisibility):
- vo.Visibility = visibility
- else:
- for vo in baseVO:
- vo.Visibility = False
-
def setupModelVisibility(self, obj):
baseVisibility = []
origVisibility = []
@@ -216,6 +192,12 @@ class ViewProvider:
self.baseVisibility = baseVisibility
self.baseOrigVisibility = origVisibility
+ def resetModelVisibility(self, obj):
+ for base, baseVisibility, origVisibility in zip(obj.Model.Group, self.baseVisibility, self.baseOrigVisibility):
+ if base.ViewObject:
+ orig = PathUtil.getPublicObject(obj.Proxy.baseObject(obj, base))
+ base.ViewObject.Visibility = baseVisibility
+ orig.ViewObject.Visibility = origVisibility
def setupEditVisibility(self, obj):
self.setupModelVisibility(obj)
@@ -225,11 +207,7 @@ class ViewProvider:
self.obj.Stock.ViewObject.Visibility = True
def resetEditVisibility(self, obj):
- for base, baseVisibility, origVisibility in zip(obj.Model.Group, self.baseVisibility, self.baseOrigVisibility):
- if base.ViewObject:
- orig = PathUtil.getPublicObject(obj.Proxy.baseObject(obj, base))
- base.ViewObject.Visibility = baseVisibility
- orig.ViewObject.Visibility = origVisibility
+ self.resetModelVisibility(obj)
if obj.Stock and obj.Stock.ViewObject:
obj.Stock.ViewObject.Visibility = self.stockVisibility
@@ -974,6 +952,15 @@ class TaskPanel:
self.form.centerInStock.setEnabled(False)
self.form.centerInStockXY.setEnabled(False)
+ def jobModelEdit(self):
+ dialog = PathJobDlg.JobCreate()
+ dialog.setupTitle(translate("Path_Job", "Model Selection"))
+ dialog.setupModel(self.obj)
+ if dialog.exec_() == 1:
+ models = dialog.getModels()
+ if models:
+ PathLog.error("shouldn't you be doing something here")
+
def tabPageChanged(self, index):
if index == 0:
# update the template with potential changes
@@ -984,14 +971,12 @@ class TaskPanel:
self.template.updateUI()
def setupUi(self, activate):
- self.setupGlobal.setupUi()
- self.setupOps.setupUi()
self.updateStockEditor(-1)
self.setFields()
# Info
self.form.jobLabel.editingFinished.connect(self.getFields)
- #self.form.jobModelEdit.clicked.connect(self.jobModelEdit)
+ self.form.jobModelEdit.clicked.connect(self.jobModelEdit)
# Post Processor
self.form.postProcessor.currentIndexChanged.connect(self.getFields)