diff --git a/src/Mod/Material/MaterialEditor.py b/src/Mod/Material/MaterialEditor.py index 77f2cf1914a7..e3dba6dce00e 100644 --- a/src/Mod/Material/MaterialEditor.py +++ b/src/Mod/Material/MaterialEditor.py @@ -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 @@ def updateCards(self): 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 @@ def updateContents(self,data): 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 @@ def updateContents(self,data): 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 @@ def accept(self): 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 @@ def collapseKey(self, key): 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 @@ def clearEditor(self): 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 @@ def deleteCustomProperty(self, key = None): 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 @@ def openfile(self): 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 @@ def savefile(self): import importFCMat importFCMat.write(filename,d) + def show(self): + self.widget.show() + + def exec_(self): + self.widget.exec_() def translate(context,text): "translates text" diff --git a/src/Mod/Material/importFCMat.py b/src/Mod/Material/importFCMat.py index 51ec311ab167..9df0ce980e2f 100644 --- a/src/Mod/Material/importFCMat.py +++ b/src/Mod/Material/importFCMat.py @@ -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: