Material: editor, allow duplicate card names and other improvements

This commit is contained in:
Bernd Hahnebach
2019-04-25 19:47:14 +02:00
parent 080c48b4a3
commit 84bb893e4b
2 changed files with 87 additions and 65 deletions

View File

@@ -39,7 +39,7 @@ if sys.version_info.major >= 3:
class MaterialEditor:
def __init__(self, obj=None, prop=None, material=None):
def __init__(self, obj=None, prop=None, material=None, card_path=''):
"""Initializes, optionally with an object name and a material property
name to edit, or directly with a material dictionary."""
@@ -54,6 +54,7 @@ class MaterialEditor:
self.materials = {}
self.cards = {}
self.icons = {}
self.card_path = card_path
# load the UI file from the same directory as this script
self.widget = FreeCADGui.PySideUic.loadUi(
@@ -88,7 +89,7 @@ class MaterialEditor:
buttonOpen.clicked.connect(self.openfile)
buttonSave.clicked.connect(self.savefile)
buttonURL.clicked.connect(self.openProductURL)
comboMaterial.currentIndexChanged[str].connect(self.updateMatParamsInTree)
comboMaterial.currentIndexChanged[int].connect(self.chooseMaterial)
buttonAddProperty.clicked.connect(self.addCustomProperty)
buttonDeleteProperty.clicked.connect(self.deleteCustomProperty)
treeView.clicked.connect(self.checkDeletable)
@@ -98,6 +99,9 @@ class MaterialEditor:
treeView.setUniformRowHeights(True)
treeView.setItemDelegate(MaterialsDelegate())
# init model
self.implementModel()
# update the editor with the contents of the property, if we have one
d = None
if self.prop and self.obj:
@@ -105,9 +109,18 @@ class MaterialEditor:
elif self.material:
d = self.material
self.implementModel()
if d:
self.updateMatParamsInTree(d)
self.widget.ComboMaterial.setCurrentIndex(0)
# set after tree params to the none material
if self.card_path:
# we need the index of this path
index = self.widget.ComboMaterial.findData(self.card_path)
self.chooseMaterial(index)
# TODO what if material and card_name was given.
# In such case ATM mateial is chosen, give some feedback for all those corner cases.
def implementModel(self):
@@ -149,55 +162,55 @@ class MaterialEditor:
def updateMatParamsInTree(self, data):
'''updates the contents of the editor with the given data, can be:
- a dictionary, if the editor was called with data
- a string, the name of a card, if material is changed in editors combo box
'''updates the contents of the editor with the given dictionary
the material property keys where added to the editor already
not known material property keys will be added to the user defined group'''
# print type(data)
if isinstance(data, dict):
# a standard material property dict is provided
model = self.widget.treeView.model()
root = model.invisibleRootItem()
for gg in range(root.rowCount() - 1):
group = root.child(gg, 0)
for pp in range(group.rowCount()):
item = group.child(pp, 0)
it = group.child(pp, 1)
kk = self.collapseKey(item.text())
# print(data)
model = self.widget.treeView.model()
root = model.invisibleRootItem()
for gg in range(root.rowCount() - 1):
group = root.child(gg, 0)
for pp in range(group.rowCount()):
item = group.child(pp, 0)
it = group.child(pp, 1)
kk = self.collapseKey(item.text())
try:
value = data[kk]
it.setText(value)
del data[kk]
except KeyError:
it.setText("")
try:
value = data[kk]
it.setText(value)
del data[kk]
except KeyError:
it.setText("")
userGroup = root.child(gg + 1, 0)
userGroup.setRowCount(0)
self.customprops = []
userGroup = root.child(gg + 1, 0)
userGroup.setRowCount(0)
self.customprops = []
for k, i in data.items():
k = self.expandKey(k)
item = QtGui.QStandardItem(k)
it = QtGui.QStandardItem(i)
userGroup.appendRow([item, it])
self.customprops.append(k)
for k, i in data.items():
k = self.expandKey(k)
item = QtGui.QStandardItem(k)
it = QtGui.QStandardItem(i)
userGroup.appendRow([item, it])
self.customprops.append(k)
elif isinstance(data, unicode):
# a card name is provided, search card, read material data and call
# this def once more with std material property dict
k = str(data)
if k:
if k in self.cards:
# be careful with reading from materials dict
# the card could be updated the dict not
from importFCMat import read
d = read(self.cards[k])
if d:
self.updateMatParamsInTree(d)
def chooseMaterial(self, index):
if index < 0:
return
self.card_path = self.widget.ComboMaterial.itemData(index)
FreeCAD.Console.PrintMessage(
'choose_material in material editor:\n'
' {}\n'.format(self.card_path)
)
if os.path.isfile(self.card_path):
from importFCMat import read
d = read(self.card_path)
self.updateMatParamsInTree(d)
# be careful with reading from materials dict
# the card could be updated the dict not
self.widget.ComboMaterial.setCurrentIndex(index) # set after tree params
else:
FreeCAD.Console.PrintError('material card not found: {}\n'.format(self.card_path))
def updateCardsInCombo(self):
@@ -223,8 +236,9 @@ class MaterialEditor:
a_path = card_names_tmp[a_name]
card_name_list.append([a_name, a_path, self.icons[a_path]])
card_name_list.insert(0, [None, '', ''])
for mat in card_name_list:
self.widget.ComboMaterial.addItem(QtGui.QIcon(mat[2]), mat[0])
self.widget.ComboMaterial.addItem(QtGui.QIcon(mat[2]), mat[0], mat[1])
def openProductURL(self):
@@ -408,14 +422,28 @@ class MaterialEditor:
self.directory,
'*.FCMat'
)
# a tuple of two empty strings returns True, so use the filename directly
filename = filetuple[0]
if filename:
from importFCMat import read
self.directory = os.path.dirname(filename)
d = read(filename)
if d:
self.updateMatParamsInTree(d)
self.card_path = filetuple[0]
index = self.widget.ComboMaterial.findData(self.card_path)
print(index)
# check if card_path is in known path, means it is in combo box already
# if not print message, and give some feedbach that the card parameter are loaded
if os.path.isfile(self.card_path):
if index == -1:
FreeCAD.Console.PrintMessage(
'Card path: {} not found in known cards.'
'The material parameter only are loaded.\n'
.format(self.card_path)
)
from importFCMat import read
d = read(self.card_path)
if d:
self.updateMatParamsInTree(d)
self.widget.ComboMaterial.setCurrentIndex(0)
# set combo box to the none material after tree params
else:
self.chooseMaterial(index)
self.directory = os.path.dirname(self.card_path)
def savefile(self):
"Saves a FCMat file."
@@ -441,6 +469,7 @@ class MaterialEditor:
filename = filetuple[0]
if filename:
self.directory = os.path.dirname(filename)
# should not be resource dir but user result dir instead
d = self.getDict()
# self.outputDict(d)
if d:
@@ -638,7 +667,7 @@ def openEditor(obj=None, prop=None):
editor.exec_()
def editMaterial(material):
def editMaterial(material=None, card_path=None):
"""editMaterial(material): opens the editor to edit the contents
of the given material dictionary. Returns the modified material dictionary."""
# if the material editor is opened with this def the combo box with the card name is empty
@@ -647,12 +676,13 @@ def editMaterial(material):
# TODO: add some text in combo box, may be "custom material data" or "user material data"
# TODO: all card could be checked if one fits exact ALL provided data
# than this card name could be displayed
editor = MaterialEditor(material=material)
editor = MaterialEditor(material=material, card_path=card_path)
result = editor.exec_()
if result:
return editor.getDict()
else:
return material
# on chancel button an empty dict is returned
return {}
'''

View File

@@ -119,14 +119,6 @@ def add_cards_from_a_dir(materials, cards, icons, mat_dir, icon):
card_name = os.path.splitext(os.path.basename(a_path))[0]
if delete_duplicates is False:
materials[a_path] = mat_dict
i = 1
while card_name in cards.values():
if i == 1:
card_name += ('_' + str(i))
else:
card_name = card_name[:-1] + str(i)
i += 1
# print(card_name)
cards[a_path] = card_name
icons[a_path] = icon
else: