Material: Fixed the material editor dialog, thanks to rockn
This commit is contained in:
parent
a029d90a98
commit
a5852dd8f2
|
@ -20,68 +20,47 @@
|
|||
#* *
|
||||
#***************************************************************************
|
||||
|
||||
import FreeCAD, os
|
||||
import FreeCAD, FreeCADGui, os
|
||||
from PySide import QtCore, QtGui, QtUiTools
|
||||
|
||||
__title__="FreeCAD material editor"
|
||||
__author__ = "Yorik van Havre"
|
||||
__url__ = "http://www.freecadweb.org"
|
||||
|
||||
# pyside dynamic ui loader from
|
||||
# from https://github.com/lunaryorn/snippets/blob/master/qt4/designer/pyside_dynamic.py
|
||||
class UiLoader(QtUiTools.QUiLoader):
|
||||
def __init__(self, baseinstance):
|
||||
QtUiTools.QUiLoader.__init__(self, baseinstance)
|
||||
self.baseinstance = baseinstance
|
||||
|
||||
def createWidget(self, class_name, parent=None, name=''):
|
||||
if parent is None and self.baseinstance:
|
||||
return self.baseinstance
|
||||
else:
|
||||
widget = QtUiTools.QUiLoader.createWidget(self, class_name, parent, name)
|
||||
if self.baseinstance:
|
||||
setattr(self.baseinstance, name, widget)
|
||||
return widget
|
||||
|
||||
class MaterialEditor(QtGui.QDialog):
|
||||
class MaterialEditor:
|
||||
|
||||
def __init__(self, obj = None, prop = None, material = None):
|
||||
"""Initializes, optionally with an object name and a material property name to edit, or directly
|
||||
with a material dictionary."""
|
||||
QtGui.QDialog.__init__(self)
|
||||
self.obj = obj
|
||||
self.prop = prop
|
||||
self.material = material
|
||||
self.customprops = []
|
||||
# load the UI file from the same directory as this script
|
||||
loader = UiLoader(self)
|
||||
widget = loader.load(os.path.dirname(__file__)+os.sep+"materials-editor.ui")
|
||||
#QtCore.QMetaObject.connectSlotsByName(widget)
|
||||
self.ui = self
|
||||
#print self.ui
|
||||
#print dir(self.ui)
|
||||
self.widget = FreeCADGui.PySideUic.loadUi(os.path.dirname(__file__)+os.sep+"materials-editor.ui")
|
||||
# additional UI fixes and tweaks
|
||||
self.ButtonURL.setIcon(QtGui.QIcon(":/icons/internet-web-browser.svg"))
|
||||
self.ButtonDeleteProperty.setEnabled(False)
|
||||
self.standardButtons.button(QtGui.QDialogButtonBox.Ok).setAutoDefault(False)
|
||||
self.standardButtons.button(QtGui.QDialogButtonBox.Cancel).setAutoDefault(False)
|
||||
self.widget.ButtonURL.setIcon(QtGui.QIcon(":/icons/internet-web-browser.svg"))
|
||||
self.widget.ButtonDeleteProperty.setEnabled(False)
|
||||
self.widget.standardButtons.button(QtGui.QDialogButtonBox.Ok).setAutoDefault(False)
|
||||
self.widget.standardButtons.button(QtGui.QDialogButtonBox.Cancel).setAutoDefault(False)
|
||||
self.updateCards()
|
||||
self.Editor.header().resizeSection(0,200)
|
||||
self.Editor.expandAll()
|
||||
self.Editor.setFocus()
|
||||
self.widget.Editor.header().resizeSection(0,200)
|
||||
self.widget.Editor.expandAll()
|
||||
self.widget.Editor.setFocus()
|
||||
# TODO allow to enter a custom property by pressing Enter in the lineedit (currently closes the dialog)
|
||||
self.Editor.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
|
||||
QtCore.QObject.connect(self.ComboMaterial, QtCore.SIGNAL("currentIndexChanged(QString)"), self.updateContents)
|
||||
QtCore.QObject.connect(self.ButtonURL, QtCore.SIGNAL("clicked()"), self.openProductURL)
|
||||
QtCore.QObject.connect(self.standardButtons, QtCore.SIGNAL("accepted()"), self.accept)
|
||||
QtCore.QObject.connect(self.standardButtons, QtCore.SIGNAL("rejected()"), self.reject)
|
||||
QtCore.QObject.connect(self.ButtonAddProperty, QtCore.SIGNAL("clicked()"), self.addCustomProperty)
|
||||
QtCore.QObject.connect(self.EditProperty, QtCore.SIGNAL("returnPressed()"), self.addCustomProperty)
|
||||
QtCore.QObject.connect(self.ButtonDeleteProperty, QtCore.SIGNAL("clicked()"), self.deleteCustomProperty)
|
||||
QtCore.QObject.connect(self.Editor, QtCore.SIGNAL("itemDoubleClicked(QTreeWidgetItem*,int)"), self.itemClicked)
|
||||
QtCore.QObject.connect(self.Editor, QtCore.SIGNAL("currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)"), self.checkDeletable)
|
||||
QtCore.QObject.connect(self.ButtonOpen, QtCore.SIGNAL("clicked()"), self.openfile)
|
||||
QtCore.QObject.connect(self.ButtonSave, QtCore.SIGNAL("clicked()"), self.savefile)
|
||||
self.widget.Editor.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
|
||||
QtCore.QObject.connect(self.widget.ComboMaterial, QtCore.SIGNAL("currentIndexChanged(QString)"), self.updateContents)
|
||||
QtCore.QObject.connect(self.widget.ButtonURL, QtCore.SIGNAL("clicked()"), self.openProductURL)
|
||||
QtCore.QObject.connect(self.widget.standardButtons, QtCore.SIGNAL("accepted()"), self.accept)
|
||||
QtCore.QObject.connect(self.widget.standardButtons, QtCore.SIGNAL("rejected()"), self.reject)
|
||||
QtCore.QObject.connect(self.widget.ButtonAddProperty, QtCore.SIGNAL("clicked()"), self.addCustomProperty)
|
||||
QtCore.QObject.connect(self.widget.EditProperty, QtCore.SIGNAL("returnPressed()"), self.addCustomProperty)
|
||||
QtCore.QObject.connect(self.widget.ButtonDeleteProperty, QtCore.SIGNAL("clicked()"), self.deleteCustomProperty)
|
||||
QtCore.QObject.connect(self.widget.Editor, QtCore.SIGNAL("itemDoubleClicked(QTreeWidgetItem*,int)"), self.itemClicked)
|
||||
QtCore.QObject.connect(self.widget.Editor, QtCore.SIGNAL("currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)"), self.checkDeletable)
|
||||
QtCore.QObject.connect(self.widget.ButtonOpen, QtCore.SIGNAL("clicked()"), self.openfile)
|
||||
QtCore.QObject.connect(self.widget.ButtonSave, QtCore.SIGNAL("clicked()"), self.savefile)
|
||||
# update the editor with the contents of the property, if we have one
|
||||
d = None
|
||||
if self.prop and self.obj:
|
||||
|
@ -106,10 +85,10 @@ class MaterialEditor(QtGui.QDialog):
|
|||
if e.upper() == ".FCMAT":
|
||||
self.cards[b] = p + os.sep + f
|
||||
if self.cards:
|
||||
self.ComboMaterial.clear()
|
||||
self.ComboMaterial.addItem("") # add a blank item first
|
||||
self.widget.ComboMaterial.clear()
|
||||
self.widget.ComboMaterial.addItem("") # add a blank item first
|
||||
for k,i in self.cards.items():
|
||||
self.ComboMaterial.addItem(k)
|
||||
self.widget.ComboMaterial.addItem(k)
|
||||
|
||||
def updateContents(self,data):
|
||||
"updates the contents of the editor with the given data (can be the name of a card or a dictionary)"
|
||||
|
@ -118,7 +97,7 @@ class MaterialEditor(QtGui.QDialog):
|
|||
self.clearEditor()
|
||||
for k,i in data.items():
|
||||
k = self.expandKey(k)
|
||||
slot = self.Editor.findItems(k,QtCore.Qt.MatchRecursive,0)
|
||||
slot = self.widget.Editor.findItems(k,QtCore.Qt.MatchRecursive,0)
|
||||
if len(slot) == 1:
|
||||
slot = slot[0]
|
||||
slot.setText(1,i)
|
||||
|
@ -135,7 +114,7 @@ class MaterialEditor(QtGui.QDialog):
|
|||
|
||||
def openProductURL(self):
|
||||
"opens the contents of the ProductURL field in an external browser"
|
||||
url = str(self.Editor.findItems(translate("Material","Product URL"),QtCore.Qt.MatchRecursive,0)[0].text(1))
|
||||
url = str(self.widget.Editor.findItems(translate("Material","Product URL"),QtCore.Qt.MatchRecursive,0)[0].text(1))
|
||||
if url:
|
||||
QtGui.QDesktopServices.openUrl(QtCore.QUrl(url, QtCore.QUrl.TolerantMode))
|
||||
|
||||
|
@ -145,7 +124,10 @@ class MaterialEditor(QtGui.QDialog):
|
|||
d = self.getDict()
|
||||
o = FreeCAD.ActiveDocument.getObject(self.obj)
|
||||
setattr(o,self.prop,d)
|
||||
QtGui.QDialog.accept(self)
|
||||
QtGui.QDialog.accept(self.widget)
|
||||
|
||||
def reject(self):
|
||||
QtGui.QDialog.reject(self.widget)
|
||||
|
||||
def expandKey(self, key):
|
||||
"adds spaces before caps in a KeyName"
|
||||
|
@ -169,8 +151,8 @@ class MaterialEditor(QtGui.QDialog):
|
|||
|
||||
def clearEditor(self):
|
||||
"Clears the contents of the editor"
|
||||
for i1 in range(self.Editor.topLevelItemCount()):
|
||||
w = self.Editor.topLevelItem(i1)
|
||||
for i1 in range(self.widget.Editor.topLevelItemCount()):
|
||||
w = self.widget.Editor.topLevelItem(i1)
|
||||
for i2 in range(w.childCount()):
|
||||
c = w.child(i2)
|
||||
c.setText(1,"")
|
||||
|
@ -180,29 +162,29 @@ class MaterialEditor(QtGui.QDialog):
|
|||
def addCustomProperty(self, key = None, value = None):
|
||||
"Adds a custom property to the editor, optionally with a value"
|
||||
if not key:
|
||||
key = str(self.EditProperty.text())
|
||||
key = str(self.widget.EditProperty.text())
|
||||
if key:
|
||||
if not key in self.customprops:
|
||||
if not self.Editor.findItems(key,QtCore.Qt.MatchRecursive,0):
|
||||
top = self.Editor.findItems(translate("Material","User defined"),QtCore.Qt.MatchExactly,0)
|
||||
if not self.widget.Editor.findItems(key,QtCore.Qt.MatchRecursive,0):
|
||||
top = self.widget.Editor.findItems(translate("Material","User defined"),QtCore.Qt.MatchExactly,0)
|
||||
if top:
|
||||
i = QtGui.QTreeWidgetItem(top[0])
|
||||
i.setFlags(QtCore.Qt.ItemIsSelectable|QtCore.Qt.ItemIsEditable|QtCore.Qt.ItemIsDragEnabled|QtCore.Qt.ItemIsUserCheckable|QtCore.Qt.ItemIsEnabled)
|
||||
i.setText(0,key)
|
||||
self.customprops.append(key)
|
||||
self.EditProperty.setText("")
|
||||
self.widget.EditProperty.setText("")
|
||||
if value:
|
||||
i.setText(1,value)
|
||||
|
||||
def deleteCustomProperty(self, key = None):
|
||||
"Deletes a custom property from the editor"
|
||||
if not key:
|
||||
key = str(self.Editor.currentItem().text(0))
|
||||
key = str(self.widget.Editor.currentItem().text(0))
|
||||
if key:
|
||||
if key in self.customprops:
|
||||
i = self.Editor.findItems(key,QtCore.Qt.MatchRecursive,0)
|
||||
i = self.widget.Editor.findItems(key,QtCore.Qt.MatchRecursive,0)
|
||||
if i:
|
||||
top = self.Editor.findItems(translate("Material","User defined"),QtCore.Qt.MatchExactly,0)
|
||||
top = self.widget.Editor.findItems(translate("Material","User defined"),QtCore.Qt.MatchExactly,0)
|
||||
if top:
|
||||
top = top[0]
|
||||
ii = top.indexOfChild(i[0])
|
||||
|
@ -213,20 +195,20 @@ class MaterialEditor(QtGui.QDialog):
|
|||
def itemClicked(self, item, column):
|
||||
"Edits an item if it is not in the first column"
|
||||
if column > 0:
|
||||
self.Editor.editItem(item, column)
|
||||
self.widget.Editor.editItem(item, column)
|
||||
|
||||
def checkDeletable(self,current,previous):
|
||||
"Checks if the current item is a custom property, if yes enable the delete button"
|
||||
if str(current.text(0)) in self.customprops:
|
||||
self.ButtonDeleteProperty.setEnabled(True)
|
||||
self.widget.ButtonDeleteProperty.setEnabled(True)
|
||||
else:
|
||||
self.ButtonDeleteProperty.setEnabled(False)
|
||||
self.widget.ButtonDeleteProperty.setEnabled(False)
|
||||
|
||||
def getDict(self):
|
||||
"returns a dictionnary from the contents of the editor"
|
||||
d = {}
|
||||
for i1 in range(self.Editor.topLevelItemCount()):
|
||||
w = self.Editor.topLevelItem(i1)
|
||||
for i1 in range(self.widget.Editor.topLevelItemCount()):
|
||||
w = self.widget.Editor.topLevelItem(i1)
|
||||
for i2 in range(w.childCount()):
|
||||
c = w.child(i2)
|
||||
# TODO the following should be translated back to english,since text(0) could be translated
|
||||
|
@ -245,7 +227,7 @@ class MaterialEditor(QtGui.QDialog):
|
|||
|
||||
def savefile(self):
|
||||
"Saves a FCMat file"
|
||||
name = str(self.Editor.findItems(translate("Material","Name"),QtCore.Qt.MatchRecursive,0)[0].text(1))
|
||||
name = str(self.widget.Editor.findItems(translate("Material","Name"),QtCore.Qt.MatchRecursive,0)[0].text(1))
|
||||
if not name:
|
||||
name = "Material"
|
||||
filename = QtGui.QFileDialog.getSaveFileName(QtGui.qApp.activeWindow(),'Save FreeCAD Material file',name+'.FCMat')
|
||||
|
@ -255,6 +237,11 @@ class MaterialEditor(QtGui.QDialog):
|
|||
import importFCMat
|
||||
importFCMat.write(filename,d)
|
||||
|
||||
def show(self):
|
||||
self.widget.show()
|
||||
|
||||
def exec_(self):
|
||||
self.widget.exec_()
|
||||
|
||||
def translate(context,text):
|
||||
"translates text"
|
||||
|
|
|
@ -79,6 +79,9 @@ def decode(name):
|
|||
|
||||
def read(filename):
|
||||
"reads a FCMat file and returns a dictionary from it"
|
||||
if isinstance(filename,unicode):
|
||||
import sys
|
||||
filename = filename.encode(sys.getfilesystemencoding())
|
||||
f = pythonopen(filename)
|
||||
d = {}
|
||||
l = 0
|
||||
|
@ -118,16 +121,21 @@ def write(filename,dictionary):
|
|||
user[k] = i
|
||||
# write header
|
||||
rev = FreeCAD.ConfigGet("BuildVersionMajor")+"."+FreeCAD.ConfigGet("BuildVersionMinor")+" "+FreeCAD.ConfigGet("BuildRevision")
|
||||
filename = filename[0]
|
||||
if isinstance(filename,unicode):
|
||||
import sys
|
||||
filename = filename.encode(sys.getfilesystemencoding())
|
||||
print filename
|
||||
f = pythonopen(filename,"wb")
|
||||
f.write("; " + header["CardName"] + "\n")
|
||||
f.write("; " + header["AuthorAndLicense"] + "\n")
|
||||
f.write("; " + header["CardName"].encode("utf8") + "\n")
|
||||
f.write("; " + header["AuthorAndLicense"].encode("utf8") + "\n")
|
||||
f.write("; file produced by FreeCAD " + rev + "\n")
|
||||
f.write("; information about the content of this card can be found here:\n")
|
||||
f.write("; http://www.freecadweb.org/wiki/index.php?title=Material\n")
|
||||
f.write("\n")
|
||||
if header["Source"]:
|
||||
f.write("; source of the data provided in this card:\n")
|
||||
f.write("; " + header["Source"] + "\n")
|
||||
f.write("; " + header["Source"].encode("utf8") + "\n")
|
||||
f.write("\n")
|
||||
# write sections
|
||||
for s in contents:
|
||||
|
|
Loading…
Reference in New Issue
Block a user