Skip to content

Commit 65526cb

Browse files
committed
Add config object
1 parent 05b2fb2 commit 65526cb

File tree

6 files changed

+189
-14
lines changed

6 files changed

+189
-14
lines changed

InteractiveHtmlBom/config.py

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
"""Config object"""
2+
3+
import dialog.settings_dialog
4+
import argparse
5+
6+
7+
class Config:
8+
# Defaults
9+
10+
# HTML section
11+
dark_mode = False
12+
show_silkscreen = True
13+
highlight_pin1 = False
14+
redraw_on_drag = True
15+
board_rotation = 0
16+
checkboxes = 'Sourced,Placed'
17+
bom_view = 1
18+
layer_view = 1
19+
open_browser = True
20+
21+
# General section
22+
bom_dest_dir = './bom/' # This is relative to pcb file directory
23+
component_sort_order = [
24+
'C', 'R', 'L', 'D', 'U', 'Y', 'X', 'F', 'SW', 'A',
25+
'~',
26+
'HS', 'CNN', 'J', 'P', 'NT', 'MH',
27+
]
28+
component_blacklist = []
29+
blacklist_virtual = True
30+
31+
# Extra fields section
32+
netlist_file = None
33+
netlist_initial_directory = '' # This is relative to pcb file directory
34+
extra_fields = []
35+
board_variant_field = ''
36+
board_variants = []
37+
dnp_field = ''
38+
39+
def __init__(self):
40+
"""Init with defaults"""
41+
pass
42+
43+
def set_from_dialog(self, dlg):
44+
# type: (dialog.settings_dialog.SettingsDialog) -> None
45+
# Html
46+
self.dark_mode = dlg.html.darkModeCheckbox.IsChecked()
47+
self.show_silkscreen = dlg.html.showSilkscreenCheckbox.IsChecked()
48+
self.highlight_pin1 = dlg.html.highlightPin1Checkbox.IsChecked()
49+
self.redraw_on_drag = dlg.html.continuousRedrawCheckbox.IsChecked()
50+
self.board_rotation = dlg.html.boardRotationSlider.Value
51+
self.checkboxes = dlg.html.bomCheckboxesCtrl.Value
52+
self.bom_view = dlg.html.bomDefaultView.Selection
53+
self.layer_view = dlg.html.layerDefaultView.Selection
54+
self.open_browser = dlg.html.openBrowserCheckbox.IsChecked()
55+
56+
# General
57+
self.bom_dest_dir = dlg.general.bomDirPicker.Path
58+
self.component_sort_order = dlg.general.componentSortOrderBox.GetItems()
59+
self.component_blacklist = dlg.general.blacklistBox.GetItems()
60+
self.blacklist_virtual = \
61+
dlg.general.blacklistVirtualCheckbox.IsChecked()
62+
63+
# Extra fields
64+
self.netlist_file = dlg.extra.netlistFilePicker.Path
65+
self.extra_fields = list(dlg.extra.extraFieldsList.GetCheckedStrings())
66+
self.board_variant_field = dlg.extra.boardVariantFieldBox.Value
67+
self.board_variants = list(
68+
dlg.extra.boardVariantList.GetCheckedStrings())
69+
self.dnp_field = dlg.extra.dnpFieldBox.Value
70+
71+
def transfer_to_dialog(self, dlg):
72+
# type: (dialog.settings_dialog.SettingsDialog) -> None
73+
# Html
74+
dlg.html.darkModeCheckbox.Value = self.dark_mode
75+
dlg.html.showSilkscreenCheckbox.Value = self.show_silkscreen
76+
dlg.html.highlightPin1Checkbox.Value = self.highlight_pin1
77+
dlg.html.continuousRedrawCheckbox.value = self.redraw_on_drag
78+
dlg.html.boardRotationSlider.Value = self.board_rotation
79+
dlg.html.bomCheckboxesCtrl.Value = self.checkboxes
80+
dlg.html.bomDefaultView.Selection = self.bom_view
81+
dlg.html.layerDefaultView.Selection = self.layer_view
82+
dlg.html.openBrowserCheckbox.Value = self.open_browser
83+
84+
# General
85+
dlg.general.bomDirPicker.Path = self.bom_dest_dir
86+
dlg.general.componentSortOrderBox.SetItems(self.component_sort_order)
87+
dlg.general.blacklistBox.SetItems(self.component_blacklist)
88+
dlg.general.blacklistVirtualCheckbox.Value = self.blacklist_virtual
89+
90+
# Extra fields
91+
if self.netlist_file is not None:
92+
dlg.extra.netlistFilePicker.Path = self.netlist_file
93+
else:
94+
dlg.extra.netlistFilePicker.SetInitialDirectory(
95+
self.netlist_initial_directory)
96+
# TODO: load netlist/xml and set strings
97+
dlg.extra.extraFieldsList.SetCheckedStrings(self.extra_fields)
98+
dlg.extra.boardVariantFieldBox.Value = self.board_variant_field
99+
# TODO: load netlist/xml and set board variants
100+
dlg.extra.boardVariantList.SetCheckedStrings(self.board_variants)
101+
dlg.extra.dnpFieldBox.Value = self.dnp_field
102+
103+
# noinspection PyTypeChecker
104+
@staticmethod
105+
def add_options(parser):
106+
# type: (argparse.ArgumentParser) -> None
107+
parser.add_argument('--show-dialog', action='store_true',
108+
help='Shows config dialog. All other flags '
109+
'will be ignored.')
110+
# Html
111+
parser.add_argument('--dark-mode', help='Default to dark mode.',
112+
action='store_true')
113+
parser.add_argument('--hide-silkscreen',
114+
help='Hide silkscreen by default.',
115+
action='store_true')
116+
parser.add_argument('--highlight-pin1',
117+
help='Highlight pin1 by default.',
118+
action='store_true')
119+
parser.add_argument('--no-redraw-on-drag',
120+
help='Do not redraw pcb on drag by default.',
121+
action='store_true')
122+
parser.add_argument('--board-rotation', type=int, default=0,
123+
help='Board rotation in degrees (-180 to 180). '
124+
'Will be rounded to multiple of 5.')
125+
parser.add_argument('--checkboxes', default='Sourced,Placed',
126+
help='Comma separated list of checkbox columns.')
127+
parser.add_argument('--bom-view', default='left-right',
128+
choices=['left-right', 'top-bottom', 'bom-only'],
129+
help='Default BOM view.')
130+
parser.add_argument('--layer-view', default='FB',
131+
choices=['FB', 'F', 'B'],
132+
help='Default layer view.')
133+
parser.add_argument('--no-browser', help='Do not launch browser.',
134+
action='store_true')
135+
136+
# General
137+
parser.add_argument('--dest-dir', default='./bom/',
138+
help='Destination directory for bom file '
139+
'relative to pcb file directory.')
140+
parser.add_argument('--sort-order',
141+
help='Default sort order for components. '
142+
'Must contain "~" once.',
143+
default=','.join([
144+
'C', 'R', 'L', 'D', 'U', 'Y', 'X', 'F', 'SW',
145+
'A',
146+
'~',
147+
'HS', 'CNN', 'J', 'P', 'NT', 'MH',
148+
]))
149+
parser.add_argument('--blacklist',
150+
help='List of comma separated blacklisted '
151+
'components or prefixes with *. E.g. "X1,MH*"')
152+
parser.add_argument('--no-blacklist-virtual', action='store_true',
153+
help='Do not blacklist virtual components.')
154+
155+
# Extra fields section
156+
parser.add_argument('--netlist-file',
157+
help='Path to netlist or xml file')
158+
parser.add_argument('--extra-fields',
159+
help='Comma separated list of extra fields to '
160+
'pull from netlist or xml file.')
161+
parser.add_argument('--board-variant-field',
162+
help='Name of the extra field that stores board '
163+
'variant for component')
164+
parser.add_argument('--board-variants',
165+
help='Comma separated list of board variants to '
166+
'include in the BOM')
167+
parser.add_argument('--dnp-field',
168+
help='Name of the extra field that indicates '
169+
'do not populate status. Components with this '
170+
'field not empty will be blacklisted.')
171+
172+
def set_from_args(self, args):
173+
# type: (argparse.Namespace) -> None
174+
# TODO: implement setting config fields from parsed args
175+
pass

InteractiveHtmlBom/dialog/dialog_base.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ def __init__( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.
312312

313313
sbSizer7 = wx.StaticBoxSizer( wx.StaticBox( self, wx.ID_ANY, u"Netlist or xml file" ), wx.VERTICAL )
314314

315-
self.netlistFilePicker = wx.FilePickerCtrl( sbSizer7.GetStaticBox(), wx.ID_ANY, wx.EmptyString, u"Select a file", u"*.*", wx.DefaultPosition, wx.DefaultSize, wx.FLP_DEFAULT_STYLE|wx.FLP_FILE_MUST_EXIST|wx.FLP_OPEN|wx.FLP_SMALL|wx.BORDER_SIMPLE )
315+
self.netlistFilePicker = wx.FilePickerCtrl( sbSizer7.GetStaticBox(), wx.ID_ANY, wx.EmptyString, u"Select a file", u"Netlist and xml files (*.net; *.xml)|*.net;*.xml", wx.DefaultPosition, wx.DefaultSize, wx.FLP_DEFAULT_STYLE|wx.FLP_FILE_MUST_EXIST|wx.FLP_OPEN|wx.FLP_SMALL|wx.BORDER_SIMPLE )
316316
sbSizer7.Add( self.netlistFilePicker, 0, wx.EXPAND|wx.BOTTOM|wx.RIGHT|wx.LEFT, 5 )
317317

318318

@@ -356,7 +356,7 @@ def __init__( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.
356356
sbSizer32.Add( self.m_staticText5, 0, wx.ALL, 5 )
357357

358358
boardVariantFieldBoxChoices = []
359-
self.boardVariantFieldBox = wx.ComboBox( sbSizer32.GetStaticBox(), wx.ID_ANY, u"-None-", wx.DefaultPosition, wx.DefaultSize, boardVariantFieldBoxChoices, 0|wx.BORDER_SIMPLE )
359+
self.boardVariantFieldBox = wx.ComboBox( sbSizer32.GetStaticBox(), wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, boardVariantFieldBoxChoices, wx.CB_READONLY|wx.CB_SORT|wx.BORDER_SIMPLE )
360360
sbSizer32.Add( self.boardVariantFieldBox, 0, wx.ALL|wx.EXPAND, 5 )
361361

362362
boardVariantListChoices = []
@@ -374,7 +374,7 @@ def __init__( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.
374374
sbSizer8.Add( self.m_staticText4, 0, wx.ALL, 5 )
375375

376376
dnpFieldBoxChoices = []
377-
self.dnpFieldBox = wx.ComboBox( sbSizer8.GetStaticBox(), wx.ID_ANY, u"-None-", wx.DefaultPosition, wx.DefaultSize, dnpFieldBoxChoices, 0|wx.BORDER_NONE )
377+
self.dnpFieldBox = wx.ComboBox( sbSizer8.GetStaticBox(), wx.ID_ANY, u"-None-", wx.DefaultPosition, wx.DefaultSize, dnpFieldBoxChoices, wx.CB_READONLY|wx.CB_SORT|wx.BORDER_NONE )
378378
sbSizer8.Add( self.dnpFieldBox, 0, wx.ALL|wx.EXPAND, 5 )
379379

380380

InteractiveHtmlBom/dialog/settings_dialog.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,16 @@ def SetSizeHints(self, sz1, sz2):
3131
self.SetSizeHintsSz(sz1, sz2)
3232

3333
def OnExit(self, event):
34-
self.Close()
34+
self.EndModal(wx.ID_CANCEL)
3535

3636
def OnSaveSettings(self, event):
3737
# TODO: implement OnSaveSettings
3838
pass
3939

4040
def OnGenerateBom(self, event):
41-
# TODO: implement OnGenerateBom
41+
self.EndModal(wx.ID_OK)
42+
43+
def init(self, extra_fields_box_wildcard):
4244
pass
4345

4446

InteractiveHtmlBom/dialog_test.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import wx
21
from dialog.settings_dialog import *
32

43

54
class MyApp(wx.App):
65
def OnInit(self):
76
frame = SettingsDialog(None)
8-
frame.ShowModal()
7+
if frame.ShowModal() == wx.ID_OK:
8+
print "Should generate bom"
99
frame.Destroy()
1010
return True
1111

InteractiveHtmlBom/generate_interactive_bom.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -539,9 +539,7 @@ def Run(self):
539539

540540
parser = argparse.ArgumentParser(
541541
description='KiCad PCB pick and place assistant')
542-
parser.add_argument('file', type=str, help="KiCad PCB file")
543-
parser.add_argument('--nobrowser', help="Don't launch browser",
544-
action="store_true")
542+
parser.add_argument('file', type=str, help="KiCad PCB file", required=True)
545543
args = parser.parse_args()
546544
if not os.path.isfile(args.file):
547545
print("File %s does not exist." % args.file)

settings_dialog.fbp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3120,7 +3120,7 @@
31203120
<property name="validator_type">wxDefaultValidator</property>
31213121
<property name="validator_variable"></property>
31223122
<property name="value"></property>
3123-
<property name="wildcard">*.*</property>
3123+
<property name="wildcard">Netlist and xml files (*.net; *.xml)|*.net;*.xml</property>
31243124
<property name="window_extra_style"></property>
31253125
<property name="window_name"></property>
31263126
<property name="window_style">wxBORDER_SIMPLE</property>
@@ -3664,15 +3664,15 @@
36643664
<property name="selection">-1</property>
36653665
<property name="show">1</property>
36663666
<property name="size"></property>
3667-
<property name="style"></property>
3667+
<property name="style">wxCB_READONLY|wxCB_SORT</property>
36683668
<property name="subclass">; ; forward_declare</property>
36693669
<property name="toolbar_pane">0</property>
36703670
<property name="tooltip"></property>
36713671
<property name="validator_data_type"></property>
36723672
<property name="validator_style">wxFILTER_NONE</property>
36733673
<property name="validator_type">wxDefaultValidator</property>
36743674
<property name="validator_variable"></property>
3675-
<property name="value">-None-</property>
3675+
<property name="value"></property>
36763676
<property name="window_extra_style"></property>
36773677
<property name="window_name"></property>
36783678
<property name="window_style">wxBORDER_SIMPLE</property>
@@ -3966,7 +3966,7 @@
39663966
<property name="selection">-1</property>
39673967
<property name="show">1</property>
39683968
<property name="size"></property>
3969-
<property name="style"></property>
3969+
<property name="style">wxCB_READONLY|wxCB_SORT</property>
39703970
<property name="subclass">; ; forward_declare</property>
39713971
<property name="toolbar_pane">0</property>
39723972
<property name="tooltip"></property>

0 commit comments

Comments
 (0)