def __init__(self, parent, file): super(SchematicFrame, self).__init__(parent) # create module list self.tree_parts_manager = TreeManagerParts( self.tree_parts, context_menu=self.menu_parts) self.tree_parts_manager.AddTextColumn("Reference") self.tree_parts_manager.AddTextColumn("Value") self.tree_parts_manager.AddTextColumn("Part") self.tree_parts_manager.AddTextColumn("Symbol") self.tree_parts_manager.AddTextColumn("Footprint") self.tree_parts_manager.OnSelectionChanged = self.onTreePartsSelChanged self.file = file self.schematic = KicadSchematicFile() self.data_frame = PartPreviewDataFrame(self.panel_preview) sizer = wx.BoxSizer(wx.VERTICAL) self.panel_preview.SetSizer(sizer) sizer.Fit(self.panel_preview) sizer.Add(self.data_frame, 0, wx.ALL | wx.EXPAND, 0) self.panel_preview.Layout() # used to know if reload dialog is already shown self.has_reload_dialog = False self.load()
def SetSchematic(self, file): self.schematic = KicadSchematicFile() self.schematic.LoadFile(file) for component in self.schematic.Components(): if component.kipart_id: part = None try: part = rest.api.find_part(component.kipart_id) self.AddPart(part) self.AddPartComponent(part, component) except Exception as e: print format(e)
class SchematicFrame(PanelSchematic): def __init__(self, parent, file): super(SchematicFrame, self).__init__(parent) # create module list self.tree_parts_manager = TreeManagerParts( self.tree_parts, context_menu=self.menu_parts) self.tree_parts_manager.AddTextColumn("Reference") self.tree_parts_manager.AddTextColumn("Value") self.tree_parts_manager.AddTextColumn("Part") self.tree_parts_manager.AddTextColumn("Symbol") self.tree_parts_manager.AddTextColumn("Footprint") self.tree_parts_manager.OnSelectionChanged = self.onTreePartsSelChanged self.file = file self.schematic = KicadSchematicFile() self.data_frame = PartPreviewDataFrame(self.panel_preview) sizer = wx.BoxSizer(wx.VERTICAL) self.panel_preview.SetSizer(sizer) sizer.Fit(self.panel_preview) sizer.Add(self.data_frame, 0, wx.ALL | wx.EXPAND, 0) self.panel_preview.Layout() # used to know if reload dialog is already shown self.has_reload_dialog = False self.load() def load(self): self.loadSchematic() def loadSchematic(self): self.schematic.LoadFile(self.file) #self.schematic.DebugWrite(self.schematic.parent) # load parts parts = rest.api.find_parts(with_parameters=True) for component in self.schematic.Components(): if component.kipart_id != '': part_id = int(component.kipart_id) part = None for p in parts: if p.id == part_id: part = p break if part: self.associate_part(component, part) self.schematic.Save() self.tree_parts_manager.SaveState() # load schematic parts for component in self.schematic.Components(): partobj = self.tree_parts_manager.FindPart(component) if partobj: partobj.component = component show = True if self.tool_show_all.IsToggled( ) and 'hidden' in component.kipart_status: show = False if show == False: try: self.tree_parts_manager.DeleteItem(None, partobj) except: pass if self.tree_parts_manager.DropStateObject(partobj) == False: if show == True: self.tree_parts_manager.AppendPart(component) self.tree_parts_manager.PurgeState() def reload(self): if self.has_reload_dialog: # reload dialog already pending return if self.schematic.Modified(): self.has_reload_dialog = True res = wx.MessageDialog(self, "%s modified, reload it?" % self.file, "File changed", wx.YES_NO | wx.ICON_QUESTION).ShowModal() if res == wx.ID_YES: self.load() self.has_reload_dialog = False def onToolRefreshSchematic(self, event): self.load() def onTreePartsSelChanged(self, event): self.data_frame.SetPart(None) if len(self.tree_parts.GetSelections()) > 1: return item = self.tree_parts.GetSelection() if item.IsOk(): partobj = self.tree_parts_manager.ItemToObject(item) part = None try: if partobj.component.kipart_id != '': part = rest.api.find_part(partobj.component.kipart_id) except Exception as e: print_stack() print format(e) self.data_frame.SetPart(part) def onMenuPartsLinkSelection(self, event): dropdown = DropdownDialog(self.tree_parts, SelectPartFrame, "") dropdown.panel.Bind(EVT_SELECT_PART_OK_EVENT, self.onSelectPartCallback) dropdown.Dropdown() def get_symbol(self, path): return re.sub(r".*\.lib/", "", path).replace(".mod", "") def get_footprint(self, path): lib = os.path.basename(os.path.dirname(path)).replace(".pretty", "") footprint = os.path.basename(path).replace(".kicad_mod", "") return lib + ":" + footprint def associate_part(self, component, part): symbol = None if part.symbol: symbol = self.get_symbol(part.symbol.source_path) footprint = None if part.footprint: footprint = self.get_footprint(part.footprint.source_path) if symbol: component.symbol = symbol if footprint: component.footprint = footprint if part.value_parameter: for parameter in part.parameters: if parameter.name == part.value_parameter: paramobj = DataModelPartParameter(part, parameter) component.value = paramobj.nom_string() component.kipart_id = unicode(part.id) component.kipart_sku = unicode(part.name) def onSelectPartCallback(self, part_event): part = part_event.data items = self.tree_parts.GetSelections() if items: for item in items: partobj = self.tree_parts_manager.ItemToObject(item) self.associate_part(partobj.component, part) self.schematic.Save() self.load() def onToolExportBomClicked(self, event): path = os.getcwd() dlg = wx.FileDialog(self, message="Save a bom file", defaultDir=path, defaultFile="new", wildcard="Kipartman bom (*.bom)|*.bom", style=wx.FD_SAVE | wx.FD_CHANGE_DIR) dlg.SetFilterIndex(0) if dlg.ShowModal() == wx.ID_OK: filename = dlg.GetPath() bom = Bom() try: bom.SetSchematic(self.file) bom.SaveFile(filename) except Exception as e: print_stack() wx.MessageBox(format(e), 'Error saving %s' % filename, wx.OK | wx.ICON_ERROR) def onMenuPartsUnlinkSelection(self, event): items = self.tree_parts.GetSelections() if items: for item in items: partobj = self.tree_parts_manager.ItemToObject(item) component = partobj.component component.kipart_id = '' component.kipart_sku = '' self.load() def onMenuPartsHideSelection(self, event): items = self.tree_parts.GetSelections() if items: for item in items: partobj = self.tree_parts_manager.ItemToObject(item) component = partobj.component component.kipart_status = 'hidden' self.schematic.Save() self.load() def onMenuPartsShowSelection(self, event): items = self.tree_parts.GetSelections() if items: for item in items: partobj = self.tree_parts_manager.ItemToObject(item) component = partobj.component component.kipart_status = '' self.schematic.Save() self.load() def onToolShowAllClicked(self, event): self.load()
def LoadFile(self, filename): print "Load BOM", filename # for part in self.parts: # self.parts.remove(part) self.part_components = {} self.component_part = {} self.parts = [] if (os.path.isfile(filename) == False): raise Exception("Error: %s does not exists" % filename) with open(filename, 'r') as infile: content = json.load(infile) # load associated schematic self.schematic = KicadSchematicFile() self.schematic.LoadFile(content['schematic']) part_not_found = [] for part in content['parts']: # load part from server try: self.parts.append(rest.api.find_part(part['id'])) self.part_components[part['id']] = [] except: print_stack() print "Warning: part %d not found on server" % part['id'] part_not_found.append(part) component_not_found = [] part_id_not_found = [] # load components from BOM for part_id in content['components']: part = None # get part from list for p in self.parts: if p.id == int(part_id): part = p break if part: schematic_components = self.schematic.Components() # get components from schematic for component in content['components'][part_id]: if self.part_components.has_key(int(part_id)): if self.schematic.ExistComponent( component['timestamp']): self.part_components[int(part_id)].append( self.schematic.GetComponent( component['timestamp'])) self.component_part[component['timestamp']] = part else: print "Warning: component %s does not exist in schematic" % component[ 'timestamp'] component_not_found.append(component) else: print "Warning: part %d not found on bom" % part_id part_id_not_found.append(int(part_id)) else: print "Warning: part %d from BOM does not exist on server" % int( part_id) part_id_not_found.append(int(part_id)) # TODO: show error messages from part_not_found, component_not_found and part_id_not_found self.filename = filename self.saved = True
class Bom(object): def __init__(self): self.filename = None self.parts = [] self.part_components = {} self.component_part = {} self.schematic = None self.saved = True def LoadFile(self, filename): print "Load BOM", filename # for part in self.parts: # self.parts.remove(part) self.part_components = {} self.component_part = {} self.parts = [] if (os.path.isfile(filename) == False): raise Exception("Error: %s does not exists" % filename) with open(filename, 'r') as infile: content = json.load(infile) # load associated schematic self.schematic = KicadSchematicFile() self.schematic.LoadFile(content['schematic']) part_not_found = [] for part in content['parts']: # load part from server try: self.parts.append(rest.api.find_part(part['id'])) self.part_components[part['id']] = [] except: print_stack() print "Warning: part %d not found on server" % part['id'] part_not_found.append(part) component_not_found = [] part_id_not_found = [] # load components from BOM for part_id in content['components']: part = None # get part from list for p in self.parts: if p.id == int(part_id): part = p break if part: schematic_components = self.schematic.Components() # get components from schematic for component in content['components'][part_id]: if self.part_components.has_key(int(part_id)): if self.schematic.ExistComponent( component['timestamp']): self.part_components[int(part_id)].append( self.schematic.GetComponent( component['timestamp'])) self.component_part[component['timestamp']] = part else: print "Warning: component %s does not exist in schematic" % component[ 'timestamp'] component_not_found.append(component) else: print "Warning: part %d not found on bom" % part_id part_id_not_found.append(int(part_id)) else: print "Warning: part %d from BOM does not exist on server" % int( part_id) part_id_not_found.append(int(part_id)) # TODO: show error messages from part_not_found, component_not_found and part_id_not_found self.filename = filename self.saved = True def byteify(self, input): if isinstance(input, dict): return { self.byteify(key): self.byteify(value) for key, value in input.iteritems() } elif isinstance(input, list): return [self.byteify(element) for element in input] elif isinstance(input, unicode): return input.encode('utf-8') else: return input def SaveFile(self, filename): print "Save BOM", filename with open(filename, 'w') as outfile: parts = [] for part in self.parts: parts.append({ 'id': part.id, 'name': part.name, 'description': part.description }) part_components = {} for part_name in self.part_components: if len(self.part_components[part_name]) > 0: part_components[part_name] = [] for component in self.part_components[part_name]: part_components[part_name].append({ 'timestamp': component.timestamp, 'reference': component.reference, 'value': component.value }) input = { 'schematic': self.schematic.filename, 'parts': parts, 'components': part_components } # json_string = json.dumps(input, ensure_ascii=False, sort_keys=True, indent=4, separators=(',', ': ')).encode('utf8') json_string = json.dumps(self.byteify(input), ensure_ascii=False, sort_keys=True, indent=4, separators=(',', ': ')) outfile.write(json_string) # json.dump(self.byteify(input), outfile, sort_keys=True, # indent=4, separators=(',', ': ')) self.filename = filename self.saved = True def Save(self): self.SaveFile(self.filename) def Parts(self): return self.parts def ExistPart(self, part): for p in self.parts: if p.id == part.id: return True return False # def FindPartComponent(self, component, part_id): # try: # part = self.component_part[component.timestamp] # except: # raise BomException("Component %s does not exist in BOM"%component.timestamp) # for part in def SetSchematic(self, file): self.schematic = KicadSchematicFile() self.schematic.LoadFile(file) for component in self.schematic.Components(): if component.kipart_id: part = None try: part = rest.api.find_part(component.kipart_id) self.AddPart(part) self.AddPartComponent(part, component) except Exception as e: print format(e) def AddPart(self, part): self.parts.append(part) self.part_components[part.id] = [] self.saved = False def AddPartComponent(self, part, component): self.part_components[part.id].append(component) self.component_part[component.timestamp] = part self.saved = False def RemovePart(self, part): self.parts.remove(part) for component in self.part_components[part.id]: self.component_part.pop(component.timestamp) self.part_components.pop(part.id) self.saved = False def RemovePartComponent(self, component): part = self.component_part[component.timestamp] self.component_part.pop(component.timestamp) for part_component in self.part_components[part.id]: if part_component.timestamp == component.timestamp: self.part_components[part.id].remove(part_component) self.saved = False def NumComponents(self, bom_part): num_components = 0 if self.part_components.has_key(bom_part.id): num_components = num_components + len( self.part_components[bom_part.id]) return num_components