blob: abcd4af4c7cbdb553b81bf3353df56a9d32cfabc [file] [log] [blame]
jk-armbf532fd2021-05-07 13:58:22 +05301#! /usr/bin/env python
2#/** @file
3# * Copyright (c) 2021, Arm Limited or its affiliates. All rights reserved.
4# * SPDX-License-Identifier : Apache-2.0
5# *
6# * Licensed under the Apache License, Version 2.0 (the "License");
7# * you may not use this file except in compliance with the License.
8# * You may obtain a copy of the License at
9# *
10# * http://www.apache.org/licenses/LICENSE-2.0
11# *
12# * Unless required by applicable law or agreed to in writing, software
13# * distributed under the License is distributed on an "AS IS" BASIS,
14# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15# * See the License for the specific language governing permissions and
16# * limitations under the License.
17#**/
18
19import os, sys, re
20
21gtoplevel = None
22filename=''
23filename_dir = []
24testsuite_list = []
25f_temp=[]
26testsuite_temp=[]
27
28
29try:
30 import Tkinter as tk
31 from Tkinter import tkFileDialog as fd
32 from Tkinter import *
33except ImportError:
34 import tkinter as tk
35 from tkinter import filedialog as fd
36 from tkinter import *
37
38try:
39 import ttk
40 py3 = False
41except ImportError:
42 import tkinter.ttk as ttk
43 py3 = True
44
45try:
46 from tkinter import messagebox
47except:
48 import tkMessageBox as messagebox
49
50# Browse the single testsuite log file
51def browseLogFile():
52 clearText()
53 clearTree()
54 filename_dir.clear()
55 testsuite_list.clear()
56 f_temp.clear()
57 global filename
58 global gtoplevel
59 try:
60 ftypes = [('all types', '*.*')]
61 filename = fd.askopenfilename(initialdir="/", title="Select A File", filetypes=ftypes)
62 if filename == "":
63 clearText()
64 gtoplevel.Scrolledtext1.insert("end", "\nPlease Select File\n")
65 return;
66 filename_dir.append(filename)
67 findTestSuite(filename)
68
69 except Exception as e:
70 gtoplevel.Scrolledtext1.insert("end", "EXCEPTION : " + str(e) + "\n")
71 pass
72
73# Browse multiple testsuite log files in single folder
74def browseLogFolder():
75 global filename_dir
76 global gtoplevel
77 testsuite_list.clear()
78 clearText()
79 clearTree()
80 filename_dir.clear()
81 f_temp.clear()
82 testsuite_temp.clear()
83
84
85 try:
86 dirname = fd.askdirectory()
87 if dirname == "":
88 clearText()
89 gtoplevel.Scrolledtext1.insert("end", "\nPlease Select Directory\n")
90 return;
91 for path in os.listdir(dirname):
92 full_path = os.path.join(dirname, path)
93 if os.path.isfile(full_path):
94 filename_dir.append(full_path)
95 for file in filename_dir:
96 findTestSuite(file)
97 for f1 in f_temp:
98 filename_dir.remove(f1)
99
100 if testsuite_temp:
101 testsuite_temp1 = set(testsuite_temp)
102 messagebox.showwarning("Warning","{} Test Suite file is already exists. \nAll the duplicate test suite will not be added.".format(testsuite_temp1))
103 testsuite_temp1.clear()
104
105 except Exception as e:
106 gtoplevel.Scrolledtext1.insert("end", "EXCEPTION : " + str(e) + "\n")
107 pass
108
109# Find testsuite from file.
110def findTestSuite(filename):
111 ut = False
112 global gtoplevel
113 f = open(filename, 'r+')
114 try:
115
116 for line in f:
117 if re.search(r'PSA\sArchitecture\sTest\sSuite\s-\sVersion\s(.*?)\s',line):
118 testsuite_version = re.search(r'PSA\sArchitecture\sTest\sSuite\s-\sVersion\s(.*?)\s',line).group(1)
119 gtoplevel.Scrolledtreeview1.heading("#0", text="PSA Arch Test Suite "+testsuite_version)
120 break
121 for line in f:
122 if re.search(r'^Running..\s(.*?)\sSuite$', line):
123 testsuite = re.search("Running..\s(.*?)\sSuite", line).group(1)
124 if testsuite in testsuite_list:
125 f_temp.append(filename)
126 testsuite_temp.append(testsuite)
127 else:
128 testsuite_list.append(testsuite)
129
130 for line in f:
131 if re.search(r'^TEST:\s[0-9]+\s\|\sDESCRIPTION:\sTesting\s.*\s.*\sAPIs\s\|\sUT:\s.*\n', line):
132 ut = True
133 break
134 if testsuite == "":
135 gtoplevel.Scrolledtext1.insert("end","Please Select Proper File")
136 if ut is True:
137 if testsuite == "Storage":
138 storageDataExtraction(filename, testsuite)
139 else:
140 testsuiteDataExtraction(filename, testsuite)
141 else:
142 if testsuite=="Attestation":
143 attestationDataExtraction(filename, testsuite)
144 elif testsuite=="Storage":
145 storageDataExtraction(filename, testsuite)
146 elif testsuite=="Crypto":
147 cryptoDataExtraction(filename, testsuite)
148 break
149
150 except Exception as e:
151 gtoplevel.Scrolledtext1.insert("end", "EXCEPTION : " + str(e) + "\n")
152 pass
153
154
155# Tests extraction from file. It will create list of tests.
156def testsExtraction(fname):
157 f = open(fname, 'r+')
158 test = None
159 tests = []
160 is_test = False
161 for line in f:
162 if not is_test and line.startswith('TEST:'):
163 is_test = True
164 test = []
165
166 elif is_test and line.startswith('TEST RESULT:'):
167 test.append(line)
168 is_test = False
169 tests.append(''.join(test))
170 test = None
171
172 if is_test:
173 test.append(line)
174 return tests
175
176
177# Crypto testsuite data extaction
178def cryptoDataExtraction(fname, testsuite):
179 global gtoplevel
180 tests = testsExtraction(fname)
181 testsuite = testsuite.lower()
182 firstlevel = []
183 secondlevel = []
184 thirdlevel = []
185
186 gtoplevel.Scrolledtreeview1.insert(parent='', index='end', iid=testsuite, text=testsuite)
187
188 for i in tests:
189 if re.search(r'^TEST:\s201',i):
190 gtoplevel.Scrolledtreeview1.insert(parent=testsuite, index='end', iid="basic", text="Basic")
191 gtoplevel.Scrolledtreeview1.insert(parent="basic", index='end', iid="psa_crypto_init", text="psa_crypto_init")
192 test_num = re.search(r'(.*?)\sDESCRIPTION:', i).group(1)
193 test_result = re.search(r'TEST\sRESULT:\s(.*?)\s', i).group(1)
194 b = test_num + " " + test_result
195 b_temp = b.replace(" ","")
196 gtoplevel.Scrolledtreeview1.insert(parent="psa_crypto_init", index='end', iid=b_temp, text=b)
197
198 if re.search(rf'^TEST:\s[0-9]+\s\|\sDESCRIPTION:\sTesting\s{testsuite}\s(.*?)\sAPIs', i):
199 x = re.search(rf'^TEST:\s[0-9]+\s\|\sDESCRIPTION:\sTesting\s{testsuite}\s(.*?)\sAPIs', i).group(1)
200 firstlevel.append(x) if x not in firstlevel else firstlevel
201
202 if not firstlevel:
203 messagebox.showerror("Error", "Test Suite File must be in required format.")
204 clearTree()
205 return
206
207 for record in firstlevel:
208 r_temp = record.replace(" ", "")
209 gtoplevel.Scrolledtreeview1.insert(parent=testsuite, index='end', iid=r_temp, text=record)
210
211 for i in firstlevel:
212 secondlevel.clear()
213 for j in tests:
214 if re.search(rf'^TEST:\s[0-9]+\s\|\sDESCRIPTION:\sTesting\s{testsuite}\s{i}\sAPIs\n', j):
215 if re.search(r'\[Check\s1\]\sTest\s(.*?)\s.*\n', j):
216 y = re.search(r'\[Check\s1\]\sTest\s(.*?)\s.*\n', j).group(1)
217 secondlevel.append(y) if y not in secondlevel else secondlevel
218
219 for r in secondlevel:
220 i_temp = i.replace(" ", "")
221 gtoplevel.Scrolledtreeview1.insert(parent=i_temp, index='end', iid=r, text=r)
222
223 for k in secondlevel:
224 thirdlevel.clear()
225 for m in tests:
226 if re.search(rf'^TEST:\s[0-9]+\s\|\sDESCRIPTION:\sTesting\s{testsuite}\s{i}\sAPIs\n', m):
227 if re.search(rf'\[Check\s1\]\sTest\s{k}\s.*\n', m):
228 test_num = re.search(r'(.*?)\sDESCRIPTION:', m).group(1)
229 test_result = re.search(r'TEST\sRESULT:\s(.*?)\s', m).group(1)
230 b = test_num + " " + test_result
231 thirdlevel.append(b) if b not in thirdlevel else thirdlevel
232
233 for rec in thirdlevel:
234 rec_temp = rec.replace(" ", "")
235 gtoplevel.Scrolledtreeview1.insert(parent=k, index='end', iid=rec_temp, text=rec)
236
237 if not secondlevel or not thirdlevel:
238 messagebox.showerror("Error", "Test Suite File must be in required format.")
239 clearTree()
240
241
242# Attestation testsuite data extraction
243def attestationDataExtraction(fname, testsuite):
244 global gtoplevel
245 tests = testsExtraction(fname)
246 testsuite = testsuite.lower()
247 attest = []
248
249 gtoplevel.Scrolledtreeview1.insert(parent='', index='end', iid=testsuite, text=testsuite)
250 testsuite_new="initial attestation"
251 for i in tests:
252 if re.search(rf'^TEST:\s[0-9]+\s\|\sDESCRIPTION:\sTesting\s{testsuite_new}\sAPIs', i):
253 if re.search(r'\[Check\s1\]\sTest\s(.*?)\s.*\n', i):
254 y = re.search(r'\[Check\s1\]\sTest\s(.*?)\s.*\n', i).group(1)
255 attest.append(y) if y not in attest else attest
256
257 for r in attest:
258 gtoplevel.Scrolledtreeview1.insert(parent=testsuite, index='end', iid=r, text=r)
259
260
261 for j in attest:
262 for t in tests:
263 if re.search(rf'\[Check\s1\]\sTest\s{j}\s.*\n', t):
264 test_num = re.search(r'(.*?)\sDESCRIPTION:', t).group(1)
265 test_result = re.search(r'TEST\sRESULT:\s(.*?)\s', t).group(1)
266 b = test_num + " " + test_result
267 gtoplevel.Scrolledtreeview1.insert(parent=j, index='end', iid=b, text=b)
268
269# Storage testsuite data extraction
270def storageDataExtraction(fname, testsuite):
271 global gtoplevel
272 tests = testsExtraction(fname)
273 testsuite = testsuite.lower()
274
275 gtoplevel.Scrolledtreeview1.insert(parent='', index='end', iid=testsuite, text=testsuite)
276 gtoplevel.Scrolledtreeview1.insert(parent=testsuite, index='end', iid="ITS", text="ITS")
277 gtoplevel.Scrolledtreeview1.insert(parent=testsuite, index='end', iid="PS", text="PS")
278 for i in tests:
279 test_num = re.search(r'(.*?)\sDESCRIPTION:', i).group(1)
280 test_result = re.search(r'TEST\sRESULT:\s(.*?)\s', i).group(1)
281 b = test_num + " " + test_result
282 b_temp = b.replace(" ", "")
283 if re.search(r'\[Info\]\sExecuting\sITS\stests\n', i):
284 b_temp1 = "its_"+b_temp
285 gtoplevel.Scrolledtreeview1.insert(parent="ITS", index='end', iid=b_temp1, text=b)
286
287 if re.search(r'\[Info\]\sExecuting\sPS\stests\n', i):
288 b_temp2 = "ps_" + b_temp
289 gtoplevel.Scrolledtreeview1.insert(parent="PS", index='end', iid=b_temp2, text=b)
290
291 its_child = gtoplevel.Scrolledtreeview1.get_children("ITS")
292 if not its_child:
293 gtoplevel.Scrolledtreeview1.delete("ITS")
294 ps_child = gtoplevel.Scrolledtreeview1.get_children("PS")
295 if not ps_child:
296 gtoplevel.Scrolledtreeview1.delete("PS")
297
298
299# Generic testsuite data extraction
300def testsuiteDataExtraction(fname, testsuite):
301 global gtoplevel
302 tests = testsExtraction(fname)
303 firstlevel = []
304 secondlevel = []
305 thirdlevel = []
306 testsuite = testsuite.lower()
307
308 gtoplevel.Scrolledtreeview1.insert(parent='', index='end', iid=testsuite, text=testsuite)
309
310 for i in tests:
311 if re.search(rf'^TEST:\s[0-9]+\s\|\sDESCRIPTION:\sTesting\s{testsuite}\s(.*?)\sAPIs', i):
312 x = re.search(rf'^TEST:\s[0-9]+\s\|\sDESCRIPTION:\sTesting\s{testsuite}\s(.*?)\sAPIs', i).group(1)
313 firstlevel.append(x) if x not in firstlevel else firstlevel
314
315 if not firstlevel:
316 messagebox.showerror("Error","Test Suite File must be in required format.")
317 clearTree()
318 return
319
320 for record in firstlevel:
321 r_temp = record.replace(" ", "")
322 gtoplevel.Scrolledtreeview1.insert(parent=testsuite, index='end', iid=r_temp, text=record)
323
324 for i in firstlevel:
325 secondlevel.clear()
326 for j in tests:
327 if re.search(rf'^TEST:\s[0-9]+\s\|\sDESCRIPTION:\sTesting\s{testsuite}\s{i}\sAPIs\s\|\sUT:\s(.*?)\n', j):
328 y = re.search(rf'^TEST:\s[0-9]+\s\|\sDESCRIPTION:\sTesting\s{testsuite}\s{i}\sAPIs\s\|\sUT:\s(.*?)\n', j).group(1)
329 secondlevel.append(y) if y not in secondlevel else secondlevel
330
331 for r in secondlevel:
332 i_temp = i.replace(" ","")
333 gtoplevel.Scrolledtreeview1.insert(parent=i_temp, index='end', iid=r, text=r)
334
335 for k in secondlevel:
336 thirdlevel.clear()
337 for m in tests:
338 if re.search(rf'^TEST:\s[0-9]+\s\|\sDESCRIPTION:\sTesting\s{testsuite}\s{i}\sAPIs\s\|\sUT:\s{k}\n', m):
339 test_num = re.search(r'(.*?)\sDESCRIPTION:',m).group(1)
340 test_result = re.search(r'TEST\sRESULT:\s(.*?)\s',m).group(1)
341 b = test_num+" "+test_result
342 thirdlevel.append(b) if b not in thirdlevel else thirdlevel
343
344 for rec in thirdlevel:
345 rec_temp=rec.replace(" ","")
346 gtoplevel.Scrolledtreeview1.insert(parent=k, index='end', iid=rec_temp, text=rec)
347
348 if not secondlevel or not thirdlevel:
349 messagebox.showerror("Error", "Test Suite File must be in required format.")
350 clearTree()
351
352
353# Get the summary result of selected tree node
354def summary_result():
355 global gtoplevel
356 passed = 0
357 failed = 0
358 skipped = 0
359 sim_error = 0
360 clearText()
361 selected_item = gtoplevel.Scrolledtreeview1.selection()[0]
362
363 if selected_item == "storage" :
364 firstlevel = gtoplevel.Scrolledtreeview1.get_children(selected_item)
365 for child in firstlevel:
366 passed = 0
367 failed = 0
368 skipped = 0
369 sim_error = 0
370 secondlevel = gtoplevel.Scrolledtreeview1.get_children(child)
371 if not secondlevel:
372 result = gtoplevel.Scrolledtreeview1.item(child)['text']
373 if re.search(r'TEST:\s[0-9]+\s\|\s(.*?)', result):
374 r = re.search(r'TEST:\s[0-9]+\s\|\s(.*?)$', result).group(1)
375 if r == "PASSED":
376 passed = passed + 1
377 if r == "FAILED":
378 failed = failed + 1
379 if r == "SKIPPED":
380 skipped = skipped + 1
381 if r == "SIM ERROR":
382 sim_error = sim_error + 1
383
384 else:
385 for c in secondlevel:
386 thirdlevel = gtoplevel.Scrolledtreeview1.get_children(c)
387
388 if not thirdlevel:
389 result = gtoplevel.Scrolledtreeview1.item(c)['text']
390 if re.search(r'TEST:\s[0-9]+\s\|\s(.*?)', result):
391 r = re.search(r'TEST:\s[0-9]+\s\|\s(.*?)$', result).group(1)
392 if r == "PASSED":
393 passed = passed + 1
394 if r == "FAILED":
395 failed = failed + 1
396 if r == "SKIPPED":
397 skipped = skipped + 1
398 if r == "SIM ERROR":
399 sim_error = sim_error + 1
400
401 total_test = passed + failed + skipped + sim_error
402 data1 = "************ "+child+" Summary Report ************\nTOTAL TESTS :" + str(
403 total_test) + "\nTOTAL PASSED :" + str(
404 passed) + "\nTOTAL SIM ERROR :" + str(sim_error) + "\nTOTAL FAILED :" + str(
405 failed) + "\nTOTAL SKIPPED :" + str(skipped) + "\n***********************************************\n"
406 gtoplevel.Scrolledtext1.insert(END, data1)
407 else:
408 firstlevel = gtoplevel.Scrolledtreeview1.get_children(selected_item)
409
410 if not firstlevel:
411 gtoplevel.Scrolledtext1.insert(END,"This node has not any leaf nodes.")
412 else:
413 for child in firstlevel:
414 secondlevel = gtoplevel.Scrolledtreeview1.get_children(child)
415 if not secondlevel:
416 result = gtoplevel.Scrolledtreeview1.item(child)['text']
417 if re.search(r'TEST:\s[0-9]+\s\|\s(.*?)', result):
418 r = re.search(r'TEST:\s[0-9]+\s\|\s(.*?)$', result).group(1)
419 if r == "PASSED":
420 passed = passed + 1
421 if r == "FAILED":
422 failed = failed + 1
423 if r == "SKIPPED":
424 skipped = skipped + 1
425 if r == "SIM ERROR":
426 sim_error = sim_error + 1
427 else:
428 for c in secondlevel:
429 thirdlevel = gtoplevel.Scrolledtreeview1.get_children(c)
430
431 if not thirdlevel:
432 result = gtoplevel.Scrolledtreeview1.item(c)['text']
433 if re.search(r'TEST:\s[0-9]+\s\|\s(.*?)', result):
434 r = re.search(r'TEST:\s[0-9]+\s\|\s(.*?)$', result).group(1)
435 if r == "PASSED":
436 passed = passed + 1
437 if r == "FAILED":
438 failed = failed + 1
439 if r == "SKIPPED":
440 skipped = skipped + 1
441 if r == "SIM ERROR":
442 sim_error = sim_error + 1
443 else:
444 for c1 in thirdlevel:
445 fourthlevel = gtoplevel.Scrolledtreeview1.get_children(c1)
446 if not fourthlevel:
447 result = gtoplevel.Scrolledtreeview1.item(c1)['text']
448 if re.search(r'TEST:\s[0-9]+\s\|\s(.*?)', result):
449 r = re.search(r'TEST:\s[0-9]+\s\|\s(.*?)$', result).group(1)
450 if r == "PASSED":
451 passed = passed + 1
452 if r == "FAILED":
453 failed = failed + 1
454 if r == "SKIPPED":
455 skipped = skipped + 1
456 if r == "SIM ERROR":
457 sim_error = sim_error + 1
458
459 total_test = passed + failed + skipped + sim_error
460 data1 = "************ Summary Report ************\nTOTAL TESTS :" + str(total_test) + "\nTOTAL PASSED :" + str(
461 passed) + "\nTOTAL SIM ERROR :" + str(sim_error) + "\nTOTAL FAILED :" + str(
462 failed) + "\nTOTAL SKIPPED :" + str(skipped) + "\n******************************************"
463 gtoplevel.Scrolledtext1.insert(END, data1)
464
465
466# On Right click of tree item it will display summary result of that tree node
467def onRightClick(e):
468 global gtoplevel
469 try:
470 e.widget.focus()
471 item = gtoplevel.Scrolledtreeview1.identify('item', e.x, e.y)
472 rmenu = Menu(None, tearoff=0, takefocus=0)
473 rmenu.add_command(label="Summary", command=summary_result)
474 rmenu.add_command(label="Expand", command=lambda: open_tree(item))
475 rmenu.add_command(label="Collapse", command=lambda: close_tree(item))
476 rmenu.tk_popup(e.x_root + 40, e.y_root + 10, entry="0")
477 except TclError:
478 print(' - rClick menu, something wrong')
479 pass
480
481 return "break"
482
483# On clicking double click on tree item for test it will fetch the test data from file and insert in text widget
484def onDoubleClick(a):
485 global gtoplevel
486 global filename
487 global filename_dir
488
489 clearText()
490 selected_item = gtoplevel.Scrolledtreeview1.selection()[0]
491 cur_item = gtoplevel.Scrolledtreeview1.item(selected_item)['text']
492
493
494 if re.search(r'^TEST:', cur_item):
495 for file in filename_dir:
496 data = showTest(file,cur_item)
497 try:
498 if data:
499 gtoplevel.Scrolledtext1.insert(END, data)
500 pass
501 except Exception as e:
502 print ('error : '+e)
503
504
505# Get specific selected test from file
506def showTest(fname,selected_item):
507 tests = testsExtraction(fname)
508 x = selected_item.split('|')
509 for i in tests:
510 if re.search(rf'{x[0]}',i):
511 return i
512
513
514# Clear Tree Widget Data
515def clearTree():
516 global gtoplevel
517 for i in gtoplevel.Scrolledtreeview1.get_children():
518 gtoplevel.Scrolledtreeview1.delete(i)
519
520
521# Clear Text Widget Data
522def clearText():
523 global gtoplevel
524 gtoplevel.Scrolledtext1.delete("1.0", "end")
525
526# Collapse tree nodes
527def close_tree(parent):
528 global gtoplevel
529 gtoplevel.Scrolledtreeview1.item(parent, open=False)
530 for child in gtoplevel.Scrolledtreeview1.get_children(parent):
531 close_tree(child)
532
533# Expand tree nodes
534def open_tree(parent):
535 global gtoplevel
536 gtoplevel.Scrolledtreeview1.item(parent, open=True)
537 for child in gtoplevel.Scrolledtreeview1.get_children(parent):
538 open_tree(child)
539
540
541def vp_start_gui():
542 '''Starting point when module is the main routine.'''
543 global gtoplevel
544 global val, w, root
545 root = tk.Tk()
546 top = Toplevel1 (root)
547
548 if platform.system() == 'Linux':
549 root.attributes('-zoomed', True)
550 elif platform.system() == 'Windows':
551 root.state('zoomed')
552 gtoplevel = top
553 gui_init(root, top)
554 root.mainloop()
555
556w = None
557def create_Toplevel1(rt, *args, **kwargs):
558 '''Starting point when module is imported by another module.
559 Correct form of call: 'create_Toplevel1(root, *args, **kwargs)' .'''
560 global w, w_win, root
561 #rt = root
562 root = rt
563 w = tk.Toplevel (root)
564 top = Toplevel1 (w)
565 gui_init(w, top, *args, **kwargs)
566 return (w, top)
567
568def destroy_Toplevel1():
569 global w
570 w.destroy()
571 w = None
572
573def gui_init(top, gui, *args, **kwargs):
574 global w, top_level, root
575 w = gui
576 top_level = top
577 root = top
578
579def destroy_window():
580 # Function which closes the window.
581 global top_level
582 top_level.destroy()
583 top_level = None
584
585class Toplevel1:
586 def __init__(self, top=None):
587 '''This class configures and populates the toplevel window.
588 top is the toplevel containing window.'''
589 _bgcolor = '#d9d9d9' # X11 color: 'gray85'
590 _fgcolor = '#000000' # X11 color: 'black'
591 _compcolor = '#d9d9d9' # X11 color: 'gray85'
592 _ana1color = '#d9d9d9' # X11 color: 'gray85'
593 _ana2color = '#ececec' # Closest X11 color: 'gray92'
594 self.style = ttk.Style()
595 if sys.platform == "win32":
596 self.style.theme_use('winnative')
597 self.style.configure('.',background="white")
598 self.style.configure('.',foreground=_fgcolor)
599 self.style.configure('.',font="TkDefaultFont")
600 self.style.map('.',background=
601 [('selected', _compcolor), ('active',_ana2color)])
602
603 self.style.configure('Treeview', font="TkDefaultFont")
604 top.geometry("1250x500")
605 top.minsize(176, 1)
606 top.maxsize(1924, 1050)
607 top.resizable(1, 1)
608
609 top.title("PSA Test Suite Log Analysis Tool")
610 top.configure(background="white")
611 top.configure(highlightbackground="#d9d9d9")
612 top.configure(highlightcolor="black")
613 top.columnconfigure(0, weight=1)
614 top.columnconfigure(1, weight=2)
615 top.rowconfigure(0, weight=1)
616
617 self.Scrolledtext1 = ScrolledText(top, borderwidth=1)
618 self.Scrolledtext1.grid(row = 0, column = 1, sticky="NSEW")
619 self.Scrolledtext1.configure(background="white")
620 self.Scrolledtext1.configure(font="TkTextFont")
621 self.Scrolledtext1.configure(foreground="black")
622 self.Scrolledtext1.configure(highlightbackground="#d9d9d9")
623 self.Scrolledtext1.configure(highlightcolor="black")
624 self.Scrolledtext1.configure(insertbackground="black")
625 self.Scrolledtext1.configure(insertborderwidth="3")
626 self.Scrolledtext1.configure(selectbackground="#c4c4c4")
627 self.Scrolledtext1.configure(selectforeground="black")
628 self.Scrolledtext1.configure(wrap="none")
629
630 self.Scrolledtreeview1 = ScrolledTreeView(top)
631 self.Scrolledtreeview1.grid(row=0, column=0, sticky="NSEW")
632 self.Scrolledtreeview1.heading("#0",text="Test Suite")
633 self.Scrolledtreeview1.heading("#0",anchor="center")
634 self.Scrolledtreeview1.column("#0", width="10")
635 self.Scrolledtreeview1.column("#0",minwidth="250")
636 self.Scrolledtreeview1.column("#0",anchor="w")
637 self.Scrolledtreeview1.bind('<Double-Button-1>', onDoubleClick)
638 self.Scrolledtreeview1.bind('<Button-3>', onRightClick)
639
640 self.Menu1 = tk.Menu(top)
641 top.configure(menu=self.Menu1)
642 self.filemenu=tk.Menu(top)
643 self.Menu1.add_cascade(menu=self.filemenu, label="Menu")
644 self.filemenu.add_command(label="Select Log File", command=browseLogFile)
645 self.filemenu.add_command(label="Select Log Folder", command=browseLogFolder)
646 self.filemenu.add_command(label="Exit", command=top.quit)
647
648
649# The following code is added to facilitate the Scrolled widgets you specified.
650class AutoScroll(object):
651 '''Configure the scrollbars for a widget.'''
652 def __init__(self, master):
653 # Rozen. Added the try-except clauses so that this class
654 # could be used for scrolled entry widget for which vertical
655 # scrolling is not supported. 5/7/14.
656 try:
657 vsb = ttk.Scrollbar(master, orient='vertical', command=self.yview)
658 except:
659 pass
660 hsb = ttk.Scrollbar(master, orient='horizontal', command=self.xview)
661 try:
662 self.configure(yscrollcommand=self._autoscroll(vsb))
663 except:
664 pass
665 self.configure(xscrollcommand=self._autoscroll(hsb))
666 self.grid(column=0, row=0, sticky='nsew')
667 try:
668 vsb.grid(column=1, row=0, sticky='ns')
669 except:
670 pass
671 hsb.grid(column=0, row=1, sticky='ew')
672 master.grid_columnconfigure(0, weight=1)
673 master.grid_rowconfigure(0, weight=1)
674 # Copy geometry methods of master (taken from ScrolledText.py)
675 if py3:
676 methods = tk.Pack.__dict__.keys() | tk.Grid.__dict__.keys() \
677 | tk.Place.__dict__.keys()
678 else:
679 methods = tk.Pack.__dict__.keys() + tk.Grid.__dict__.keys() \
680 + tk.Place.__dict__.keys()
681 for meth in methods:
682 if meth[0] != '_' and meth not in ('config', 'configure'):
683 setattr(self, meth, getattr(master, meth))
684
685 @staticmethod
686 def _autoscroll(sbar):
687 '''Hide and show scrollbar as needed.'''
688 def wrapped(first, last):
689 first, last = float(first), float(last)
690 if first <= 0 and last >= 1:
691 sbar.grid_remove()
692 else:
693 sbar.grid()
694 sbar.set(first, last)
695 return wrapped
696
697 def __str__(self):
698 return str(self.master)
699
700def _create_container(func):
701 '''Creates a ttk Frame with a given master, and use this new frame to
702 place the scrollbars and the widget.'''
703 def wrapped(cls, master, **kw):
704 container = ttk.Frame(master)
705 container.bind('<Enter>', lambda e: _bound_to_mousewheel(e, container))
706 container.bind('<Leave>', lambda e: _unbound_to_mousewheel(e, container))
707 return func(cls, container, **kw)
708 return wrapped
709
710class ScrolledText(AutoScroll, tk.Text):
711 '''A standard Tkinter Text widget with scrollbars that will
712 automatically show/hide as needed.'''
713 @_create_container
714 def __init__(self, master, **kw):
715 tk.Text.__init__(self, master, **kw)
716 AutoScroll.__init__(self, master)
717
718class ScrolledTreeView(AutoScroll, ttk.Treeview):
719 '''A standard ttk Treeview widget with scrollbars that will
720 automatically show/hide as needed.'''
721 @_create_container
722 def __init__(self, master, **kw):
723 ttk.Treeview.__init__(self, master, **kw)
724 AutoScroll.__init__(self, master)
725
726
727import platform
728def _bound_to_mousewheel(event, widget):
729 child = widget.winfo_children()[0]
730 if platform.system() == 'Windows' or platform.system() == 'Darwin':
731 child.bind_all('<MouseWheel>', lambda e: _on_mousewheel(e, child))
732 child.bind_all('<Shift-MouseWheel>', lambda e: _on_shiftmouse(e, child))
733 else:
734 child.bind_all('<Button-4>', lambda e: _on_mousewheel(e, child))
735 child.bind_all('<Button-5>', lambda e: _on_mousewheel(e, child))
736 child.bind_all('<Shift-Button-4>', lambda e: _on_shiftmouse(e, child))
737 child.bind_all('<Shift-Button-5>', lambda e: _on_shiftmouse(e, child))
738
739def _unbound_to_mousewheel(event, widget):
740 if platform.system() == 'Windows' or platform.system() == 'Darwin':
741 widget.unbind_all('<MouseWheel>')
742 widget.unbind_all('<Shift-MouseWheel>')
743 else:
744 widget.unbind_all('<Button-4>')
745 widget.unbind_all('<Button-5>')
746 widget.unbind_all('<Shift-Button-4>')
747 widget.unbind_all('<Shift-Button-5>')
748
749def _on_mousewheel(event, widget):
750 if platform.system() == 'Windows':
751 widget.yview_scroll(-1*int(event.delta/120),'units')
752 elif platform.system() == 'Darwin':
753 widget.yview_scroll(-1*int(event.delta),'units')
754 else:
755 if event.num == 4:
756 widget.yview_scroll(-1, 'units')
757 elif event.num == 5:
758 widget.yview_scroll(1, 'units')
759
760def _on_shiftmouse(event, widget):
761 if platform.system() == 'Windows':
762 widget.xview_scroll(-1*int(event.delta/120), 'units')
763 elif platform.system() == 'Darwin':
764 widget.xview_scroll(-1*int(event.delta), 'units')
765 else:
766 if event.num == 4:
767 widget.xview_scroll(-1, 'units')
768 elif event.num == 5:
769 widget.xview_scroll(1, 'units')
770
771if __name__ == '__main__':
772 vp_start_gui()