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:
Salvador E. Tropea 2020-08-01 18:31:26 -03:00
parent 64576e3975
commit 5be7254594
14 changed files with 47 additions and 73 deletions

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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:

View File

@ -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)

View File

@ -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__()

View File

@ -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)

View File

@ -10,7 +10,7 @@ outputs:
options:
format: CSV
columns:
- field: Component
- field: Row
name: Renglón
- field: References
name: Referencias

View File

@ -10,7 +10,7 @@ outputs:
options:
format: HTML
columns:
- field: Component
- field: Row
name: Renglón
- field: References
name: Referencias

View File

@ -10,7 +10,7 @@ outputs:
options:
format: XLSX
columns:
- field: Component
- field: Row
name: Renglón
- field: References
name: Referencias

View File

@ -10,7 +10,7 @@ outputs:
options:
format: XML
columns:
- field: Component
- field: Row
name: Renglón
- field: References
name: Referencias

View File

@ -9,7 +9,6 @@ outputs:
dir: BoM
options:
format: CSV
number_rows: false
columns:
- references
- value

View File

@ -10,6 +10,7 @@ outputs:
options:
format: CSV
columns:
- Row
- References
- Part
- field: Value

View File

@ -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