diff --git a/src/Mod/Path/Gui/Resources/panels/DlgJobCreate.ui b/src/Mod/Path/Gui/Resources/panels/DlgJobCreate.ui
index ca922809ff..c8802bb6ac 100644
--- a/src/Mod/Path/Gui/Resources/panels/DlgJobCreate.ui
+++ b/src/Mod/Path/Gui/Resources/panels/DlgJobCreate.ui
@@ -6,7 +6,7 @@
0
0
- 388
+ 532
616
@@ -43,30 +43,13 @@
-
-
+
QAbstractItemView::NoEditTriggers
true
-
- QAbstractItemView::MultiSelection
-
-
- 1
-
-
- false
-
-
- true
-
-
-
- 1
-
-
diff --git a/src/Mod/Path/PathScripts/PathJobDlg.py b/src/Mod/Path/PathScripts/PathJobDlg.py
index 6f7016d607..c0f619a5f3 100644
--- a/src/Mod/Path/PathScripts/PathJobDlg.py
+++ b/src/Mod/Path/PathScripts/PathJobDlg.py
@@ -33,6 +33,7 @@ import glob
import os
from PySide import QtCore, QtGui
+from collections import Counter
# Qt tanslation handling
def translate(context, text, disambig=None):
@@ -49,9 +50,9 @@ class JobCreate:
def __init__(self, parent=None, sel=None):
self.dialog = FreeCADGui.PySideUic.loadUi(":/panels/DlgJobCreate.ui")
- self.itemsSolid = QtGui.QTreeWidgetItem([translate('PathJob', 'Solids')])
- self.itemsTwoD = QtGui.QTreeWidgetItem([translate('PathJob', '2D')])
- self.itemsJob = QtGui.QTreeWidgetItem([translate('PathJob', 'Jobs')])
+ self.itemsSolid = QtGui.QStandardItem(translate('PathJob', 'Solids'))
+ self.items2D = QtGui.QStandardItem(translate('PathJob', '2D'))
+ self.itemsJob = QtGui.QStandardItem(translate('PathJob', 'Jobs'))
self.dialog.templateGroup.hide()
self.dialog.modelGroup.hide()
@@ -59,72 +60,117 @@ class JobCreate:
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]
+ preSelected = Counter([PathUtil.getPublicObject(job.Proxy.baseObject(job, obj)).Label for obj in job.Model.Group])
+ jobResources = job.Model.Group + [job.Stock]
else:
- sel = FreeCADGui.Selection.getSelection()
- xxx = []
+ preSelected = Counter([obj.Label for obj in FreeCADGui.Selection.getSelection()])
+ jobResources = []
- if sel:
- selected = [s.Label for s in sel]
- else:
- selected = []
-
- PathLog.track('selected', selected)
+ self.candidates = sorted(PathJob.ObjectJob.baseCandidates(), key=lambda o: o.Label)
expandSolids = False
- expandTwoDs = False
+ expand2Ds = False
expandJobs = False
- index = 0
- candidates = sorted(PathJob.ObjectJob.baseCandidates(), key=lambda o: o.Label)
- for base in candidates:
- PathLog.track(base.Label)
- if not base in xxx and not PathJob.isResourceClone(job, base, None) and not hasattr(base, 'StockType'):
- PathLog.track('base', base.Label)
- item = QtGui.QTreeWidgetItem([base.Label])
- item.setData(0, self.DataObject, base)
- sel = base.Label in selected
- if sel or (1 == len(candidates) and not selected):
- item.setCheckState(0, QtCore.Qt.CheckState.Checked)
+
+ for i, base in enumerate(self.candidates):
+ if not base in jobResources and not PathJob.isResourceClone(job, base, None) and not hasattr(base, 'StockType'):
+ item0 = QtGui.QStandardItem()
+ item1 = QtGui.QStandardItem()
+
+ item0.setData(base.Label, QtCore.Qt.EditRole)
+ item0.setData(base, self.DataObject)
+ item0.setCheckable(True)
+ item0.setEditable(False)
+
+ if base.Label in preSelected:
+ itemSelected = True
+ item0.setCheckState(QtCore.Qt.CheckState.Checked)
+ item1.setEnabled(True)
+ item1.setData(preSelected[base.Label], QtCore.Qt.EditRole)
else:
- item.setCheckState(0, QtCore.Qt.CheckState.Unchecked)
+ itemSelected = False
+ item0.setCheckState(QtCore.Qt.CheckState.Unchecked)
+ item1.setEnabled(False)
+ item1.setData(0, QtCore.Qt.EditRole)
+
if PathUtil.isSolid(base):
- self.itemsSolid.addChild(item)
- if sel:
+ self.itemsSolid.appendRow([item0, item1])
+ if itemSelected:
expandSolids = True
else:
- self.itemsTwoD.addChild(item)
- if sel:
- expandTwoDs = True
+ self.items2D.appendRow([item0, item1])
+ if itemSelected:
+ expand2Ds = True
for j in sorted(PathJob.Instances(), key=lambda x: x.Label):
if j != job:
- item = QtGui.QTreeWidgetItem([j.Label])
- item.setData(0, self.DataObject, j)
- if j.Label in selected:
- expandJobs = True
- item.setCheckState(0, QtCore.Qt.CheckState.Checked)
- else:
- item.setCheckState(0, QtCore.Qt.CheckState.Unchecked)
- self.itemsJob.addChild(item)
+ item0 = QtGui.QStandardItem()
+ item1 = QtGui.QStandardItem()
- if self.itemsSolid.childCount() > 0:
- self.dialog.modelTree.addTopLevelItem(self.itemsSolid)
- if expandSolids or not (expandTwoDs or expandJobs):
- PathLog.track()
- self.itemsSolid.setExpanded(True)
+ item0.setData(j.Label, QtCore.Qt.EditRole)
+ item0.setData(j, self.DataObject)
+
+ item0.setCheckable(True)
+ item0.setEditable(False)
+
+ if j.Label in preSelected:
+ expandJobs = True
+ item0.setCheckState(QtCore.Qt.CheckState.Checked)
+ item1.setEnabled(True)
+ item1.setData(preSelected[j.Label], QtCore.Qt.EditRole)
+ else:
+ item0.setCheckState(QtCore.Qt.CheckState.Unchecked)
+ item1.setEnabled(False)
+ item1.setData(0, QtCore.Qt.EditRole)
+
+ self.itemsJob.appendRow([item0, item1])
+
+ self.model = QtGui.QStandardItemModel(self.dialog)
+ self.model.setHorizontalHeaderLabels(['Model', 'Count'])
+
+
+ if self.itemsSolid.hasChildren():
+ self.model.appendRow(self.itemsSolid)
+ if expandSolids or not (expand2Ds or expandJobs):
expandSolids = True
- if self.itemsTwoD.childCount() > 0:
- self.dialog.modelTree.addTopLevelItem(self.itemsTwoD)
- if expandTwoDs:
- self.itemsTwoD.setExpanded(True)
- if self.itemsJob.childCount() > 0:
- self.dialog.modelTree.addTopLevelItem(self.itemsJob)
- if expandJobs:
- self.itemsJob.setExpanded(True)
+ if self.items2D.hasChildren():
+ self.model.appendRow(self.items2D)
+ if self.itemsJob.hasChildren():
+ self.model.appendRow(self.itemsJob)
+
+ self.dialog.modelTree.setModel(self.model)
+ self.dialog.modelTree.expandAll()
+ self.dialog.modelTree.resizeColumnToContents(0)
+ self.dialog.modelTree.resizeColumnToContents(1)
+ self.dialog.modelTree.collapseAll()
+
+ if expandSolids:
+ self.dialog.modelTree.setExpanded(self.itemsSolid.index(), True)
+ if expand2Ds:
+ self.dialog.modelTree.setExpanded(self.items2D.index(), True)
+ if expandJobs:
+ self.dialog.modelTree.setExpanded(self.itemsJob.index(), True)
+
+ self.dialog.modelTree.setEditTriggers(QtGui.QAbstractItemView.AllEditTriggers)
+ self.dialog.modelTree.setSelectionBehavior(QtGui.QAbstractItemView.SelectItems)
+
+ self.model.dataChanged.connect(self.updateData)
self.dialog.modelGroup.show()
+ def updateData(self, topLeft, bottomRight):
+ if topLeft.column() == bottomRight.column() == 0:
+ item0 = self.model.itemFromIndex(topLeft)
+ item1 = self.model.itemFromIndex(topLeft.sibling(topLeft.row(), 1))
+ if item0.checkState() == QtCore.Qt.Checked:
+ item1.setEnabled(True)
+ item1.setEditable(True)
+ item1.setData(1, QtCore.Qt.EditRole)
+ else:
+ item1.setEnabled(False)
+ item1.setEditable(False)
+ item1.setData(0, QtCore.Qt.EditRole)
def setupTemplate(self):
templateFiles = []
@@ -159,23 +205,22 @@ class JobCreate:
return glob.glob(path + '/job_*.json')
def getModels(self):
- '''answer the base models selected for the job'''
models = []
- for i in range(self.itemsSolid.childCount()):
- if self.itemsSolid.child(i).checkState(0) == QtCore.Qt.CheckState.Checked:
- models.append(self.itemsSolid.child(i).data(0, self.DataObject))
+ for i in range(self.itemsSolid.rowCount()):
+ for j in range(self.itemsSolid.child(i, 1).data(QtCore.Qt.EditRole)):
+ models.append(self.itemsSolid.child(i).data(self.DataObject))
- for i in range(self.itemsTwoD.childCount()):
- if self.itemsTwoD.child(i).checkState(0) == QtCore.Qt.CheckState.Checked:
- models.append(self.itemsTwoD.child(i).data(0, self.DataObject))
+ for i in range(self.items2D.rowCount()):
+ for j in range(self.items2D.child(i, 1).data(QtCore.Qt.EditRole)):
+ models.append(self.items2D.child(i).data(self.DataObject))
- for i in range(self.itemsJob.childCount()):
- if self.itemsJob.child(i).checkState(0) == QtCore.Qt.CheckState.Checked:
+ for i in range(self.itemsJob.rowCount()):
+ for j in range(self.itemsJob.child(i, 1).data(QtCore.Qt.EditRole)):
# Note that we do want to use the models (resource clones) of the
# source job as base objects for the new job in order to get the
# identical placement, and anything else that's been customized.
- models.extend(self.itemsJob.child(i).data(0, self.DataObject).Model.Group)
+ models.extend(self.itemsJob.child(i, 0).data(self.DataObject).Model.Group)
return models
diff --git a/src/Mod/Path/PathScripts/PathJobGui.py b/src/Mod/Path/PathScripts/PathJobGui.py
index 588d697a72..5619b764b8 100644
--- a/src/Mod/Path/PathScripts/PathJobGui.py
+++ b/src/Mod/Path/PathScripts/PathJobGui.py
@@ -45,6 +45,7 @@ import sys
import traceback
from PySide import QtCore, QtGui
+from collections import Counter
from contextlib import contextmanager
from pivy import coin
@@ -1072,23 +1073,30 @@ class TaskPanel:
obj = self.obj
proxy = obj.Proxy
- # first remove all retired base models
- retired = [base for base in self.obj.Model.Group if not proxy.baseObject(obj, base) in models]
- for base in retired:
- self.vproxy.forgetBaseVisibility(obj, base)
- self.obj.Proxy.removeBase(obj, base, True)
+ want = Counter(models)
+ have = Counter([proxy.baseObject(obj, o) for o in obj.Model.Group])
+
+ obsolete = have - want
+ additions = want - have
+
+ # first remove all obsolete base models
+ for model, count in PathUtil.keyValueIter(obsolete):
+ for i in range(count):
+ # it seems natural to remove the last of all the base objects for a given model
+ base = [b for b in obj.Model.Group if proxy.baseObject(obj, b) == model][-1]
+ self.vproxy.forgetBaseVisibility(obj, base)
+ self.obj.Proxy.removeBase(obj, base, True)
# do not access any of the retired objects after this point, they don't exist anymore
# then add all rookie base models
- baseOrigNames = [proxy.baseObject(obj, base).Name for base in obj.Model.Group]
- rookies = [base for base in models if not base.Name in baseOrigNames]
- for orig in rookies:
- base = PathJob.createModelResourceClone(obj, orig)
- obj.Model.addObject(base)
- self.vproxy.rememberBaseVisibility(obj, base)
+ for model, count in PathUtil.keyValueIter(additions):
+ for i in range(count):
+ base = PathJob.createModelResourceClone(obj, model)
+ obj.Model.addObject(base)
+ self.vproxy.rememberBaseVisibility(obj, base)
# refresh the view
- if retired or rookies:
+ if obsolete or additions:
self.setFields()
else:
PathLog.track('no changes to model')