blob: 2fb3e0b55f6cfa5553ae663f818c2ba6faef03d7 [file] [log] [blame]
emayecs5656b2b2021-08-04 12:44:13 -04001#!/usr/bin/env python3
emayecs5966a532021-07-29 10:07:02 -04002#
3#------------------------------------------------------------
emayecs14748312021-08-05 14:21:26 -04004# Profile settings window for the project manager
emayecs5966a532021-07-29 10:07:02 -04005#
6#------------------------------------------------------------
7# Written by Tim Edwards
8# efabless, inc.
9# July 21, 2017
10# Version 0.1
11#--------------------------------------------------------
12
13import os
14import re
15import json
16import tkinter
17import subprocess
18from tkinter import ttk
19
emayecsb2487ae2021-08-05 10:30:13 -040020import config
emayecs5966a532021-07-29 10:07:02 -040021
22class Profile(tkinter.Toplevel):
emayecs14748312021-08-05 14:21:26 -040023 """Project manager profile settings management."""
emayecs5966a532021-07-29 10:07:02 -040024
25 def __init__(self, parent=None, fontsize = 11, *args, **kwargs):
26 '''See the __init__ for Tkinter.Toplevel.'''
27 tkinter.Toplevel.__init__(self, parent, *args, **kwargs)
28
29 s = ttk.Style()
30 s.configure('normal.TButton', font=('Helvetica', fontsize), border = 3, relief = 'raised')
31 self.protocol("WM_DELETE_WINDOW", self.close)
32 self.parent = parent
33 self.withdraw()
emayecs14748312021-08-05 14:21:26 -040034 self.title('Project Manager Profile Settings')
emayecs5966a532021-07-29 10:07:02 -040035 self.sframe = tkinter.Frame(self)
36 self.sframe.grid(column = 0, row = 0, sticky = "news")
37
38 self.sframe.stitle = ttk.Label(self.sframe,
39 style='title.TLabel', text = 'Profile')
40 self.sframe.stitle.grid(column = 0, row = 0, sticky = 'news', padx = 5, pady = 5, columnspan = 2)
41 self.sframe.sbar = ttk.Separator(self.sframe, orient='horizontal')
42 self.sframe.sbar.grid(column = 0, row = 1, sticky = 'news', padx = 5, pady = 5, columnspan = 2)
43
44 # Read profile JSON file
45 self.prefsfile = os.path.expanduser('~/.open_pdks/prefs.json')
46
47 if os.path.exists(self.prefsfile):
48 with open(self.prefsfile, 'r') as f:
49 prefs = json.load(f)
50 else:
51 prefs = {}
52
53 # Default font size preference
54
55 self.fontsize = tkinter.IntVar(self.sframe)
56 self.sframe.lfsize = ttk.Label(self.sframe, text='Font size', style='blue.TLabel', anchor='e')
57 self.sframe.fsize = ttk.Entry(self.sframe, textvariable=self.fontsize)
58 self.sframe.lfsize.grid(column = 0, row = 2, sticky = 'news', padx = 5, pady = 5)
59 self.sframe.fsize.grid(column = 1, row = 2, sticky = 'news', padx = 5, pady = 5)
60
61 if 'fontsize' in prefs:
62 self.fontsize.set(int(prefs['fontsize']))
63 else:
64 self.fontsize.set(11)
65
66 # User name as written at the top of the project manager and characterization tools
67
68 self.username = tkinter.StringVar(self.sframe)
69 self.sframe.luser = ttk.Label(self.sframe, text='User name', style='blue.TLabel', anchor='e')
70 self.sframe.user = ttk.Entry(self.sframe, textvariable=self.username)
71 self.sframe.luser.grid(column = 0, row = 3, sticky = 'news', padx = 5, pady = 5)
72 self.sframe.user.grid(column = 1, row = 3, sticky = 'news', padx = 5, pady = 5)
73
74 if 'username' in prefs:
75 self.username.set(prefs['username'])
76 else:
77 userid = os.environ['USER']
78 '''
79 p = subprocess.run(['/ef/apps/bin/withnet',
emayecsb2487ae2021-08-05 10:30:13 -040080 config.apps_path + '/og_uid_service.py', userid],
emayecs5966a532021-07-29 10:07:02 -040081 stdout = subprocess.PIPE)
82
83 if p.stdout:
84 uid_string = p.stdout.splitlines()[0].decode('utf-8')
85 userspec = re.findall(r'[^"\s]\S*|".+?"', uid_string)
86 if len(userspec) > 0:
87 username = userspec[0].strip('"')
88 # Note userspec[1] = UID and userspec[2] = role, useful
89 # for future applications.
90 else:
91 username = userid
92 else:
93 username = userid
94 '''
95 username=userid
96
97 self.username.set(username)
98
99 # Graphics format for magic
100 magicgraphics = ['X11', 'CAIRO', 'OPENGL']
101
102 self.maggraph = tkinter.StringVar(self.sframe)
103 self.maggraph.set(0)
104 self.sframe.lmaggraph = ttk.Label(self.sframe, text='Layout editor graphics format', style='blue.TLabel', anchor='e')
105 self.sframe.maggraph = ttk.OptionMenu(self.sframe, self.maggraph,
106 self.maggraph.get(), *magicgraphics)
107
108 self.sframe.lmaggraph.grid(column = 0, row = 4, sticky = 'news', padx = 5, pady = 5)
109 self.sframe.maggraph.grid(column = 1, row = 4, sticky = 'news', padx = 5, pady = 5)
110
111 if 'magic-graphics' in prefs:
112 self.maggraph.set(prefs['magic-graphics'])
113 else:
114 self.maggraph.set('X11')
115
116 # Choice of layout editor
117 layouteditors = ['magic', 'klayout', 'electric']
118
119 self.layouteditor = tkinter.StringVar(self.sframe)
120 self.layouteditor.set(0)
121 self.sframe.llayouteditor = ttk.Label(self.sframe, text='Layout editor', style='blue.TLabel', anchor='e')
122 self.sframe.layouteditor = ttk.OptionMenu(self.sframe, self.layouteditor,
123 self.layouteditor.get(), *layouteditors)
124
125 self.sframe.llayouteditor.grid(column = 0, row = 5, sticky = 'news', padx = 5, pady = 5)
126 self.sframe.layouteditor.grid(column = 1, row = 5, sticky = 'news', padx = 5, pady = 5)
127
128 if 'layout-editor' in prefs:
129 self.layouteditor.set(prefs['layout-editor'])
130 else:
131 self.layouteditor.set('magic')
132
133 # Choice of schematic editor
134 schemeditors = ['electric', 'xschem', 'xcircuit']
135
136 self.schemeditor = tkinter.StringVar(self.sframe)
137 self.schemeditor.set(0)
138 self.sframe.lschemeditor = ttk.Label(self.sframe, text='Schematic editor', style='blue.TLabel', anchor='e')
139 self.sframe.schemeditor = ttk.OptionMenu(self.sframe, self.schemeditor,
140 self.schemeditor.get(), *schemeditors)
141
142 self.sframe.lschemeditor.grid(column = 0, row = 6, sticky = 'news', padx = 5, pady = 5)
143 self.sframe.schemeditor.grid(column = 1, row = 6, sticky = 'news', padx = 5, pady = 5)
144
145
146 if 'schemeditor' in prefs:
147 self.schemeditor.set(prefs['schemeditor'])
148 else:
149 self.schemeditor.set('electric')
150
151 # Allow the project manager to list development PDKs and create projects
152 # using them.
153
154 self.development = tkinter.IntVar(self.sframe)
155 self.sframe.ldev = ttk.Label(self.sframe, text='Create projects with development PDKs', style='blue.TLabel', anchor='e')
156 self.sframe.dev = ttk.Checkbutton(self.sframe, variable=self.development)
157 self.sframe.ldev.grid(column = 0, row = 7, sticky = 'news', padx = 5, pady = 5)
158 self.sframe.dev.grid(column = 1, row = 7, sticky = 'news', padx = 5, pady = 5)
159
160 if 'development' in prefs:
161 self.development.set(True)
162 else:
163 self.development.set(False)
164
165 # Allow the synthesis tool to list PDK development standard cell sets
166
167 self.devstdcells = tkinter.IntVar(self.sframe)
168 self.sframe.ldev = ttk.Label(self.sframe, text='Use development libraries for digital synthesis', style='blue.TLabel', anchor='e')
169 self.sframe.dev = ttk.Checkbutton(self.sframe, variable=self.devstdcells)
170 self.sframe.ldev.grid(column = 0, row = 8, sticky = 'news', padx = 5, pady = 5)
171 self.sframe.dev.grid(column = 1, row = 8, sticky = 'news', padx = 5, pady = 5)
172
173 if 'devstdcells' in prefs:
174 self.devstdcells.set(True)
175 else:
176 self.devstdcells.set(False)
177
178 # Button bar
179
180 self.bbar = ttk.Frame(self)
181 self.bbar.grid(column = 0, row = 1, sticky = "news")
182
183 self.bbar.save_button = ttk.Button(self.bbar, text='Save',
184 command=self.save, style = 'normal.TButton')
185 self.bbar.save_button.grid(column=0, row=0, padx = 5)
186
187 self.bbar.close_button = ttk.Button(self.bbar, text='Close',
188 command=self.close, style = 'normal.TButton')
189 self.bbar.close_button.grid(column=1, row=0, padx = 5)
190
191 def save(self):
192 # Create JSON record of options and write them to prefs.json
193 with open(self.prefsfile, 'w') as f:
194 prefs = {}
195 prefs['fontsize'] = self.get_fontsize()
196 prefs['username'] = self.get_username()
197 prefs['schemeditor'] = self.get_schemeditor()
198 prefs['magic-graphics'] = self.get_magic_graphics()
199 prefs['development'] = self.get_development()
200 prefs['devstdcells'] = self.get_devstdcells()
201 json.dump(prefs, f, indent = 4)
202 # Live-updates where easy. Due read_prefs, a magic-graphics takes effect immediately.
203 self.parent.read_prefs()
204 self.parent.refreshToolTips()
205
206 def grid_configure(self, padx, pady):
207 pass
208
209 def redisplay(self):
210 pass
211
212 def get_fontsize(self):
213 # return the fontsize value
214 return self.fontsize.get()
215
216 def get_username(self):
217 # return the username
218 return self.username.get()
219
220 def get_schemeditor(self):
221 # return the state of the "keep simulation files" checkbox
222 return self.schemeditor.get()
223
224 def get_magic_graphics(self):
225 # return the format of graphics to use in Magic
226 return self.maggraph.get()
227
228 def get_development(self):
229 # return the T/F value for creating projects with development PDKs
230 return self.development.get()
231
232 def get_devstdcells(self):
233 # return the T/F value for synthesizing projects with development standard cells
234 return self.devstdcells.get()
235
236 def refresh(self):
237 self.prefsfile = os.path.expanduser('~/.open_pdks/prefs.json')
238
239 if os.path.exists(self.prefsfile):
240 with open(self.prefsfile, 'r') as f:
241 prefs = json.load(f)
242 else:
243 prefs = {}
244 if 'fontsize' in prefs:
245 self.fontsize.set(int(prefs['fontsize']))
246 else:
247 self.fontsize.set(11)
248 if 'username' in prefs:
249 self.username.set(prefs['username'])
250 else:
251 userid = os.environ['USER']
252 if 'magic-graphics' in prefs:
253 self.maggraph.set(prefs['magic-graphics'])
254 else:
255 self.maggraph.set('X11')
256 if 'layout-editor' in prefs:
257 self.layouteditor.set(prefs['layout-editor'])
258 else:
259 self.layouteditor.set('magic')
260 if 'schemeditor' in prefs:
261 self.schemeditor.set(prefs['schemeditor'])
262 else:
263 self.schemeditor.set('electric')
264 if 'development' in prefs:
265 self.development.set(True)
266 else:
267 self.development.set(False)
268 if 'devstdcells' in prefs:
269 self.devstdcells.set(True)
270 else:
271 self.devstdcells.set(False)
272
273 def close(self):
274 # pop down profile settings window
275 self.withdraw()
276
277 def open(self):
278 # pop up profile settings window
279 self.refresh()
280 self.deiconify()
281 self.lift()