diff --git a/src/Mod/Material/Init.py b/src/Mod/Material/Init.py index c583d073e3..faec0e158e 100644 --- a/src/Mod/Material/Init.py +++ b/src/Mod/Material/Init.py @@ -1,6 +1,6 @@ #*************************************************************************** #* * -#* Copyright (c) 2013 - Juergen Riegel * +#* Copyright (c) 2013 - Juergen Riegel * #* * #* This program is free software; you can redistribute it and/or modify * #* it under the terms of the GNU Lesser General Public License (LGPL) * @@ -20,6 +20,9 @@ #* * #*************************************************************************** -# import for the FreeCAD Material card -FreeCAD.addImportType("FreeCAD Material Card (*.FCMat)","importFCMat") +import FreeCAD + + +# import for the FreeCAD Material card +FreeCAD.addImportType("FreeCAD Material Card (*.FCMat)", "importFCMat") diff --git a/src/Mod/Material/Material.py b/src/Mod/Material/Material.py index dca607a105..da6e24a6df 100644 --- a/src/Mod/Material/Material.py +++ b/src/Mod/Material/Material.py @@ -68,7 +68,7 @@ def importFCMat(fileName): return dict1 -def exportFCMat(fileName,matDict): +def exportFCMat(fileName, matDict): "Write a material dictionary to a FCMat file" try: import ConfigParser as configparser @@ -79,14 +79,14 @@ def exportFCMat(fileName,matDict): # create groups for x in matDict.keys(): - grp,key = string.split(x,sep='_') + grp, key = string.split(x, sep='_') if not Config.has_section(grp): Config.add_section(grp) # fill groups for x in matDict.keys(): - grp,key = string.split(x,sep='_') - Config.set(grp,key,matDict[x]) + grp, key = string.split(x, sep='_') + Config.set(grp, key, matDict[x]) Preamble = "# This is a FreeCAD material-card file\n\n" # Writing our configuration file to 'example.cfg' diff --git a/src/Mod/Material/MaterialEditor.py b/src/Mod/Material/MaterialEditor.py index 2aa8a9822d..a70e398efa 100644 --- a/src/Mod/Material/MaterialEditor.py +++ b/src/Mod/Material/MaterialEditor.py @@ -1,6 +1,6 @@ #*************************************************************************** #* * -#* Copyright (c) 2013 - Yorik van Havre * +#* Copyright (c) 2013 - Yorik van Havre * #* * #* This program is free software; you can redistribute it and/or modify * #* it under the terms of the GNU Lesser General Public License (LGPL) * @@ -19,20 +19,24 @@ #* USA * #* * #*************************************************************************** + + from __future__ import print_function +import FreeCAD +import FreeCADGui +import os +from PySide import QtCore, QtGui +# from PySide import QtUiTools, QtSvg -import FreeCAD, FreeCADGui, os -from PySide import QtCore, QtGui, QtUiTools, QtSvg -__title__="FreeCAD material editor" +__title__ = "FreeCAD material editor" __author__ = "Yorik van Havre" __url__ = "http://www.freecadweb.org" class MaterialEditor: - - def __init__(self, obj = None, prop = None, material = None): + 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.""" self.obj = obj @@ -40,14 +44,14 @@ class MaterialEditor: self.material = material self.customprops = [] # load the UI file from the same directory as this script - self.widget = FreeCADGui.PySideUic.loadUi(os.path.dirname(__file__)+os.sep+"materials-editor.ui") + self.widget = FreeCADGui.PySideUic.loadUi(os.path.dirname(__file__) + os.sep + "materials-editor.ui") # additional UI fixes and tweaks 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.widget.Editor.header().resizeSection(0,200) + 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) @@ -79,7 +83,6 @@ class MaterialEditor: if d: self.updateContents(d) - def addPropertiesToGroup(self, propertygroup=None): "Adds property to a known group in Tree widges" if propertygroup: @@ -87,20 +90,19 @@ class MaterialEditor: groupproperties = propertygroup[1] else: return - + # parent self.widget.Editor.addTopLevelItem(QtGui.QTreeWidgetItem([groupname, ])) # how to expand it ? # childs for key in groupproperties: - if not self.widget.Editor.findItems(key,QtCore.Qt.MatchRecursive,0): - top = self.widget.Editor.findItems(translate("Material", groupname),QtCore.Qt.MatchExactly,0) + if not self.widget.Editor.findItems(key, QtCore.Qt.MatchRecursive, 0): + top = self.widget.Editor.findItems(translate("Material", groupname), 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) - + i.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsDragEnabled | QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled) + i.setText(0, key) def getMaterialResources(self): self.fem_prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Material/Resources") @@ -122,45 +124,42 @@ class MaterialEditor: self.resources.append(custom_mat_dir) self.outputResources() - def outputResources(self): print('locations we gone look for material cards:') for path in self.resources: print(' ' + path) print('\n') - def updateCards(self): "updates the contents of the materials combo with existing material cards" self.getMaterialResources() self.cards = {} for p in self.resources: for f in os.listdir(p): - b,e = os.path.splitext(f) + b, e = os.path.splitext(f) if e.upper() == ".FCMAT": self.cards[b] = p + os.sep + f if self.cards: self.widget.ComboMaterial.clear() - self.widget.ComboMaterial.addItem("") # add a blank item first - for k,i in self.cards.items(): + self.widget.ComboMaterial.addItem("") # add a blank item first + for k, i in self.cards.items(): self.widget.ComboMaterial.addItem(k) - - def updateContents(self,data): + def updateContents(self, data): "updates the contents of the editor with the given data (can be the name of a card or a dictionary)" #print type(data) - if isinstance(data,dict): + if isinstance(data, dict): self.clearEditor() - for k,i in data.items(): + for k, i in data.items(): k = self.expandKey(k) # most material dict keys are added with addPropertiesToGroup, see tuple with all these properties at module end - slot = self.widget.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) + slot.setText(1, i) else: - self.addCustomProperty(k,i) - elif isinstance(data,unicode): + self.addCustomProperty(k, i) + elif isinstance(data, unicode): k = str(data) if k: if k in self.cards: @@ -169,27 +168,23 @@ class MaterialEditor: if d: self.updateContents(d) - def openProductURL(self): "opens the contents of the ProductURL field in an external browser" - url = str(self.widget.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)) - def accept(self): "if we are editing a property, set the property values" if self.prop and self.obj: d = self.getDict() o = FreeCAD.ActiveDocument.getObject(self.obj) - setattr(o,self.prop,d) + setattr(o, self.prop, d) QtGui.QDialog.accept(self.widget) - def reject(self): QtGui.QDialog.reject(self.widget) - def expandKey(self, key): "adds spaces before caps in a KeyName" nk = "" @@ -202,7 +197,6 @@ class MaterialEditor: nk += l return nk - def collapseKey(self, key): "removes the spaces in a Key Name" nk = "" @@ -211,45 +205,42 @@ class MaterialEditor: nk += l return nk - def clearEditor(self): "Clears the contents of the editor" 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,"") + c.setText(1, "") for k in self.customprops: self.deleteCustomProperty(k) - - def addCustomProperty(self, key = None, value = None): + def addCustomProperty(self, key=None, value=None): "Adds a custom property to the editor, optionally with a value" if not key: key = str(self.widget.EditProperty.text()) if key: - if not key in self.customprops: - 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 key not in self.customprops: + 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) + 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.widget.EditProperty.setText("") if value: - i.setText(1,value) + i.setText(1, value) - - def deleteCustomProperty(self, key = None): + def deleteCustomProperty(self, key=None): "Deletes a custom property from the editor" if not key: key = str(self.widget.Editor.currentItem().text(0)) if key: if key in self.customprops: - i = self.widget.Editor.findItems(key,QtCore.Qt.MatchRecursive,0) + i = self.widget.Editor.findItems(key, QtCore.Qt.MatchRecursive, 0) if i: - top = self.widget.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]) @@ -257,28 +248,24 @@ class MaterialEditor: top.takeChild(ii) self.customprops.remove(key) - def itemClicked(self, item, column): "Edits an item if it is not in the first column" if column > 0: self.widget.Editor.editItem(item, column) - def itemChanged(self, item, column): "Handles text changes" if item.text(0) == "Section Fill Pattern": if column == 1: self.setTexture(item.text(1)) - - def checkDeletable(self,current,previous): + 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.widget.ButtonDeleteProperty.setEnabled(True) else: self.widget.ButtonDeleteProperty.setEnabled(False) - def getDict(self): "returns a dictionary from the contents of the editor" d = {} @@ -289,26 +276,23 @@ class MaterialEditor: # TODO the following should be translated back to english,since text(0) could be translated matkey = self.collapseKey(str(c.text(0))) matvalue = unicode(c.text(1)) - if matvalue or (matkey == 'Name'): + if matvalue or (matkey == 'Name'): # use only keys which are not empty and the name even if empty d[matkey] = matvalue # self.outputDict(d) return d - # ??? after return ??? if d: self.updateContents(d) - self.widget.Editor.topLevelItem(6).child(4).setToolTip(1,self.getPatternsList()) - + self.widget.Editor.topLevelItem(6).child(4).setToolTip(1, self.getPatternsList()) def outputDict(self, d): print('MaterialEditor dictionary') for param in d: print(' ' + param + ' : ' + d[param]) - - def setTexture(self,pattern): + def setTexture(self, pattern): "displays a texture preview if needed" self.widget.PreviewVector.hide() if pattern: @@ -317,15 +301,14 @@ class MaterialEditor: except: print("DrawingPatterns not found") else: - pattern = DrawingPatterns.buildFileSwatch(pattern,size=96,png=True) + pattern = DrawingPatterns.buildFileSwatch(pattern, size=96, png=True) if pattern: self.widget.PreviewVector.setPixmap(QtGui.QPixmap(pattern)) self.widget.PreviewVector.show() - def openfile(self): "Opens a FCMat file" - filetuple = QtGui.QFileDialog.getOpenFileName(QtGui.QApplication.activeWindow(),'Open FreeCAD Material file','*.FCMat') + filetuple = QtGui.QFileDialog.getOpenFileName(QtGui.QApplication.activeWindow(), 'Open FreeCAD Material file', '*.FCMat') filename = filetuple[0] # a tuple of two empty strings returns True, so use the filename directly if filename: self.clearEditor() @@ -334,41 +317,36 @@ class MaterialEditor: if d: self.updateContents(d) - def savefile(self): "Saves a FCMat file" - name = str(self.widget.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" - filetuple = QtGui.QFileDialog.getSaveFileName(QtGui.QApplication.activeWindow(),'Save FreeCAD Material file',name+'.FCMat') + filetuple = QtGui.QFileDialog.getSaveFileName(QtGui.QApplication.activeWindow(), 'Save FreeCAD Material file', name + '.FCMat') filename = filetuple[0] # a tuple of two empty strings returns True, so use the filename directly if filename: d = self.getDict() # self.outputDict(d) if d: import importFCMat - importFCMat.write(filename,d) - + importFCMat.write(filename, d) def show(self): return self.widget.show() - def exec_(self): return self.widget.exec_() - - -def translate(context,text): +def translate(context, text): "translates text" - return text #TODO use Qt translation mechanism here + return text # TODO use Qt translation mechanism here -def openEditor(obj = None, prop = None): +def openEditor(obj=None, prop=None): """openEditor([obj,prop]): opens the editor, optionally with an object name and material property name to edit""" - editor = MaterialEditor(obj,prop) + editor = MaterialEditor(obj, prop) editor.exec_() @@ -393,4 +371,4 @@ material_properties = ( ('Rendering', ['Diffuse Color', 'Ambient Color', 'Specular Color', 'Shininess', 'Emissive Color', 'Transparency', 'Vertex Shader', 'Fragment Shader', 'Texture Path', 'Texture Scaling']), ('Vector rendering', ['View Color', 'Father', 'View Linewidth', 'Section Color', 'Section Fill Pattern', 'Section Linewidth']), ('User defined', []) - ) +) diff --git a/src/Mod/Material/importFCMat.py b/src/Mod/Material/importFCMat.py index 2c0b290be2..c0011e4e3c 100644 --- a/src/Mod/Material/importFCMat.py +++ b/src/Mod/Material/importFCMat.py @@ -1,6 +1,6 @@ #*************************************************************************** #* * -#* Copyright (c) 2013 - Juergen Riegel * +#* Copyright (c) 2013 - Juergen Riegel * #* * #* This program is free software; you can redistribute it and/or modify * #* it under the terms of the GNU Lesser General Public License (LGPL) * @@ -20,29 +20,35 @@ #* * #*************************************************************************** -import FreeCAD, Material + +import FreeCAD +# import Material import os -__title__="FreeCAD material card importer" + +__title__ = "FreeCAD material card importer" __author__ = "Juergen Riegel" __url__ = "http://www.freecadweb.org" + # file structure - this affects how files are saved FileStructure = [ - [ "Meta", ["CardName","AuthorAndLicense","Source"] ], - [ "General", ["Name","Father","Description","Density","Vendor","ProductURL","SpecificPrice"] ], - [ "Mechanical", ["YoungsModulus","UltimateTensileStrength","CompressiveStrength","Elasticity","FractureToughness"] ], - [ "FEM", ["PoissonRatio"] ], - [ "Architectural", ["Model","ExecutionInstructions","FireResistanceClass","StandardCode","ThermalConductivity","SoundTransmissionClass","Color","Finish","UnitsPerQuantity","EnvironmentalEfficiencyClass"] ], - [ "Rendering", ["DiffuseColor","AmbientColor","SpecularColor","Shininess","EmissiveColor","Transparency","VertexShader","FragmentShader","TexturePath","TextureScaling"] ], - [ "Vector rendering",["ViewColor","ViewFillPattern","SectionFillPattern","ViewLinewidth","SectionLinewidth"] ], - [ "User defined", [] ] + ["Meta", ["CardName", "AuthorAndLicense", "Source"]], + ["General", ["Name", "Father", "Description", "Density", "Vendor", "ProductURL", "SpecificPrice"]], + ["Mechanical", ["YoungsModulus", "UltimateTensileStrength", "CompressiveStrength", "Elasticity", "FractureToughness"]], + ["FEM", ["PoissonRatio"]], + ["Architectural", ["Model", "ExecutionInstructions", "FireResistanceClass", "StandardCode", "ThermalConductivity", "SoundTransmissionClass", "Color", "Finish", "UnitsPerQuantity", "EnvironmentalEfficiencyClass"]], + ["Rendering", ["DiffuseColor", "AmbientColor", "SpecularColor", "Shininess", "EmissiveColor", "Transparency", "VertexShader", "FragmentShader", "TexturePath", "TextureScaling"]], + ["Vector rendering", ["ViewColor", "ViewFillPattern", "SectionFillPattern", "ViewLinewidth", "SectionLinewidth"]], + ["User defined", []] ] + # to distinguish python built-in open function from the one declared below if open.__module__ == '__builtin__': pythonopen = open + def open(filename): "called when freecad wants to open a file" docname = os.path.splitext(os.path.basename(filename))[0] @@ -52,7 +58,8 @@ def open(filename): read(filename) return doc -def insert(filename,docname): + +def insert(filename, docname): "called when freecad wants to import a file" try: doc = FreeCAD.getDocument(docname) @@ -62,10 +69,12 @@ def insert(filename,docname): read(filename) return doc -def export(exportList,filename): + +def export(exportList, filename): "called when freecad exports a file" return + def decode(name): "decodes encoded strings" try: @@ -78,9 +87,10 @@ def decode(name): decodedName = name return decodedName + def read(filename): "reads a FCMat file and returns a dictionary from it" - if isinstance(filename,unicode): + if isinstance(filename, unicode): import sys filename = filename.encode(sys.getfilesystemencoding()) f = pythonopen(filename) @@ -99,19 +109,20 @@ def read(filename): l += 1 return d -def write(filename,dictionary): + +def write(filename, dictionary): "writes the given dictionary to the given file" # sort the data into sections contents = [] for key in FileStructure: - contents.append({"keyname":key[0]}) + contents.append({"keyname": key[0]}) if key[0] == "Meta": header = contents[-1] elif key[0] == "User defined": user = contents[-1] for p in key[1]: contents[-1][p] = "" - for k,i in dictionary.iteritems(): + for k, i in dictionary.iteritems(): found = False for group in contents: if not found: @@ -121,12 +132,12 @@ def write(filename,dictionary): if not found: user[k] = i # write header - rev = FreeCAD.ConfigGet("BuildVersionMajor")+"."+FreeCAD.ConfigGet("BuildVersionMinor")+" "+FreeCAD.ConfigGet("BuildRevision") - if isinstance(filename,unicode): + rev = FreeCAD.ConfigGet("BuildVersionMajor") + "." + FreeCAD.ConfigGet("BuildVersionMinor") + " " + FreeCAD.ConfigGet("BuildRevision") + if isinstance(filename, unicode): import sys filename = filename.encode(sys.getfilesystemencoding()) print(filename) - f = pythonopen(filename,"wb") + f = pythonopen(filename, "wb") f.write("; " + header["CardName"].encode("utf8") + "\n") f.write("; " + header["AuthorAndLicense"].encode("utf8") + "\n") f.write("; file produced by FreeCAD " + rev + "\n") @@ -143,7 +154,7 @@ def write(filename,dictionary): if len(s) > 1: # if the section has no contents, we don't write it f.write("[" + s["keyname"] + "]\n") - for k,i in s.iteritems(): + for k, i in s.iteritems(): if (k != "keyname" and i != '') or k == "Name": # use only keys which are not empty and the name even if empty f.write(k + "=" + i.encode('utf-8') + "\n")