Modified og_gui_manager.py to make it accessible on devices not on the efabless platform. Changed the create project script to make the proper config directories so that the editors can be used. Modified profile.py to make the settings properly reflect the user preferences.
diff --git a/common/editparam.py b/common/editparam.py
new file mode 100755
index 0000000..30a9d06
--- /dev/null
+++ b/common/editparam.py
@@ -0,0 +1,647 @@
+#!/ef/efabless/opengalaxy/venv/bin/python3
+#
+#-----------------------------------------------------------
+# Parameter editing for the Open Galaxy characterization tool
+#-----------------------------------------------------------
+# Written by Tim Edwards
+# efabless, inc.
+# March 28, 2017
+# Version 0.1
+#--------------------------------------------------------
+
+import os
+import re
+import tkinter
+from tkinter import ttk
+
+class Condition(object):
+ def __init__(self, parent = None):
+ self.min = tkinter.StringVar(parent)
+ self.typ = tkinter.StringVar(parent)
+ self.max = tkinter.StringVar(parent)
+ self.step = tkinter.StringVar(parent)
+ self.steptype = tkinter.StringVar(parent)
+ self.unit = tkinter.StringVar(parent)
+ self.condition = tkinter.StringVar(parent)
+ self.display = tkinter.StringVar(parent)
+
+class Limit(object):
+ def __init__(self, parent = None):
+ self.target = tkinter.StringVar(parent)
+ self.penalty = tkinter.StringVar(parent)
+ self.calc = tkinter.StringVar(parent)
+ self.limit = tkinter.StringVar(parent)
+
+class EditParam(tkinter.Toplevel):
+ """Characterization tool electrical parameter editor."""
+
+ def __init__(self, parent=None, fontsize = 11, *args, **kwargs):
+ '''See the __init__ for Tkinter.Toplevel.'''
+ tkinter.Toplevel.__init__(self, parent, *args, **kwargs)
+
+ s = ttk.Style()
+ s.configure('normal.TButton', font=('Helvetica', fontsize), border = 3, relief = 'raised')
+ s.configure('bg.TFrame', background='gray40')
+ self.parent = parent
+ self.withdraw()
+ self.title('Electrical parameter editor')
+ self.sframe = tkinter.Frame(self)
+ self.sframe.grid(column = 0, row = 0, sticky = "news")
+
+ # Keep current parameter
+ self.param = None
+
+ #-------------------------------------------------------------
+ # Add the entries that are common to all electrical parameters
+
+ self.selmethod = tkinter.StringVar(self)
+ self.display = tkinter.StringVar(self)
+ self.unit = tkinter.StringVar(self)
+ self.minrec = Limit(self)
+ self.typrec = Limit(self)
+ self.maxrec = Limit(self)
+ self.cond = []
+
+ #--------------------------------------------------------
+
+ self.bbar = ttk.Frame(self)
+ self.bbar.grid(column = 0, row = 2, sticky = "news")
+
+ self.bbar.apply_button = ttk.Button(self.bbar, text='Apply',
+ command=self.apply, style = 'normal.TButton')
+ self.bbar.apply_button.grid(column=0, row=0, padx = 5)
+
+ self.bbar.close_button = ttk.Button(self.bbar, text='Close',
+ command=self.close, style = 'normal.TButton')
+ self.bbar.close_button.grid(column=1, row=0, padx = 5)
+
+ self.rowconfigure(0, weight = 1)
+ self.rowconfigure(1, weight = 0)
+ self.columnconfigure(0, weight = 1)
+
+ self.protocol("WM_DELETE_WINDOW", self.close)
+
+ def grid_configure(self, padx, pady):
+ return
+
+ def redisplay(self):
+ return
+
+ def populate(self, param):
+ # Remove all existing contents
+ for widget in self.sframe.winfo_children():
+ widget.destroy()
+
+ # Add major frames
+
+ frame1 = ttk.Frame(self.sframe)
+ frame1.grid(column = 0, row = 0, sticky = 'news')
+ frame2 = ttk.Frame(self.sframe)
+ frame2.grid(column = 0, row = 1, sticky = 'news')
+ frame3 = ttk.Frame(self.sframe)
+ frame3.grid(column = 0, row = 2, sticky = 'news')
+
+ # The Conditions area is the one that grows
+ self.sframe.rowconfigure(2, weight=1)
+ self.sframe.columnconfigure(0, weight=1)
+
+ ttk.Separator(frame3, orient='horizontal').grid(row = 0, column = 0,
+ sticky = 'news')
+
+ # The conditions list can get very big, so build out a
+ # scrolled canvas.
+
+ frame3.canvas = tkinter.Canvas(frame3)
+ frame3.canvas.grid(row = 1, column = 0, sticky = 'nswe')
+ frame3.canvas.dframe = ttk.Frame(frame3.canvas, style='bg.TFrame')
+ # Save the canvas widget, as we need to access it from places like
+ # the scrollbar callbacks.
+ self.canvas = frame3.canvas
+ # Place the frame in the canvas
+ frame3.canvas.create_window((0,0), window=frame3.canvas.dframe,
+ anchor="nw")
+ # Make sure the main window resizes, not the scrollbars.
+ frame3.rowconfigure(1, weight=1)
+ frame3.columnconfigure(0, weight = 1)
+ # X scrollbar for conditions list
+ main_xscrollbar = ttk.Scrollbar(frame3, orient = 'horizontal')
+ main_xscrollbar.grid(row = 2, column = 0, sticky = 'nswe')
+ # Y scrollbar for conditions list
+ main_yscrollbar = ttk.Scrollbar(frame3, orient = 'vertical')
+ main_yscrollbar.grid(row = 1, column = 1, sticky = 'nswe')
+ # Attach console to scrollbars
+ frame3.canvas.config(xscrollcommand = main_xscrollbar.set)
+ main_xscrollbar.config(command = frame3.canvas.xview)
+ frame3.canvas.config(yscrollcommand = main_yscrollbar.set)
+ main_yscrollbar.config(command = frame3.canvas.yview)
+
+ # Make sure that scrollwheel pans the window
+ frame3.canvas.bind_all("<Button-4>", self.on_mousewheel)
+ frame3.canvas.bind_all("<Button-5>", self.on_mousewheel)
+
+ # Set up configure callback
+ frame3.canvas.dframe.bind("<Configure>", self.frame_configure)
+
+ # Get list of methods from testbench folder
+ dspath = os.path.split(self.parent.cur_datasheet)[0]
+ tbpath = dspath + '/testbench'
+ tbfiles = os.listdir(tbpath)
+ methods = []
+ for spifile in tbfiles:
+ if os.path.splitext(spifile)[1] == '.spi':
+ methods.append(os.path.splitext(spifile)[0].upper())
+
+ # Get list of pins from parent datasheet
+ dsheet = self.parent.datatop['data-sheet']
+ pins = dsheet['pins']
+ pinlist = []
+ for pin in pins:
+ pinlist.append(pin['name'])
+ pinlist.append('(none)')
+
+ # Add common elements
+ frame1.ldisplay = ttk.Label(frame1, text='Description:',
+ style= 'blue.TLabel', anchor = 'e')
+ frame1.lmethod = ttk.Label(frame1, text='Method:',
+ style= 'blue.TLabel', anchor = 'e')
+ frame1.lunit = ttk.Label(frame1, text='Unit:',
+ style= 'blue.TLabel', anchor = 'e')
+
+ # If 'pin' exists (old style), append it to 'condition' and remove.
+ if 'pin' in param:
+ if 'method' in param and ':' not in param['method']:
+ param['method'] += ':' + param['pin']
+ param.pop('pin', 0)
+
+ # Find method and apply to OptionMenu
+ if 'method' in param:
+ self.selmethod.set(param['method'])
+ else:
+ self.selmethod.set('(none)')
+
+
+ frame1.display = ttk.Entry(frame1, textvariable = self.display)
+ frame1.method = ttk.OptionMenu(frame1, self.selmethod, self.selmethod.get(), *methods)
+ frame1.unit = ttk.Entry(frame1, textvariable = self.unit)
+
+ frame1.ldisplay.grid(column = 0, row = 0, sticky = 'news', padx=5, pady=5)
+ frame1.display.grid(column = 1, row = 0, sticky = 'news', padx=5, pady=3)
+ frame1.lmethod.grid(column = 0, row = 1, sticky = 'news', padx=5, pady=5)
+ frame1.method.grid(column = 1, row = 1, sticky = 'news', padx=5, pady=3)
+ frame1.lunit.grid(column = 0, row = 2, sticky = 'news', padx=5, pady=5)
+ frame1.unit.grid(column = 1, row = 2, sticky = 'news', padx=5, pady=3)
+
+ frame1.columnconfigure(0, weight = 0)
+ frame1.columnconfigure(1, weight = 1)
+
+ frame1.display.delete(0, 'end')
+ if 'display' in param:
+ frame1.display.insert(0, param['display'])
+ else:
+ frame1.display.insert(0, '(none)')
+
+ frame1.unit.delete(0, 'end')
+ if 'unit' in param:
+ frame1.unit.insert(0, param['unit'])
+ else:
+ frame1.unit.insert(0, '(none)')
+
+ ttk.Separator(frame1, orient='horizontal').grid(row = 4, column = 0,
+ columnspan = 2, sticky = 'nsew')
+
+ # Calculation types
+ calctypes = ["min", "max", "avg", "diffmin", "diffmax", "(none)"]
+ limittypes = ["above", "below", "exact", "legacy", "(none)"]
+
+ # Add min/typ/max (To-do: Add plot)
+
+ frame2min = ttk.Frame(frame2, borderwidth = 2, relief='groove')
+ frame2min.grid(row = 0, column = 0, padx = 2, pady = 2, sticky = 'news')
+ ttk.Label(frame2min, text="Minimum:", style = 'blue.TLabel',
+ anchor = 'w').grid(row = 0, column = 0, padx = 5,
+ sticky = 'news')
+ if 'min' in param:
+ minrec = param['min']
+ else:
+ minrec = {}
+ ttk.Label(frame2min, text="Target:", anchor = 'e',
+ style = 'normal.TLabel').grid(row = 1, column = 0, padx = 5,
+ sticky = 'news')
+ frame2min.tmin = ttk.Entry(frame2min, textvariable = self.minrec.target)
+ frame2min.tmin.grid(row = 1, column = 1, padx = 5, sticky = 'news')
+ frame2min.tmin.delete(0, 'end')
+ if 'target' in minrec:
+ frame2min.tmin.insert(0, minrec['target'])
+ ttk.Label(frame2min, text="Penalty:", anchor = 'e',
+ style = 'normal.TLabel').grid(row = 2, column = 0, padx = 5,
+ sticky = 'news')
+ frame2min.pmin = ttk.Entry(frame2min, textvariable = self.minrec.penalty)
+ frame2min.pmin.grid(row = 2, column = 1, padx = 5, sticky = 'news')
+ frame2min.pmin.delete(0, 'end')
+ if 'penalty' in minrec:
+ frame2min.pmin.insert(0, minrec['penalty'])
+ if 'calc' in minrec:
+ calcrec = minrec['calc']
+ try:
+ calctype, limittype = calcrec.split('-')
+ except ValueError:
+ calctype = calcrec
+ if calctype == 'min':
+ limittype = 'above'
+ elif calctype == 'max':
+ limittype = 'below'
+ elif calctype == 'avg':
+ limittype = 'exact'
+ elif calctype == 'diffmin':
+ limittype = 'above'
+ elif calctype == 'diffmax':
+ limittype = 'below'
+ else:
+ limittype = '(none)'
+ else:
+ calctype = 'min'
+ limittype = 'above'
+
+ ttk.Label(frame2min, text="Calculation:", anchor = 'e',
+ style = 'normal.TLabel').grid(row = 3, column = 0, padx = 5,
+ sticky = 'news')
+ self.cmin = tkinter.StringVar(self)
+ self.cmin.set(calctype)
+ frame2min.cmin = ttk.OptionMenu(frame2min, self.cmin, calctype, *calctypes)
+ frame2min.cmin.grid(row = 3, column = 1, padx = 5, sticky = 'news')
+ ttk.Label(frame2min, text="Limit:", anchor = 'e',
+ style = 'normal.TLabel').grid(row = 4, column = 0, padx = 5,
+ sticky = 'news')
+ self.lmin = tkinter.StringVar(self)
+ self.lmin.set(limittype)
+ frame2min.lmin = ttk.OptionMenu(frame2min, self.lmin, limittype, *limittypes)
+ frame2min.lmin.grid(row = 4, column = 1, padx = 5, sticky = 'news')
+
+ frame2typ = ttk.Frame(frame2, borderwidth = 2, relief='groove')
+ frame2typ.grid(row = 0, column = 1, padx = 2, pady = 2, sticky = 'news')
+ ttk.Label(frame2typ, text="Typical:", style = 'blue.TLabel',
+ anchor = 'w').grid(row = 0, column = 0, padx = 5,
+ sticky = 'news')
+ if 'typ' in param:
+ typrec = param['typ']
+ else:
+ typrec = {}
+ ttk.Label(frame2typ, text="Target:", anchor = 'e',
+ style = 'normal.TLabel').grid(row = 1, column = 0, padx = 5,
+ sticky = 'news')
+ frame2typ.ttyp = ttk.Entry(frame2typ, textvariable = self.typrec.target)
+ frame2typ.ttyp.grid(row = 1, column = 1, padx = 5, sticky = 'news')
+ frame2typ.ttyp.delete(0, 'end')
+ if 'target' in typrec:
+ frame2typ.ttyp.insert(0, typrec['target'])
+ ttk.Label(frame2typ, text="Penalty:", anchor = 'e',
+ style = 'normal.TLabel').grid(row = 2, column = 0, padx = 5,
+ sticky = 'news')
+ frame2typ.ptyp = ttk.Entry(frame2typ, textvariable = self.typrec.penalty)
+ frame2typ.ptyp.grid(row = 2, column = 1, padx = 5, sticky = 'news')
+ frame2typ.ptyp.delete(0, 'end')
+ if 'penalty' in typrec:
+ frame2typ.ptyp.insert(0, typrec['penalty'])
+ if 'calc' in typrec:
+ calcrec = typrec['calc']
+ try:
+ calctype, limittype = calcrec.split('-')
+ except ValueError:
+ calctype = calcrec
+ if calctype == 'min':
+ limittype = 'above'
+ elif calctype == 'max':
+ limittype = 'below'
+ elif calctype == 'avg':
+ limittype = 'exact'
+ elif calctype == 'diffmin':
+ limittype = 'above'
+ elif calctype == 'diffmax':
+ limittype = 'below'
+ else:
+ limittype = '(none)'
+ else:
+ calctype = 'avg'
+ limittype = 'exact'
+
+ ttk.Label(frame2typ, text="Calculation:", anchor = 'e',
+ style = 'normal.TLabel').grid(row = 3, column = 0, padx = 5,
+ sticky = 'news')
+ self.ctyp = tkinter.StringVar(self)
+ self.ctyp.set(calctype)
+ frame2typ.ctyp = ttk.OptionMenu(frame2typ, self.ctyp, calctype, *calctypes)
+ frame2typ.ctyp.grid(row = 3, column = 1, padx = 5, sticky = 'news')
+ ttk.Label(frame2typ, text="Limit:", anchor = 'e',
+ style = 'normal.TLabel').grid(row = 4, column = 0, padx = 5,
+ sticky = 'news')
+ self.ltyp = tkinter.StringVar(self)
+ self.ltyp.set(limittype)
+ frame2typ.ltyp = ttk.OptionMenu(frame2typ, self.ltyp, limittype, *limittypes)
+ frame2typ.ltyp.grid(row = 4, column = 1, padx = 5, sticky = 'news')
+
+ frame2max = ttk.Frame(frame2, borderwidth = 2, relief='groove')
+ frame2max.grid(row = 0, column = 2, padx = 2, pady = 2, sticky = 'news')
+ ttk.Label(frame2max, text="Maximum:", style = 'blue.TLabel',
+ anchor = 'w').grid(row = 0, column = 0, padx = 5,
+ sticky = 'news')
+ if 'max' in param:
+ maxrec = param['max']
+ else:
+ maxrec = {}
+ ttk.Label(frame2max, text="Target:", anchor = 'e',
+ style = 'normal.TLabel').grid(row = 1, column = 0, padx = 5,
+ sticky = 'news')
+ frame2max.tmax = ttk.Entry(frame2max, textvariable = self.maxrec.target)
+ frame2max.tmax.grid(row = 1, column = 1, padx = 5, sticky = 'news')
+ frame2max.tmax.delete(0, 'end')
+ if 'target' in maxrec:
+ frame2max.tmax.insert(0, maxrec['target'])
+ ttk.Label(frame2max, text="Penalty:", anchor = 'e',
+ style = 'normal.TLabel').grid(row = 2, column = 0, padx = 5,
+ sticky = 'news')
+ frame2max.pmax = ttk.Entry(frame2max, textvariable = self.maxrec.penalty)
+ frame2max.pmax.grid(row = 2, column = 1, padx = 5, sticky = 'news')
+ frame2max.pmax.delete(0, 'end')
+ if 'penalty' in maxrec:
+ frame2max.pmax.insert(0, maxrec['penalty'])
+ if 'calc' in maxrec:
+ calcrec = maxrec['calc']
+ try:
+ calctype, limittype = calcrec.split('-')
+ except ValueError:
+ calctype = calcrec
+ if calctype == 'min':
+ limittype = 'above'
+ elif calctype == 'max':
+ limittype = 'below'
+ elif calctype == 'avg':
+ limittype = 'exact'
+ elif calctype == 'diffmin':
+ limittype = 'above'
+ elif calctype == 'diffmax':
+ limittype = 'below'
+ else:
+ limittype = '(none)'
+ else:
+ calctype = 'max'
+ limittype = 'below'
+
+ ttk.Label(frame2max, text="Calculation:", anchor = 'e',
+ style = 'normal.TLabel').grid(row = 3, column = 0, padx = 5,
+ sticky = 'news')
+ self.cmax = tkinter.StringVar(self)
+ self.cmax.set(calctype)
+ frame2max.cmax = ttk.OptionMenu(frame2max, self.cmax, calctype, *calctypes)
+ frame2max.cmax.grid(row = 3, column = 1, padx = 5, sticky = 'news')
+ ttk.Label(frame2max, text="Limit:", anchor = 'e',
+ style = 'normal.TLabel').grid(row = 4, column = 0, padx = 5,
+ sticky = 'news')
+ self.lmax = tkinter.StringVar(self)
+ self.lmax.set(limittype)
+ frame2max.lmax = ttk.OptionMenu(frame2max, self.lmax, limittype, *limittypes)
+ frame2max.lmax.grid(row = 4, column = 1, padx = 5, sticky = 'news')
+
+ dframe = frame3.canvas.dframe
+
+ ttk.Label(dframe, text="Conditions:", style = 'blue.TLabel',
+ anchor='w').grid(row = 0, column = 0, padx = 5, sticky = 'news', columnspan = 5)
+
+ # Add conditions
+
+ condtypes = ["VOLTAGE", "DIGITAL", "CURRENT", "RISETIME", "FALLTIME",
+ "RESISTANCE", "CAPACITANCE", "TEMPERATURE", "FREQUENCY",
+ "CORNER", "SIGMA", "ITERATIONS", "(none)"]
+
+ steptypes = ['linear', 'log', '(none)']
+
+ n = 0
+ r = 1
+ self.crec = []
+ self.cond = []
+ for cond in param['conditions']:
+ # If over 5 columns of conditions, create a new row.
+ if n >= 5:
+ r += 1
+ n = 0
+ # New column
+ frame3c = ttk.Frame(dframe, borderwidth = 2, relief='groove')
+ frame3c.grid(row = r, column = n, padx = 2, pady = 2, sticky = 'news')
+
+ crec = Condition(self)
+ # Condition description
+ ttk.Label(frame3c, text='Description:', style='normal.TLabel',
+ anchor='e').grid(row = 0, column = 0, padx = 5, sticky = 'news')
+ c1 = ttk.Entry(frame3c, textvariable = crec.display)
+ c1.grid(row = 0, column = 1, padx = 5, sticky = 'news')
+ c1.delete(0, 'end')
+ if 'display' in cond:
+ c1.insert(0, cond['display'])
+ else:
+ c1.insert(0, '(none)')
+ # Condition type (pulldown menu)
+ if 'condition' in cond:
+ crec.condition.set(cond['condition'])
+ else:
+ crec.condition.set('(none)')
+ ttk.Label(frame3c, text='Condition:', style='normal.TLabel',
+ anchor='e').grid(row = 1, column = 0, padx = 5, sticky = 'news')
+ c2 = ttk.OptionMenu(frame3c, crec.condition, crec.condition.get(), *condtypes)
+ c2.grid(row = 1, column = 1, padx = 5, sticky = 'news')
+ # Condition unit
+ ttk.Label(frame3c, text='Unit:', style='normal.TLabel',
+ anchor='e').grid(row = 3, column = 0, padx = 5, sticky = 'news')
+ c4 = ttk.Entry(frame3c, textvariable = crec.unit)
+ c4.grid(row = 3, column = 1, padx = 5, sticky = 'news')
+ c4.delete(0, 'end')
+ if 'unit' in cond:
+ c4.insert(0, cond['unit'])
+ else:
+ c4.insert(0, '(none)')
+ # Condition min
+ ttk.Label(frame3c, text='Minimum:', style='normal.TLabel',
+ anchor='e').grid(row = 4, column = 0, padx = 5, sticky = 'news')
+ c5 = ttk.Entry(frame3c, textvariable = crec.min)
+ c5.grid(row = 4, column = 1, padx = 5, sticky = 'news')
+ c5.delete(0, 'end')
+ if 'min' in cond:
+ c5.insert(0, cond['min'])
+ else:
+ c5.insert(0, '(none)')
+ # Condition typ
+ ttk.Label(frame3c, text='Typical:', style='normal.TLabel',
+ anchor='e').grid(row = 5, column = 0, padx = 5, sticky = 'news')
+ c6 = ttk.Entry(frame3c, textvariable = crec.typ)
+ c6.grid(row = 5, column = 1, padx = 5, sticky = 'news')
+ c6.delete(0, 'end')
+ if 'typ' in cond:
+ c6.insert(0, cond['typ'])
+ else:
+ c6.insert(0, '(none)')
+ # Condition max
+ ttk.Label(frame3c, text='Maximum:', style='normal.TLabel',
+ anchor='e').grid(row = 6, column = 0, padx = 5, sticky = 'news')
+ c7 = ttk.Entry(frame3c, textvariable = crec.max)
+ c7.grid(row = 6, column = 1, padx = 5, sticky = 'news')
+ c7.delete(0, 'end')
+ if 'max' in cond:
+ c7.insert(0, cond['max'])
+ else:
+ c7.insert(0, '(none)')
+ # Condition steptype
+ ttk.Label(frame3c, text='Step type:', style='normal.TLabel',
+ anchor='e').grid(row = 7, column = 0, padx = 5, sticky = 'news')
+ c8 = ttk.OptionMenu(frame3c, crec.steptype, crec.steptype.get(), *steptypes)
+ c8.grid(row = 7, column = 1, padx = 5, sticky = 'news')
+ if 'linstep' in cond:
+ crec.steptype.set('linear')
+ elif 'logstep' in cond:
+ crec.steptype.set('log')
+ else:
+ crec.steptype.set('(none)')
+ # Condition step
+ ttk.Label(frame3c, text='Step:', style='normal.TLabel',
+ anchor='e').grid(row = 8, column = 0, padx = 5, sticky = 'news')
+ c9 = ttk.Entry(frame3c, textvariable = crec.step)
+ c9.grid(row = 8, column = 1, padx = 5, sticky = 'news')
+ c9.delete(0, 'end')
+ if 'linstep' in cond:
+ c9.insert(0, cond['linstep'])
+ elif 'logstep' in cond:
+ c9.insert(0, cond['logstep'])
+ else:
+ c9.insert(0, '(none)')
+
+ n += 1
+ self.cond.append(crec)
+ # Condition remove
+ c10 = ttk.Button(frame3c, text='Remove', style='normal.TButton',
+ command = lambda cond=cond: self.remove_condition(cond))
+ c10.grid(row = 9, column = 1, padx = 5, sticky = 'news')
+
+ # Add 'add condition' button
+ dframe.bcond = ttk.Button(dframe, text="Add Condition",
+ style = 'blue.TButton', command = self.add_condition)
+ if n >= 5:
+ dframe.bcond.grid(row = r + 1, column = 0, padx = 5, pady = 3, sticky = 'nsw')
+ else:
+ dframe.bcond.grid(row = r, column = n, padx = 5, pady = 3, sticky = 'new')
+
+ # Set the current parameter
+ self.param = param
+
+ def on_mousewheel(self, event):
+ if event.num == 5:
+ self.canvas.yview_scroll(1, "units")
+ elif event.num == 4:
+ self.canvas.yview_scroll(-1, "units")
+
+ def frame_configure(self, event):
+ self.update_idletasks()
+ self.canvas.configure(scrollregion=self.canvas.bbox("all"))
+
+ def add_condition(self):
+ # Add a new condition
+ newcond = {}
+ newcond['condition'] = '(none)'
+ self.param['conditions'].append(newcond)
+ self.populate(self.param)
+
+ def remove_condition(self, cond):
+ # Remove and existing condition
+ condlist = self.param['conditions']
+ eidx = condlist.index(cond)
+ condlist.pop(eidx)
+ self.populate(self.param)
+
+ def apply(self):
+ # Apply the values back to the parameter record
+ self.param['method'] = self.selmethod.get()
+ unit = self.unit.get()
+ if not (unit == '(none)' or unit == ''):
+ self.param['unit'] = unit
+ display = self.display.get()
+ if not (display == '(none)' or display == ''):
+ self.param['display'] = display
+ targmin = self.minrec.target.get()
+ if not (targmin == '(none)' or targmin == ''):
+ pmin = {}
+ pmin['target'] = targmin
+ pmin['penalty'] = self.minrec.penalty.get()
+ cmin = self.minrec.calc.get()
+ if not (cmin == '(none)' or cmin == ''):
+ lmin = self.minrec.limit.get()
+ if not (lmin == '(none)' or lmin == ''):
+ pmin['calc'] = cmin + '-' + lmin
+ else:
+ pmin['calc'] = cmin
+ self.param['min'] = pmin
+ targtyp = self.typrec.target.get()
+ if not (targtyp == '(none)' or targtyp == ''):
+ ptyp= {}
+ ptyp['target'] = targtyp
+ ptyp['penalty'] = self.typrec.penalty.get()
+ ctyp = self.typrec.calc.get()
+ if not (ctyp == '(none)' or ctyp == ''):
+ ltyp = self.typrec.limit.get()
+ if not (ltyp == '(none)' or ltyp == ''):
+ ptyp['calc'] = ctyp + '-' + ltyp
+ else:
+ ptyp['calc'] = ctyp
+ self.param['typ'] = ptyp
+ targmax = self.maxrec.target.get()
+ if not (targmax == '(none)' or targmax == ''):
+ pmax= {}
+ pmax['target'] = targmax
+ pmax['penalty'] = self.maxrec.penalty.get()
+ cmax = self.maxrec.calc.get()
+ if not (cmax == '(none)' or cmax == ''):
+ lmax = self.maxrec.limit.get()
+ if not (lmax == '(none)' or lmax == ''):
+ pmax['calc'] = cmax + '-' + lmax
+ else:
+ pmax['calc'] = cmax
+ self.param['max'] = pmax
+
+ condlist = []
+ for crec in self.cond:
+ cond = {}
+ cname = crec.condition.get()
+ if cname == '(none)' or cname == '':
+ continue
+ cond['condition'] = cname
+ display = crec.display.get()
+ if not (display == '(none)' or display == ''):
+ cond['display'] = display
+ min = crec.min.get()
+ if not (min == '(none)' or min == ''):
+ cond['min'] = min
+ typ = crec.typ.get()
+ if not (typ == '(none)' or typ == ''):
+ cond['typ'] = typ
+ max = crec.max.get()
+ if not (max == '(none)' or max == ''):
+ cond['max'] = max
+ unit = crec.unit.get()
+ if not (unit == '(none)' or unit == ''):
+ cond['unit'] = unit
+ steptype = crec.steptype.get()
+ step = crec.step.get()
+ if not (step == '(none)' or step == ''):
+ if steptype == 'linear':
+ cond['linstep'] = step
+ elif steptype == 'log':
+ cond['logstep'] = step
+ condlist.append(cond)
+ self.param['conditions'] = condlist
+
+ self.parent.create_datasheet_view()
+ return
+
+ def close(self):
+ # pop down settings window
+ self.withdraw()
+
+ def open(self):
+ # pop up settings window
+ self.deiconify()
+ self.lift()