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()
Esempio n. 2
0
    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()
Esempio n. 4
0
    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
Esempio n. 5
0
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