654 lines
26 KiB
Python
Executable File
654 lines
26 KiB
Python
Executable File
#!/bin/env python3
|
|
#
|
|
# Simple ttk treeview with split view, scrollbar, and
|
|
# row of callback buttons
|
|
|
|
import os
|
|
import re
|
|
import itertools
|
|
|
|
import tkinter
|
|
from tkinter import ttk
|
|
|
|
#------------------------------------------------------
|
|
# Tree view used as a multi-column list box
|
|
#------------------------------------------------------
|
|
|
|
class TreeViewSplit(ttk.Frame):
|
|
def __init__(self, parent, fontsize=11, *args, **kwargs):
|
|
ttk.Frame.__init__(self, parent, *args, **kwargs)
|
|
s = ttk.Style()
|
|
s.configure('normal.TLabel', font=('Helvetica', fontsize))
|
|
s.configure('title.TLabel', font=('Helvetica', fontsize, 'bold'))
|
|
s.configure('normal.TButton', font=('Helvetica', fontsize),
|
|
border = 3, relief = 'raised')
|
|
s.configure('Treeview.Heading', font=('Helvetica', fontsize, 'bold'))
|
|
s.configure('Treeview.Column', font=('Helvetica', fontsize))
|
|
self.fontsize = fontsize
|
|
|
|
# Last item is a list of 2-item lists, each containing the name of a button
|
|
# to place along the button bar at the bottom, and a callback function to
|
|
# run when the button is pressed.
|
|
|
|
def populate(self, title1="", item1list=[], title2="", item2list=[], buttons=[], height=10):
|
|
self.item1list = item1list[:]
|
|
self.item2list = item2list[:]
|
|
columns = [0, 1]
|
|
|
|
treeFrame = ttk.Frame(self)
|
|
treeFrame.pack(side='top', padx=5, pady=5, fill='both', expand='true')
|
|
|
|
scrollBar = ttk.Scrollbar(treeFrame)
|
|
scrollBar.pack(side='right', fill='y')
|
|
self.treeView = ttk.Treeview(treeFrame, selectmode='browse', columns=columns, height=height)
|
|
self.treeView.pack(side='left', fill='both', expand='true')
|
|
scrollBar.config(command=self.treeView.yview)
|
|
self.treeView.config(yscrollcommand=scrollBar.set)
|
|
self.treeView.column('#0', width=120, stretch='false')
|
|
self.treeView.heading(0, text=title1, anchor='w')
|
|
self.treeView.heading(1, text=title2, anchor='w')
|
|
buttonFrame = ttk.Frame(self)
|
|
buttonFrame.pack(side='bottom', fill='x')
|
|
|
|
self.treeView.tag_configure('select',background='darkslategray',foreground='white')
|
|
|
|
# Test type tags
|
|
self.treeView.tag_configure('error', font=('Helvetica', self.fontsize - 1), foreground = 'red')
|
|
self.treeView.tag_configure('clean', font=('Helvetica', self.fontsize - 1), foreground = 'green3')
|
|
self.treeView.tag_configure('normal', font=('Helvetica', self.fontsize - 1), foreground = 'black')
|
|
self.treeView.tag_configure('prep', font=('Helvetica', self.fontsize, 'bold italic'),
|
|
foreground = 'black', anchor = 'center')
|
|
self.treeView.tag_configure('header1', font=('Helvetica', self.fontsize, 'bold italic'),
|
|
foreground = 'brown', anchor = 'center')
|
|
self.treeView.tag_configure('header2', font=('Helvetica', self.fontsize - 1, 'bold'),
|
|
foreground = 'blue', anchor = 'center')
|
|
self.treeView.tag_configure('header3', font=('Helvetica', self.fontsize - 1, 'italic'),
|
|
foreground = 'green4', anchor = 'center')
|
|
self.treeView.tag_configure('header4', font=('Helvetica', self.fontsize - 1),
|
|
foreground = 'purple', anchor = 'center')
|
|
|
|
|
|
self.func_buttons = []
|
|
for button in buttons:
|
|
func = button[2]
|
|
# Each func_buttons entry is a list of two items; first is the
|
|
# button widget, and the second is a boolean that is True if the
|
|
# button is to be present always, False if the button is only
|
|
# present when there are entries in the itemlists.
|
|
self.func_buttons.append([ttk.Button(buttonFrame, text=button[0],
|
|
style = 'normal.TButton',
|
|
command = lambda func=func: self.func_callback(func)),
|
|
button[1]])
|
|
|
|
self.selectcallback = None
|
|
self.lastselected = None
|
|
self.lasttag = None
|
|
self.repopulate(item1list, item2list)
|
|
|
|
def get_button(self, index):
|
|
if index >= 0 and index < len(self.func_buttons):
|
|
return self.func_buttons[index][0]
|
|
else:
|
|
return None
|
|
|
|
def set_title(self, title):
|
|
self.treeView.heading('#0', text=title, anchor='w')
|
|
|
|
def repopulate(self, item1list=[], item2list=[]):
|
|
|
|
# Remove all children of treeview
|
|
self.treeView.delete(*self.treeView.get_children())
|
|
|
|
self.item1list = item1list[:]
|
|
self.item2list = item2list[:]
|
|
lines = max(len(self.item1list), len(self.item2list))
|
|
|
|
# Parse the information coming from comp.out. This is preferably
|
|
# handled from inside netgen, but that requires development in netgen.
|
|
# Note: A top-level group is denoted by an empty string.
|
|
|
|
nested = ['']
|
|
if lines > 0:
|
|
# print("Create item ID 0 parent = ''")
|
|
self.treeView.insert(nested[-1], 'end', text='-', iid='0',
|
|
value=['Initialize', 'Initialize'], tags=['prep'])
|
|
nested.append('0')
|
|
tagstyle = 'header1'
|
|
|
|
emptyrec = re.compile('^[\t ]*$')
|
|
subrex = re.compile('Subcircuit summary')
|
|
cktrex = re.compile('Circuit[\t ]+[12]:[\t ]+([^ \t]+)')
|
|
netrex = re.compile('NET mismatches')
|
|
devrex = re.compile('DEVICE mismatches')
|
|
seprex = re.compile('-----')
|
|
sumrex = re.compile('Netlists ')
|
|
matchrex = re.compile('.*\*\*Mismatch\*\*')
|
|
incircuit = False
|
|
watchgroup = False
|
|
groupnum = 0
|
|
|
|
for item1, item2, index in zip(self.item1list, self.item2list, range(lines)):
|
|
cname1 = 'Layout' # Placeholder
|
|
cname2 = 'Schematic' # Placeholder
|
|
|
|
# Remove blank lines from the display
|
|
lmatch = emptyrec.match(item1)
|
|
if lmatch:
|
|
lmatch = emptyrec.match(item2)
|
|
if lmatch:
|
|
continue
|
|
index = str(index + 1)
|
|
# Parse text to determine how to structure and display it.
|
|
tagstyle = 'normal'
|
|
nextnest = None
|
|
lmatch = subrex.match(item1)
|
|
if lmatch:
|
|
nested = [''] # pop back to topmost level
|
|
nextnest = index
|
|
tagstyle = 'header1'
|
|
incircuit = False
|
|
watchgroup = False
|
|
groupnum = 0
|
|
item1 = 'Layout compare'
|
|
item2 = 'Schematic compare'
|
|
else:
|
|
lmatch = cktrex.match(item1)
|
|
if lmatch and not incircuit:
|
|
# Pick up circuit names and replace them in the title, then use them
|
|
# for all following titles.
|
|
cname1 = lmatch.group(1)
|
|
lmatch = cktrex.match(item2)
|
|
cname2 = lmatch.group(1)
|
|
print("Circuit names " + cname1 + " " + cname2)
|
|
# Rewrite title
|
|
cktitem = self.treeView.item(nested[-1], values=[cname1 + ' compare',
|
|
cname2 + ' compare'])
|
|
nextnest = index
|
|
tagstyle = 'header2'
|
|
incircuit = True
|
|
item1 = cname1 + ' Summary'
|
|
item2 = cname2 + ' Summary'
|
|
elif lmatch:
|
|
continue
|
|
else:
|
|
lmatch = netrex.match(item1)
|
|
if lmatch:
|
|
if watchgroup:
|
|
nested = nested[0:-1]
|
|
nested = nested[0:-1]
|
|
nextnest = index
|
|
tagstyle = 'header2'
|
|
groupnum = 1
|
|
watchgroup = True
|
|
item1 = cname1 + ' Net mismatches'
|
|
item2 = cname2 + ' Net mismatches'
|
|
else:
|
|
lmatch = devrex.match(item1)
|
|
if lmatch:
|
|
if watchgroup:
|
|
nested = nested[0:-1]
|
|
nested = nested[0:-1]
|
|
nextnest = index
|
|
tagstyle = 'header2'
|
|
groupnum = 1
|
|
watchgroup = True
|
|
item1 = cname1 + ' Device mismatches'
|
|
item2 = cname2 + ' Device mismatches'
|
|
else:
|
|
lmatch = seprex.match(item1)
|
|
if lmatch:
|
|
if watchgroup:
|
|
tagstyle = 'header3'
|
|
item1 = 'Group ' + str(groupnum)
|
|
item2 = 'Group ' + str(groupnum)
|
|
if groupnum > 1:
|
|
nested = nested[0:-1]
|
|
groupnum += 1
|
|
nextnest = index
|
|
watchgroup = False
|
|
else:
|
|
if groupnum > 0:
|
|
watchgroup = True
|
|
continue
|
|
else:
|
|
lmatch = sumrex.match(item1)
|
|
if lmatch:
|
|
if watchgroup:
|
|
nested = nested[0:-1]
|
|
nested = nested[0:-1]
|
|
watchgroup = False
|
|
tagstyle = 'header2'
|
|
groupnum = 0
|
|
|
|
lmatch1 = matchrex.match(item1)
|
|
lmatch2 = matchrex.match(item2)
|
|
if lmatch1 or lmatch2:
|
|
tagstyle='error'
|
|
|
|
# print("Create item ID " + str(index) + " parent = " + str(nested[-1]))
|
|
self.treeView.insert(nested[-1], 'end', text=index, iid=index, value=[item1, item2],
|
|
tags=[tagstyle])
|
|
|
|
if nextnest:
|
|
nested.append(nextnest)
|
|
|
|
for button in self.func_buttons:
|
|
button[0].pack_forget()
|
|
|
|
if lines == 0:
|
|
self.treeView.insert('', 'end', text='-', value=['(no items)', '(no items)'])
|
|
for button in self.func_buttons:
|
|
if button[1]:
|
|
button[0].pack(side='left', padx = 5)
|
|
else:
|
|
for button in self.func_buttons:
|
|
button[0].pack(side='left', padx = 5)
|
|
|
|
# Special routine to pull in the JSON file data produced by netgen-1.5.72
|
|
def json_repopulate(self, lvsdata):
|
|
|
|
# Remove all children of treeview
|
|
self.treeView.delete(*self.treeView.get_children())
|
|
|
|
# Parse the information coming from comp.out. This is preferably
|
|
# handled from inside netgen, but that requires development in netgen.
|
|
# Note: A top-level group is denoted by an empty string.
|
|
|
|
index = 0
|
|
errtotal = {}
|
|
errtotal['net'] = 0
|
|
errtotal['netmatch'] = 0
|
|
errtotal['device'] = 0
|
|
errtotal['devmatch'] = 0
|
|
errtotal['property'] = 0
|
|
errtotal['pin'] = 0
|
|
ncells = len(lvsdata)
|
|
for c in range(0, ncells):
|
|
cellrec = lvsdata[c]
|
|
if c == ncells - 1:
|
|
topcell = True
|
|
else:
|
|
topcell = False
|
|
|
|
errcell = {}
|
|
errcell['net'] = 0
|
|
errcell['netmatch'] = 0
|
|
errcell['device'] = 0
|
|
errcell['devmatch'] = 0
|
|
errcell['property'] = 0
|
|
errcell['pin'] = 0;
|
|
|
|
cname1 = 'Layout'
|
|
cname2 = 'Schematic'
|
|
|
|
# cellrec is a dictionary. Parse the cell summary, then failing nets,
|
|
# devices, and properties, and finally pins.
|
|
|
|
if 'name' in cellrec:
|
|
names = cellrec['name']
|
|
cname1 = names[0]
|
|
cname2 = names[1]
|
|
else:
|
|
# This is an error but don't halt the program because of it.
|
|
cname1 = '(unknown layout)'
|
|
cname2 = '(unknown schematic)'
|
|
|
|
item1 = cname1
|
|
item2 = cname2
|
|
tagstyle = 'header1'
|
|
index += 1
|
|
nest0 = index
|
|
self.treeView.insert('', 'end', text=index, iid=index, value=[item1, item2],
|
|
tags=[tagstyle])
|
|
|
|
if 'devices' in cellrec or 'nets' in cellrec:
|
|
item1 = cname1 + " Summary"
|
|
item2 = cname2 + " Summary"
|
|
tagstyle = 'header2'
|
|
index += 1
|
|
nest1 = index
|
|
self.treeView.insert(nest0, 'end', text=index, iid=index, value=[item1, item2],
|
|
tags=[tagstyle])
|
|
|
|
if 'devices' in cellrec:
|
|
item1 = cname1 + " Devices"
|
|
item2 = cname2 + " Devices"
|
|
tagstyle = 'header3'
|
|
index += 1
|
|
nest2 = index
|
|
self.treeView.insert(nest1, 'end', text=index, iid=index, value=[item1, item2],
|
|
tags=[tagstyle])
|
|
|
|
devices = cellrec['devices']
|
|
devlist = [val for pair in zip(devices[0], devices[1]) for val in pair]
|
|
devpair = list(devlist[p:p + 2] for p in range(0, len(devlist), 2))
|
|
for dev in devpair:
|
|
c1dev = dev[0]
|
|
c2dev = dev[1]
|
|
|
|
item1 = c1dev[0] + "(" + str(c1dev[1]) + ")"
|
|
item2 = c2dev[0] + "(" + str(c2dev[1]) + ")"
|
|
|
|
diffdevs = abs(c1dev[1] - c2dev[1])
|
|
if diffdevs == 0:
|
|
tagstyle = 'normal'
|
|
else:
|
|
tagstyle = 'error'
|
|
errcell['device'] += diffdevs
|
|
if topcell:
|
|
errtotal['device'] += diffdevs
|
|
index += 1
|
|
nest2 = index
|
|
self.treeView.insert(nest1, 'end', text=index, iid=index,
|
|
value=[item1, item2], tags=[tagstyle])
|
|
|
|
if 'nets' in cellrec:
|
|
item1 = cname1 + " Nets"
|
|
item2 = cname2 + " Nets"
|
|
tagstyle = 'header3'
|
|
index += 1
|
|
nest2 = index
|
|
self.treeView.insert(nest1, 'end', text=index, iid=index, value=[item1, item2],
|
|
tags=[tagstyle])
|
|
|
|
nets = cellrec['nets']
|
|
|
|
item1 = nets[0]
|
|
item2 = nets[1]
|
|
diffnets = abs(nets[0] - nets[1])
|
|
if diffnets == 0:
|
|
tagstyle = 'normal'
|
|
else:
|
|
tagstyle = 'error'
|
|
errcell['net'] = diffnets
|
|
if topcell:
|
|
errtotal['net'] += diffnets
|
|
index += 1
|
|
nest2 = index
|
|
self.treeView.insert(nest1, 'end', text=index, iid=index,
|
|
value=[item1, item2], tags=[tagstyle])
|
|
|
|
if 'badnets' in cellrec:
|
|
badnets = cellrec['badnets']
|
|
|
|
if len(badnets) > 0:
|
|
item1 = cname1 + " Net Mismatches"
|
|
item2 = cname2 + " Net Mismatches"
|
|
tagstyle = 'header2'
|
|
index += 1
|
|
nest1 = index
|
|
self.treeView.insert(nest0, 'end', text=index, iid=index,
|
|
value=[item1, item2], tags=[tagstyle])
|
|
|
|
groupnum = 0
|
|
for group in badnets:
|
|
groupc1 = group[0]
|
|
groupc2 = group[1]
|
|
nnets = len(groupc1)
|
|
|
|
groupnum += 1
|
|
tagstyle = 'header3'
|
|
index += 1
|
|
nest2 = index
|
|
item1 = "Group " + str(groupnum) + ' (' + str(nnets) + ' nets)'
|
|
self.treeView.insert(nest1, 'end', text=index, iid=index,
|
|
value=[item1, item1], tags=[tagstyle])
|
|
|
|
tagstyle = 'error'
|
|
errcell['netmatch'] += nnets
|
|
if topcell:
|
|
errtotal['netmatch'] += nnets
|
|
|
|
for netnum in range(0, nnets):
|
|
if netnum > 0:
|
|
item1 = ""
|
|
index += 1
|
|
nest3 = index
|
|
self.treeView.insert(nest2, 'end', text=index, iid=index,
|
|
value=[item1, item1], tags=[tagstyle])
|
|
|
|
net1 = groupc1[netnum]
|
|
net2 = groupc2[netnum]
|
|
tagstyle = 'header4'
|
|
item1 = net1[0]
|
|
item2 = net2[0]
|
|
index += 1
|
|
nest3 = index
|
|
self.treeView.insert(nest2, 'end', text=index, iid=index,
|
|
value=[item1, item2], tags=[tagstyle])
|
|
|
|
# Pad shorter device list to the length of the longer one
|
|
netdevs = list(itertools.zip_longest(net1[1], net2[1]))
|
|
for devpair in netdevs:
|
|
devc1 = devpair[0]
|
|
devc2 = devpair[1]
|
|
tagstyle = 'normal'
|
|
if devc1 and devc1[0] != "":
|
|
item1 = devc1[0] + '/' + devc1[1] + ' = ' + str(devc1[2])
|
|
else:
|
|
item1 = ""
|
|
if devc2 and devc2[0] != "":
|
|
item2 = devc2[0] + '/' + devc2[1] + ' = ' + str(devc2[2])
|
|
else:
|
|
item2 = ""
|
|
index += 1
|
|
nest3 = index
|
|
self.treeView.insert(nest2, 'end', text=index, iid=index,
|
|
value=[item1, item2], tags=[tagstyle])
|
|
|
|
if 'badelements' in cellrec:
|
|
badelements = cellrec['badelements']
|
|
|
|
if len(badelements) > 0:
|
|
item1 = cname1 + " Device Mismatches"
|
|
item2 = cname2 + " Device Mismatches"
|
|
tagstyle = 'header2'
|
|
index += 1
|
|
nest1 = index
|
|
self.treeView.insert(nest0, 'end', text=index, iid=index,
|
|
value=[item1, item2], tags=[tagstyle])
|
|
|
|
groupnum = 0
|
|
for group in badelements:
|
|
groupc1 = group[0]
|
|
groupc2 = group[1]
|
|
ndevs = len(groupc1)
|
|
|
|
groupnum += 1
|
|
tagstyle = 'header3'
|
|
index += 1
|
|
nest2 = index
|
|
item1 = "Group " + str(groupnum) + ' (' + str(ndevs) + ' devices)'
|
|
self.treeView.insert(nest1, 'end', text=index, iid=index,
|
|
value=[item1, item1], tags=[tagstyle])
|
|
|
|
tagstyle = 'error'
|
|
errcell['devmatch'] += ndevs
|
|
if topcell:
|
|
errtotal['devmatch'] += ndevs
|
|
|
|
for elemnum in range(0, ndevs):
|
|
if elemnum > 0:
|
|
item1 = ""
|
|
index += 1
|
|
nest3 = index
|
|
self.treeView.insert(nest2, 'end', text=index, iid=index,
|
|
value=[item1, item1], tags=[tagstyle])
|
|
|
|
elem1 = groupc1[elemnum]
|
|
elem2 = groupc2[elemnum]
|
|
tagstyle = 'header4'
|
|
item1 = elem1[0]
|
|
item2 = elem2[0]
|
|
index += 1
|
|
nest3 = index
|
|
self.treeView.insert(nest2, 'end', text=index, iid=index,
|
|
value=[item1, item2], tags=[tagstyle])
|
|
|
|
# Pad shorter pin list to the length of the longer one
|
|
elempins = list(itertools.zip_longest(elem1[1], elem2[1]))
|
|
for pinpair in elempins:
|
|
pinc1 = pinpair[0]
|
|
pinc2 = pinpair[1]
|
|
tagstyle = 'normal'
|
|
if pinc1 and pinc1[0] != "":
|
|
item1 = pinc1[0] + ' = ' + str(pinc1[1])
|
|
else:
|
|
item1 = ""
|
|
if pinc2 and pinc2[0] != "":
|
|
item2 = pinc2[0] + ' = ' + str(pinc2[1])
|
|
else:
|
|
item2 = ""
|
|
index += 1
|
|
nest3 = index
|
|
self.treeView.insert(nest2, 'end', text=index, iid=index,
|
|
value=[item1, item2], tags=[tagstyle])
|
|
|
|
if 'properties' in cellrec:
|
|
properties = cellrec['properties']
|
|
numproperr = len(properties)
|
|
if numproperr > 0:
|
|
item1 = cname1 + " Properties"
|
|
item2 = cname2 + " Properties"
|
|
tagstyle = 'header2'
|
|
index += 1
|
|
nest1 = index
|
|
self.treeView.insert(nest0, 'end', text=index, iid=index, value=[item1, item2],
|
|
tags=[tagstyle])
|
|
errcell['property'] = numproperr
|
|
errtotal['property'] += numproperr
|
|
|
|
for prop in properties:
|
|
|
|
if prop != properties[0]:
|
|
item1 = ""
|
|
index += 1
|
|
nest2 = index
|
|
self.treeView.insert(nest1, 'end', text=index, iid=index,
|
|
value=[item1, item1], tags=[tagstyle])
|
|
|
|
propc1 = prop[0]
|
|
propc2 = prop[1]
|
|
|
|
tagstyle = 'header3'
|
|
item1 = propc1[0]
|
|
item2 = propc2[0]
|
|
index += 1
|
|
nest2 = index
|
|
self.treeView.insert(nest1, 'end', text=index, iid=index,
|
|
value=[item1, item2], tags=[tagstyle])
|
|
|
|
# Pad shorter property list to the length of the longer one
|
|
elemprops = list(itertools.zip_longest(propc1[1], propc2[1]))
|
|
for proppair in elemprops:
|
|
perrc1 = proppair[0]
|
|
perrc2 = proppair[1]
|
|
tagstyle = 'normal'
|
|
if perrc1 and perrc1[0] != "":
|
|
item1 = perrc1[0] + ' = ' + str(perrc1[1])
|
|
else:
|
|
item1 = ""
|
|
if perrc2 and perrc2[0] != "":
|
|
item2 = perrc2[0] + ' = ' + str(perrc2[1])
|
|
else:
|
|
item2 = ""
|
|
index += 1
|
|
nest2 = index
|
|
self.treeView.insert(nest1, 'end', text=index, iid=index,
|
|
value=[item1, item2], tags=[tagstyle])
|
|
|
|
if 'pins' in cellrec:
|
|
item1 = cname1 + " Pins"
|
|
item2 = cname2 + " Pins"
|
|
tagstyle = 'header2'
|
|
index += 1
|
|
nest1 = index
|
|
self.treeView.insert(nest0, 'end', text=index, iid=index, value=[item1, item2],
|
|
tags=[tagstyle])
|
|
|
|
pins = cellrec['pins']
|
|
pinlist = [val for pair in zip(pins[0], pins[1]) for val in pair]
|
|
pinpair = list(pinlist[p:p + 2] for p in range(0, len(pinlist), 2))
|
|
for pin in pinpair:
|
|
item1 = pin[0]
|
|
item2 = pin[1]
|
|
if item1.lower() == item2.lower():
|
|
tagstyle = 'header4'
|
|
else:
|
|
tagstyle = 'error'
|
|
errcell['pin'] += 1
|
|
if topcell:
|
|
errtotal['pin'] += 1
|
|
index += 1
|
|
nest2 = index
|
|
self.treeView.insert(nest1, 'end', text=index, iid=index,
|
|
value=[item1, item2], tags=[tagstyle])
|
|
|
|
allcellerror = errcell['net'] + errcell['device'] + errcell['property'] + errcell['pin'] + errcell['netmatch'] + errcell['devmatch']
|
|
if allcellerror > 0:
|
|
item1 = 'Errors: Net = ' + str(errcell['net']) + ', Device = ' + str(errcell['device']) + ', Property = ' + str(errcell['property']) + ', Pin = ' + str(errcell['pin']) + ', Net match = ' + str(errcell['netmatch']) + ', Device match = ' + str(errcell['devmatch'])
|
|
tagstyle = 'error'
|
|
else:
|
|
item1 = 'LVS Clean'
|
|
tagstyle = 'clean'
|
|
|
|
item2 = ""
|
|
index += 1
|
|
nest0 = index
|
|
self.treeView.insert('', 'end', text=index, iid=index, value=[item1, item2],
|
|
tags=[tagstyle])
|
|
|
|
item1 = "Final LVS result:"
|
|
item2 = ""
|
|
tagstyle = 'header1'
|
|
index += 1
|
|
nest0 = index
|
|
self.treeView.insert('', 'end', text=index, iid=index, value=[item1, item2],
|
|
tags=[tagstyle])
|
|
|
|
allerror = errtotal['net'] + errtotal['device'] + errtotal['property'] + errtotal['pin'] + errtotal['netmatch'] + errtotal['devmatch']
|
|
if allerror > 0:
|
|
item1 = 'Errors: Net = ' + str(errtotal['net']) + ', Device = ' + str(errtotal['device']) + ', Property = ' + str(errtotal['property']) + ', Pin = ' + str(errtotal['pin']) + ', Net match = ' + str(errtotal['netmatch']) + ', Device match = ' + str(errtotal['devmatch'])
|
|
tagstyle = 'error'
|
|
else:
|
|
item1 = 'LVS Clean'
|
|
tagstyle = 'clean'
|
|
|
|
item2 = ""
|
|
index += 1
|
|
nest0 = index
|
|
self.treeView.insert('', 'end', text=index, iid=index, value=[item1, item2],
|
|
tags=[tagstyle])
|
|
|
|
for button in self.func_buttons:
|
|
button[0].pack_forget()
|
|
|
|
if index == 0:
|
|
self.treeView.insert('', 'end', text='-', value=['(no items)', '(no items)'])
|
|
for button in self.func_buttons:
|
|
if button[1]:
|
|
button[0].pack(side='left', padx = 5)
|
|
else:
|
|
for button in self.func_buttons:
|
|
button[0].pack(side='left', padx = 5)
|
|
|
|
# Return values from the treeview
|
|
def getlist(self):
|
|
return self.treeView.get_children()
|
|
|
|
def func_callback(self, callback, event=None):
|
|
callback(self.treeView.item(self.treeView.selection()))
|
|
|
|
def bindselect(self, callback):
|
|
self.selectcallback = callback
|
|
|
|
def setselect(self, value):
|
|
self.treeView.selection_set(value)
|
|
|
|
def selected(self):
|
|
value = self.treeView.item(self.treeView.selection())
|
|
if value['values']:
|
|
return value
|
|
else:
|
|
return None
|