Now the row number column is a regular column.
Its name is `Row` and you can put everywhere. No `number_rows` option needed or special cases, is just another column
This commit is contained in:
parent
64576e3975
commit
5be7254594
|
|
@ -365,6 +365,16 @@ def group_components(cfg, components):
|
|||
# Sort the groups
|
||||
# First priority is the Type of component (e.g. R?, U?, L?)
|
||||
groups = sorted(groups, key=lambda g: [g.components[0].ref_prefix, get_value_sort(g.components[0])])
|
||||
# Enumerate the groups
|
||||
c = 1
|
||||
dnf = 1
|
||||
for g in groups:
|
||||
if cfg.ignore_dnf and not g.is_fitted():
|
||||
g.update_field('Row', str(dnf))
|
||||
dnf += 1
|
||||
else:
|
||||
g.update_field('Row', str(c))
|
||||
c += 1
|
||||
return groups
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ class ColumnList:
|
|||
COL_DATASHEET_L = COL_DATASHEET.lower()
|
||||
COL_SHEETPATH = 'Sheetpath'
|
||||
COL_SHEETPATH_L = COL_SHEETPATH.lower()
|
||||
COL_ROW_NUMBER = 'Row'
|
||||
COL_ROW_NUMBER_L = COL_ROW_NUMBER.lower()
|
||||
|
||||
# Default columns for groups
|
||||
COL_GRP_QUANTITY = 'Quantity Per PCB'
|
||||
|
|
@ -37,13 +39,15 @@ class ColumnList:
|
|||
COL_GRP_BUILD_QUANTITY_L = COL_GRP_BUILD_QUANTITY.lower()
|
||||
|
||||
# Generated columns
|
||||
COLUMNS_GEN_L = [
|
||||
COL_GRP_QUANTITY_L,
|
||||
COL_GRP_BUILD_QUANTITY_L,
|
||||
]
|
||||
COLUMNS_GEN_L = {
|
||||
COL_GRP_QUANTITY_L: 1,
|
||||
COL_GRP_BUILD_QUANTITY_L: 1,
|
||||
COL_ROW_NUMBER_L: 1,
|
||||
}
|
||||
|
||||
# Default columns
|
||||
COLUMNS_DEFAULT = [
|
||||
COL_ROW_NUMBER,
|
||||
COL_DESCRIPTION,
|
||||
COL_PART,
|
||||
COL_PART_LIB,
|
||||
|
|
|
|||
|
|
@ -31,14 +31,7 @@ def write_csv(filename, ext, groups, headings, head_names, cfg):
|
|||
writer = csv.writer(f, delimiter=delimiter, lineterminator="\n")
|
||||
# Headers
|
||||
if not cfg.hide_headers:
|
||||
if cfg.number_rows:
|
||||
comp = "Component"
|
||||
comp_lc = comp.lower()
|
||||
if comp_lc in cfg.column_rename:
|
||||
comp = cfg.column_rename[comp_lc]
|
||||
writer.writerow([comp] + head_names)
|
||||
else:
|
||||
writer.writerow(head_names)
|
||||
writer.writerow(head_names)
|
||||
# Body
|
||||
count = 0
|
||||
row_count = 1
|
||||
|
|
@ -46,9 +39,6 @@ def write_csv(filename, ext, groups, headings, head_names, cfg):
|
|||
if cfg.ignore_dnf and not group.is_fitted():
|
||||
continue
|
||||
row = group.get_row(headings)
|
||||
# Row number
|
||||
if cfg.number_rows:
|
||||
row = [str(row_count)] + row
|
||||
writer.writerow(row)
|
||||
count += group.get_count()
|
||||
row_count += 1
|
||||
|
|
|
|||
|
|
@ -38,8 +38,6 @@ def html_table(html, groups, headings, head_names, cfg, link_datasheet, link_dig
|
|||
html.write('<table border="1">\n')
|
||||
# Row titles:
|
||||
html.write("<tr>\n")
|
||||
if cfg.number_rows:
|
||||
html.write("\t<th></th>\n")
|
||||
for i, h in enumerate(head_names):
|
||||
# Cell background color
|
||||
bg = bg_color(headings[i])
|
||||
|
|
@ -53,10 +51,6 @@ def html_table(html, groups, headings, head_names, cfg, link_datasheet, link_dig
|
|||
row = group.get_row(headings)
|
||||
row_count += 1
|
||||
html.write("<tr>\n")
|
||||
# Row number
|
||||
if cfg.number_rows:
|
||||
html.write('\t<td align="center">{n}</td>\n'.format(n=row_count))
|
||||
|
||||
for n, r in enumerate(row):
|
||||
# A link to Digi-Key?
|
||||
if link_digikey and headings[n] in link_digikey:
|
||||
|
|
|
|||
|
|
@ -46,9 +46,8 @@ def add_info(worksheet, column_widths, row, formats, text, value):
|
|||
value = str(value)
|
||||
else:
|
||||
worksheet.write_string(row, 1, value, formats[1])
|
||||
value_l = len(value)
|
||||
if value_l > column_widths[1]:
|
||||
column_widths[1] = value_l
|
||||
column_widths[0] = max(len(text), column_widths[0])
|
||||
column_widths[1] = max(len(value), column_widths[1])
|
||||
return row + 1
|
||||
|
||||
|
||||
|
|
@ -68,25 +67,13 @@ def write_xlsx(filename, groups, col_fields, head_names, cfg):
|
|||
workbook = Workbook(filename)
|
||||
worksheet = workbook.add_worksheet()
|
||||
|
||||
if cfg.number_rows:
|
||||
comp = "Component"
|
||||
if comp.lower() in cfg.column_rename:
|
||||
comp = cfg.column_rename[comp.lower()]
|
||||
row_headings = [comp] + head_names
|
||||
else:
|
||||
row_headings = head_names
|
||||
|
||||
# Headings
|
||||
row_headings = head_names
|
||||
cellformats = {}
|
||||
column_widths = {}
|
||||
for i in range(len(row_headings)):
|
||||
cellformats[i] = workbook.add_format(DEFAULT_FMT)
|
||||
bg = None
|
||||
if cfg.number_rows:
|
||||
if i > 0:
|
||||
bg = bg_color(col_fields[i-1])
|
||||
else:
|
||||
bg = bg_color(col_fields[i])
|
||||
bg = bg_color(col_fields[i])
|
||||
if bg:
|
||||
cellformats[i].set_bg_color(bg)
|
||||
column_widths[i] = len(row_headings[i]) + 10
|
||||
|
|
@ -106,9 +93,6 @@ def write_xlsx(filename, groups, col_fields, head_names, cfg):
|
|||
continue
|
||||
# Get the data row
|
||||
row = group.get_row(col_fields)
|
||||
# Add row number
|
||||
if cfg.number_rows:
|
||||
row = [str(row_count)] + row
|
||||
# Fill the row
|
||||
for i in range(len(row)):
|
||||
cell = row[i]
|
||||
|
|
@ -131,6 +115,7 @@ def write_xlsx(filename, groups, col_fields, head_names, cfg):
|
|||
title_fmt.set_bold()
|
||||
|
||||
formats = [title_fmt, cellformat_left]
|
||||
# TODO: Language?
|
||||
row_count = add_info(worksheet, column_widths, row_count, formats, "Component Groups:", cfg.n_groups)
|
||||
row_count = add_info(worksheet, column_widths, row_count, formats, "Component Count:", cfg.n_total)
|
||||
row_count = add_info(worksheet, column_widths, row_count, formats, "Fitted Components:", cfg.n_fitted)
|
||||
|
|
|
|||
|
|
@ -93,8 +93,6 @@ class BoMOptions(BaseOptions):
|
|||
""" Generate a separated section for DNF (Do Not Fit) components (HTML only) """
|
||||
self.use_alt = False
|
||||
""" Print grouped references in the alternate compressed style eg: R1-R7,R18 """
|
||||
self.number_rows = True
|
||||
""" First column is the row number """
|
||||
self.group_connectors = True
|
||||
""" Connectors with the same footprints will be grouped together, independent of the name of the connector """
|
||||
self.test_regex = True
|
||||
|
|
@ -208,9 +206,8 @@ class BoMOptions(BaseOptions):
|
|||
# This is tricky
|
||||
# Lower case available columns
|
||||
valid_columns = self._get_columns()
|
||||
valid_columns.append(ColumnList.COL_ROW_NUMBER)
|
||||
valid_columns_l = {c.lower(): c for c in valid_columns}
|
||||
# Special row number column
|
||||
valid_columns_l['component'] = 'Component'
|
||||
logger.debug("Valid columns: "+str(valid_columns))
|
||||
# Create the different lists
|
||||
columns = []
|
||||
|
|
@ -233,9 +230,6 @@ class BoMOptions(BaseOptions):
|
|||
raise KiPlotConfigurationError('Invalid column name `{}`'.format(new_col))
|
||||
columns.append(new_col)
|
||||
columns_l[new_col.lower()] = new_col
|
||||
# TODO less magic, more explicit
|
||||
if 'component' in columns_l:
|
||||
del columns_l['component']
|
||||
# Create a list of the columns we don't want
|
||||
self.ignore = [c for c in valid_columns_l.keys() if c not in columns_l]
|
||||
# And this is the ordered list with the case style defined by the user
|
||||
|
|
@ -264,6 +258,7 @@ class BoM(BaseOutput): # noqa: F821
|
|||
are loaded from the schematic.
|
||||
Important differences with KiBoM output:
|
||||
- All options are in the main `options` section, not in `conf` subsection.
|
||||
- The `Component` column is named `Row` and works just like any other column.
|
||||
This output is what you get from the 'Tools/Generate Bill of Materials' menu in eeschema. """
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ Tests of Internal BoM files
|
|||
- ignore_dnf = 0
|
||||
- html_generate_dnf = 0
|
||||
- use_alt = 1
|
||||
- number_rows = 0
|
||||
- COLUMN_RENAME
|
||||
- CSV
|
||||
- HTML
|
||||
|
|
@ -56,7 +55,7 @@ BOM_DIR = 'BoM'
|
|||
REF_COLUMN_NAME = 'References'
|
||||
REF_COLUMN_NAME_R = 'Referencias'
|
||||
QTY_COLUMN_NAME = 'Quantity Per PCB'
|
||||
COMP_COLUMN_NAME = 'Component'
|
||||
COMP_COLUMN_NAME = 'Row'
|
||||
COMP_COLUMN_NAME_R = 'Renglón'
|
||||
KIBOM_TEST_HEAD = [COMP_COLUMN_NAME, 'Description', 'Part', REF_COLUMN_NAME, 'Value', 'Footprint', QTY_COLUMN_NAME,
|
||||
'Datasheet', 'Config']
|
||||
|
|
@ -130,9 +129,7 @@ def test_int_bom_simple_html():
|
|||
assert len(headers) == 2
|
||||
# Test both tables has the same headings and they are the expected
|
||||
assert headers[0] == headers[1]
|
||||
head_no_comp = deepcopy(KIBOM_TEST_HEAD)
|
||||
head_no_comp[0] = '' # HTML numbered column doesn't have a name
|
||||
assert headers[0] == head_no_comp
|
||||
assert headers[0] == KIBOM_TEST_HEAD
|
||||
# Look for reference and quantity columns
|
||||
ref_column = headers[0].index(REF_COLUMN_NAME)
|
||||
qty_column = headers[0].index(QTY_COLUMN_NAME)
|
||||
|
|
@ -161,8 +158,6 @@ def test_int_bom_simple_xml():
|
|||
rows, header = ctx.load_xml(out)
|
||||
# Columns get sorted by name, so we need to take care of it
|
||||
for c in KIBOM_TEST_HEAD:
|
||||
if c == COMP_COLUMN_NAME:
|
||||
continue
|
||||
assert adapt_xml(c) in header, "Missing column "+c
|
||||
ref_column = header.index(adapt_xml(REF_COLUMN_NAME))
|
||||
qty_column = header.index(adapt_xml(QTY_COLUMN_NAME))
|
||||
|
|
@ -224,7 +219,7 @@ def test_int_bom_datasheet_link():
|
|||
assert len(headers) == 2
|
||||
# Test both tables has the same headings and they are the expected
|
||||
assert headers[0] == headers[1]
|
||||
assert headers[0] == ['', 'References', 'Part', 'Value', 'Quantity Per PCB', 'digikey#', 'manf#']
|
||||
assert headers[0] == ['References', 'Part', 'Value', 'Quantity Per PCB', 'digikey#', 'manf#']
|
||||
# Look for reference and quantity columns
|
||||
ref_column = headers[0].index(REF_COLUMN_NAME)
|
||||
part_column = headers[0].index('Part')
|
||||
|
|
@ -253,7 +248,7 @@ def test_int_bom_digikey_link():
|
|||
assert len(headers) == 2
|
||||
# Test both tables has the same headings and they are the expected
|
||||
assert headers[0] == headers[1]
|
||||
assert headers[0] == ['', 'References', 'Part', 'Value', 'Quantity Per PCB', 'digikey#', 'manf#']
|
||||
assert headers[0] == ['References', 'Part', 'Value', 'Quantity Per PCB', 'digikey#', 'manf#']
|
||||
# Look for reference and quantity columns
|
||||
ref_column = headers[0].index(REF_COLUMN_NAME)
|
||||
dk_column = headers[0].index('digikey#')
|
||||
|
|
@ -322,10 +317,7 @@ def test_int_bom_html_generate_dnf():
|
|||
# Test we got the normal and DNF tables
|
||||
assert len(rows) == 1
|
||||
assert len(headers) == 1
|
||||
# Test both tables has the same headings and they are the expected
|
||||
head_no_comp = deepcopy(KIBOM_TEST_HEAD)
|
||||
head_no_comp[0] = '' # HTML numbered column doesn't have a name
|
||||
assert headers[0] == head_no_comp
|
||||
assert headers[0] == KIBOM_TEST_HEAD
|
||||
# Look for reference and quantity columns
|
||||
ref_column = headers[0].index(REF_COLUMN_NAME)
|
||||
qty_column = headers[0].index(QTY_COLUMN_NAME)
|
||||
|
|
@ -351,7 +343,7 @@ def test_int_bom_use_alt():
|
|||
|
||||
|
||||
def test_int_bom_no_number_rows():
|
||||
""" number_rows: false """
|
||||
""" Was number_rows: false, now is different """
|
||||
prj = 'kibom-test'
|
||||
ext = 'csv'
|
||||
ctx = context.TestContextSCH('test_int_bom_no_number_rows', prj, 'int_bom_no_number_rows', BOM_DIR)
|
||||
|
|
@ -386,9 +378,7 @@ def test_int_bom_column_rename_html():
|
|||
ctx.run()
|
||||
out = prj + '-bom.' + ext
|
||||
rows, headers = ctx.load_html(out)
|
||||
head_no_comp = deepcopy(KIBOM_RENAME_HEAD)
|
||||
head_no_comp[0] = '' # HTML numbered column doesn't have a name
|
||||
assert headers[0] == head_no_comp
|
||||
assert headers[0] == KIBOM_RENAME_HEAD
|
||||
ref_column = headers[0].index(REF_COLUMN_NAME_R)
|
||||
check_kibom_test_netlist(rows[0], ref_column, LINKS_GROUPS, LINKS_EXCLUDE, LINKS_COMPONENTS)
|
||||
ctx.clean_up()
|
||||
|
|
@ -403,8 +393,6 @@ def test_int_bom_column_rename_xml():
|
|||
rows, header = ctx.load_xml(out)
|
||||
# Columns get sorted by name, so we need to take care of it
|
||||
for c in KIBOM_RENAME_HEAD:
|
||||
if c == COMP_COLUMN_NAME_R:
|
||||
continue
|
||||
assert adapt_xml(c) in header, "Missing column "+c
|
||||
ref_column = header.index(REF_COLUMN_NAME_R)
|
||||
check_kibom_test_netlist(rows, ref_column, LINKS_GROUPS, LINKS_EXCLUDE, LINKS_COMPONENTS)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ outputs:
|
|||
options:
|
||||
format: CSV
|
||||
columns:
|
||||
- field: Component
|
||||
- field: Row
|
||||
name: Renglón
|
||||
- field: References
|
||||
name: Referencias
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ outputs:
|
|||
options:
|
||||
format: HTML
|
||||
columns:
|
||||
- field: Component
|
||||
- field: Row
|
||||
name: Renglón
|
||||
- field: References
|
||||
name: Referencias
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ outputs:
|
|||
options:
|
||||
format: XLSX
|
||||
columns:
|
||||
- field: Component
|
||||
- field: Row
|
||||
name: Renglón
|
||||
- field: References
|
||||
name: Referencias
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ outputs:
|
|||
options:
|
||||
format: XML
|
||||
columns:
|
||||
- field: Component
|
||||
- field: Row
|
||||
name: Renglón
|
||||
- field: References
|
||||
name: Referencias
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ outputs:
|
|||
dir: BoM
|
||||
options:
|
||||
format: CSV
|
||||
number_rows: false
|
||||
columns:
|
||||
- references
|
||||
- value
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ outputs:
|
|||
options:
|
||||
format: CSV
|
||||
columns:
|
||||
- Row
|
||||
- References
|
||||
- Part
|
||||
- field: Value
|
||||
|
|
|
|||
|
|
@ -8,6 +8,14 @@ outputs:
|
|||
type: bom
|
||||
dir: BoM
|
||||
options:
|
||||
number_rows: false
|
||||
format: CSV
|
||||
columns:
|
||||
- Description
|
||||
- Part
|
||||
- References
|
||||
- Value
|
||||
- Footprint
|
||||
- Quantity Per PCB
|
||||
- Datasheet
|
||||
- Config
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue