495 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			495 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			Python
		
	
	
	
import py
 | 
						|
from py.__.test.tkinter import backend
 | 
						|
from py.__.test.tkinter import util
 | 
						|
from py.__.test.tkinter import event
 | 
						|
Null = util.Null
 | 
						|
Event = event.Event
 | 
						|
 | 
						|
import ScrolledText
 | 
						|
from Tkinter import PhotoImage
 | 
						|
import Tkinter
 | 
						|
import re
 | 
						|
import os
 | 
						|
 | 
						|
myfont = ('Helvetica', 12, 'normal')
 | 
						|
 | 
						|
class StatusBar(Tkinter.Frame):
 | 
						|
 | 
						|
    font = ('Helvetica', 14, 'normal')
 | 
						|
 | 
						|
    def __init__(self, master=None, **kw):
 | 
						|
        if master is None:
 | 
						|
            master = Tk()
 | 
						|
        Tkinter.Frame.__init__(self, master, **kw)
 | 
						|
        self.labels = {}
 | 
						|
        self.callback = Null()
 | 
						|
        self.tkvariable_dict = {'failed': Tkinter.BooleanVar(),
 | 
						|
                                'skipped': Tkinter.BooleanVar(),
 | 
						|
                                'passed_item': Tkinter.BooleanVar()}
 | 
						|
        self.init_widgets()
 | 
						|
        
 | 
						|
    def init_widgets(self):
 | 
						|
        def get_button(text, var):
 | 
						|
            b = Tkinter.Checkbutton(self, text=text,
 | 
						|
                                    variable=var,
 | 
						|
                                    onvalue=True, offvalue=False,
 | 
						|
                                    anchor=Tkinter.W,
 | 
						|
                                    font=self.font, indicatoron = False,
 | 
						|
                                    command = self.do_callback)
 | 
						|
            b.select()
 | 
						|
            return b
 | 
						|
        
 | 
						|
        self.add_widget('Failed',
 | 
						|
                        get_button('Failed', self.tkvariable_dict['failed']))
 | 
						|
        self._get_widget('Failed').configure(bg = 'Red3', fg = 'White',
 | 
						|
                                             highlightcolor = 'Red',
 | 
						|
                                             selectcolor = 'Red',
 | 
						|
                                             activebackground= 'Red',
 | 
						|
                                             activeforeground = 'White')
 | 
						|
        self.add_widget('Skipped',
 | 
						|
                        get_button('Skipped', self.tkvariable_dict['skipped']))
 | 
						|
        self._get_widget('Skipped').configure(bg = 'Yellow3',
 | 
						|
                                              highlightcolor = 'Yellow',
 | 
						|
                                              selectcolor = 'Yellow',
 | 
						|
                                              activebackground= 'Yellow')
 | 
						|
        b = get_button('Passed', self.tkvariable_dict['passed_item'])
 | 
						|
        b.deselect()
 | 
						|
        self.add_widget('Passed', b)
 | 
						|
        self._get_widget('Passed').configure(bg = 'Green3', fg = 'Black',
 | 
						|
                                             highlightcolor = 'Black',
 | 
						|
                                             selectcolor = 'Green',
 | 
						|
                                             activeforeground = 'Black',
 | 
						|
                                             activebackground= 'Green')
 | 
						|
        
 | 
						|
    def set_filter_args_callback(self, callback):
 | 
						|
        self.callback = callback
 | 
						|
 | 
						|
    def do_callback(self,):
 | 
						|
        kwargs = dict([(key, var.get())
 | 
						|
                       for key, var in self.tkvariable_dict.items()])
 | 
						|
        self.callback(**kwargs)
 | 
						|
        
 | 
						|
    def set_label(self, name, text='', side=Tkinter.LEFT):
 | 
						|
        if not self.labels.has_key(name):
 | 
						|
            label = Tkinter.Label(self, bd=1, relief=Tkinter.SUNKEN,
 | 
						|
                                  anchor=Tkinter.W,
 | 
						|
                                  font=self.font)
 | 
						|
            self.add_widget(name, label, side)
 | 
						|
        else:
 | 
						|
            label = self.labels[name]
 | 
						|
        label.config(text='%s:\t%s' % (name,text))
 | 
						|
 | 
						|
    def add_widget(self, name, widget, side=Tkinter.LEFT):
 | 
						|
        widget.pack(side=side)
 | 
						|
        self.labels[name] = widget
 | 
						|
 | 
						|
    def _get_widget(self, name):
 | 
						|
        if not self.labels.has_key(name):
 | 
						|
            self.set_label(name, 'NoText')
 | 
						|
        return self.labels[name]
 | 
						|
 | 
						|
    def update_all(self, reportstore = Null(), ids = []):
 | 
						|
        self.set_label('Failed', str(len(reportstore.get(failed = True))))
 | 
						|
        self.set_label('Skipped', str(len(reportstore.get(skipped = True))))
 | 
						|
        self.set_label('Passed',
 | 
						|
                       str(len(reportstore.get(passed_item = True))))
 | 
						|
        root_report =  reportstore.root
 | 
						|
        if root_report.time < 7*24*60*60:
 | 
						|
            self.set_label('Time', '%0.2f seconds' % root_report.time)
 | 
						|
        else:
 | 
						|
            self.set_label('Time', '%0.2f seconds' % 0.0)
 | 
						|
 | 
						|
class ReportListBox(Tkinter.LabelFrame):
 | 
						|
 | 
						|
    font = myfont
 | 
						|
 | 
						|
    def __init__(self, *args, **kwargs):
 | 
						|
        Tkinter.LabelFrame.__init__(self, *args, **kwargs)
 | 
						|
        self.callback = Null()
 | 
						|
        self.data = {}
 | 
						|
        self.filter_kwargs = {'skipped': True, 'failed': True}
 | 
						|
        self.label = Tkinter.Label(self)
 | 
						|
        self.label.configure(font = self.font, width = 80, anchor = Tkinter.W) 
 | 
						|
        self.configure(labelwidget=self.label)
 | 
						|
        self.createwidgets()
 | 
						|
        self.label.configure(text = 'Idle')
 | 
						|
        self.configure(font = myfont)
 | 
						|
        
 | 
						|
        
 | 
						|
    def createwidgets(self):
 | 
						|
        self.listbox = Tkinter.Listbox(self,  foreground='red',
 | 
						|
                                   selectmode=Tkinter.SINGLE, font = self.font)
 | 
						|
 | 
						|
        self.scrollbar = Tkinter.Scrollbar(self, command=self.listbox.yview)
 | 
						|
        self.scrollbar.pack(side = Tkinter.RIGHT, fill = Tkinter.Y,
 | 
						|
                            anchor = Tkinter.N)
 | 
						|
        self.listbox.pack(side = Tkinter.LEFT,
 | 
						|
                          fill = Tkinter.BOTH, expand = Tkinter.YES,
 | 
						|
                          anchor = Tkinter.NW)
 | 
						|
        self.listbox.configure(yscrollcommand = self.scrollbar.set,
 | 
						|
                               bg = 'White',selectbackground= 'Red',
 | 
						|
                               takefocus= Tkinter.YES)
 | 
						|
 | 
						|
    def set_callback(self, callback):
 | 
						|
        self.callback = callback
 | 
						|
        self.listbox.bind('<Double-1>', self.do_callback)
 | 
						|
 | 
						|
    def do_callback(self, *args):
 | 
						|
        report_ids = [self.data[self.listbox.get(int(item))]
 | 
						|
                      for item in self.listbox.curselection()]
 | 
						|
        for report_id in report_ids:
 | 
						|
            self.callback(report_id)
 | 
						|
 | 
						|
    def set_filter_kwargs(self, **kwargs):
 | 
						|
        self.filter_kwargs = kwargs
 | 
						|
            
 | 
						|
    def update_label(self, report):
 | 
						|
        label = report.path
 | 
						|
        if not label:
 | 
						|
            label = 'Idle'
 | 
						|
        self.label.configure(text = label)
 | 
						|
 | 
						|
    def update_list(self, reportstore):
 | 
						|
        reports = reportstore.get(**self.filter_kwargs)
 | 
						|
        old_selections = [self.listbox.get(int(sel))
 | 
						|
                          for sel in self.listbox.curselection()]
 | 
						|
        self.listbox.delete(0, Tkinter.END)
 | 
						|
        self.data = {}
 | 
						|
        for report in reports:
 | 
						|
            label = '%s: %s' % (report.status, report.label)
 | 
						|
            self.data[label] = report.full_id
 | 
						|
            self.listbox.insert(Tkinter.END, label)
 | 
						|
            if label in old_selections:
 | 
						|
                self.listbox.select_set(Tkinter.END)
 | 
						|
                self.listbox.see(Tkinter.END)
 | 
						|
            
 | 
						|
            
 | 
						|
        
 | 
						|
 | 
						|
class LabelEntry(Tkinter.Frame):
 | 
						|
 | 
						|
    font = myfont
 | 
						|
 | 
						|
    def __init__(self, *args, **kwargs):    
 | 
						|
        Tkinter.Frame.__init__(self, *args, **kwargs)
 | 
						|
        self.label = Tkinter.Label(self)
 | 
						|
        self.label.configure(font = self.font)
 | 
						|
        self.label.pack(side = Tkinter.LEFT)
 | 
						|
        self.entry = Tkinter.Entry(self)
 | 
						|
        self.entry.configure(font = self.font)
 | 
						|
        self.entry.pack(side = Tkinter.LEFT, expand = Tkinter.YES,
 | 
						|
                        fill = Tkinter.X)
 | 
						|
 | 
						|
    def update(self, reportstore = Null(), ids = []):
 | 
						|
        bgcolor = 'White'
 | 
						|
        fgcolor = 'Black'
 | 
						|
        root_status = reportstore.root.status
 | 
						|
        if root_status == reportstore.ReportClass.Status.Passed():
 | 
						|
            bgcolor = 'Green'
 | 
						|
        elif root_status == reportstore.ReportClass.Status.Failed():
 | 
						|
            bgcolor = 'Red'
 | 
						|
            fgcolor = 'White'
 | 
						|
        elif root_status == reportstore.ReportClass.Status.Skipped() :
 | 
						|
            bgcolor = 'Yellow'
 | 
						|
        self.entry.configure(bg = bgcolor, fg = fgcolor)
 | 
						|
 | 
						|
class ReportFrame(Tkinter.LabelFrame):
 | 
						|
    font = myfont
 | 
						|
 | 
						|
    def __init__(self, *args, **kwargs):    
 | 
						|
        Tkinter.LabelFrame.__init__(self, *args, **kwargs)
 | 
						|
        self.report = Null()
 | 
						|
        self.label = Tkinter.Label(self,foreground="red", justify=Tkinter.LEFT)
 | 
						|
        self.label.pack(anchor=Tkinter.W)
 | 
						|
        self.label.configure(font = self.font)
 | 
						|
        self.configure(labelwidget = self.label)
 | 
						|
        self.text = ScrolledText.ScrolledText(self)
 | 
						|
        self.text.configure(bg = 'White', font = ('Helvetica', 11, 'normal'))
 | 
						|
        self.text.tag_config('sel', relief=Tkinter.FLAT)
 | 
						|
        self.text.pack(expand=Tkinter.YES, fill=Tkinter.BOTH,
 | 
						|
                       side = Tkinter.TOP)
 | 
						|
 | 
						|
    def set_report(self, report):
 | 
						|
        self.report = report
 | 
						|
        self.label.configure(text ='%s: %s' % (self.report.status,
 | 
						|
                                               self.report.label),
 | 
						|
                             foreground="red", justify=Tkinter.LEFT)
 | 
						|
        self.text['state'] = Tkinter.NORMAL
 | 
						|
        self.text.delete(1.0, Tkinter.END)
 | 
						|
        self.text.insert(Tkinter.END, self.report.error_report)
 | 
						|
        self.text.yview_pickplace(Tkinter.END)
 | 
						|
        self.text['state'] = Tkinter.DISABLED
 | 
						|
        self.attacheditorhotspots(self.text)
 | 
						|
        
 | 
						|
    def clear(self):
 | 
						|
        self.label.configure(text = '')
 | 
						|
        self.text['state'] = Tkinter.NORMAL
 | 
						|
        self.text.delete(1.0, Tkinter.END)
 | 
						|
        self.text['state'] = Tkinter.DISABLED
 | 
						|
        
 | 
						|
    def launch_editor(self, file, line):
 | 
						|
        editor = (py.std.os.environ.get('PYTHON_EDITOR', None) or
 | 
						|
                  py.std.os.environ.get('EDITOR_REMOTE', None) or
 | 
						|
                  os.environ.get('EDITOR', None) or "emacsclient --no-wait ")
 | 
						|
        if editor:
 | 
						|
            print "%s +%s %s" % (editor, line, file)
 | 
						|
            #py.process.cmdexec('%s +%s %s' % (editor, line, file))
 | 
						|
            os.system('%s +%s %s' % (editor, line, file))
 | 
						|
 | 
						|
    def attacheditorhotspots(self, text):
 | 
						|
        # Attach clickable regions to a Text widget.
 | 
						|
        filelink = re.compile(r"""\[(?:testcode\s*:)?\s*(.+):(\d+)\]""")
 | 
						|
        skippedlink = re.compile(r"""in\s+(/.*):(\d+)\s+""")
 | 
						|
        lines = text.get('1.0', Tkinter.END).splitlines(1)
 | 
						|
        if not lines:
 | 
						|
            return
 | 
						|
        tagname = ''
 | 
						|
        start, end = 0,0
 | 
						|
        for index, line in enumerate(lines):
 | 
						|
            match = filelink.search(line)
 | 
						|
            if match is None:
 | 
						|
                match = skippedlink.search(line)
 | 
						|
            if match is None:
 | 
						|
                continue
 | 
						|
            file, line = match.group(1, 2)
 | 
						|
            start, end = match.span()
 | 
						|
            tagname = "ref%d" % index
 | 
						|
            text.tag_add(tagname,
 | 
						|
                         "%d.%d" % (index + 1, start),
 | 
						|
                         "%d.%d" % (index + 1, end))
 | 
						|
            text.tag_bind(tagname, "<Enter>",
 | 
						|
                          lambda e, n=tagname:
 | 
						|
                          e.widget.tag_config(n, underline=1))
 | 
						|
            text.tag_bind(tagname, "<Leave>",
 | 
						|
                          lambda e, n=tagname:
 | 
						|
                          e.widget.tag_config(n, underline=0))
 | 
						|
            text.tag_bind(tagname, "<Button-1>",
 | 
						|
                          lambda e, self=self, f=file, l=line:
 | 
						|
                          self.launch_editor(f, l))
 | 
						|
 | 
						|
 | 
						|
class MinimalButton(Tkinter.Button):
 | 
						|
 | 
						|
    format_string = '%dF / %dS / %dP'
 | 
						|
    
 | 
						|
    def __init__(self, *args, **kwargs):
 | 
						|
        Tkinter.Button.__init__(self, *args, **kwargs)
 | 
						|
        self.configure(text = 'Start/Stop') #self.format_string % (0,0,0))
 | 
						|
 | 
						|
    def update_label(self, reportstore):
 | 
						|
        failed = len(reportstore.get(failed = True))
 | 
						|
        skipped = len(reportstore.get(skipped = True))
 | 
						|
        passed = len(reportstore.get(passed_item = True))
 | 
						|
        #self.configure(text = self.format_string % (failed, skipped, passed))
 | 
						|
        bgcolor = 'Green'
 | 
						|
        fgcolor = 'Black'
 | 
						|
        highlightcolor = 'Green',
 | 
						|
        activebackground= 'Green',
 | 
						|
        activeforeground = 'Black'
 | 
						|
        
 | 
						|
        if skipped > 0:
 | 
						|
            bgcolor = 'Yellow'
 | 
						|
            activebackground = 'Yellow'
 | 
						|
        if failed > 0:
 | 
						|
            bgcolor = 'Red'
 | 
						|
            fgcolor = 'White'
 | 
						|
            activebackground= 'Red',
 | 
						|
            activeforeground = 'White'
 | 
						|
            
 | 
						|
        self.configure(bg = bgcolor, fg = fgcolor,
 | 
						|
                       highlightcolor = highlightcolor,
 | 
						|
                       activeforeground = activeforeground,
 | 
						|
                       activebackground = activebackground)
 | 
						|
        
 | 
						|
class LayoutManager:
 | 
						|
 | 
						|
    def __init__(self):
 | 
						|
        self.current_layout = 0
 | 
						|
        self.layout_dict = {}
 | 
						|
        
 | 
						|
    def add(self, widget, layout_ids, **kwargs):
 | 
						|
        for id in layout_ids:
 | 
						|
            list = self.layout_dict.setdefault(id, [])
 | 
						|
            list.append((widget, kwargs))
 | 
						|
    
 | 
						|
    def set_layout(self, layout = 0):
 | 
						|
        if self.current_layout != layout:
 | 
						|
            widget_list = self.layout_dict.get(self.current_layout, [])
 | 
						|
            for widget, kwargs in widget_list:
 | 
						|
                widget.pack_forget()
 | 
						|
        self.current_layout = layout
 | 
						|
        widget_list = self.layout_dict.get(self.current_layout, [])
 | 
						|
        for widget, kwargs in widget_list:
 | 
						|
            widget.pack(**kwargs)
 | 
						|
        
 | 
						|
                      
 | 
						|
class TkGui:
 | 
						|
 | 
						|
    font = ('Helvetica', 9, 'normal')
 | 
						|
    
 | 
						|
    def __init__(self, parent, config):
 | 
						|
        self._parent = parent
 | 
						|
        self._config = config
 | 
						|
        self._should_stop = False
 | 
						|
        #XXX needed?
 | 
						|
        self._paths = []
 | 
						|
        self.backend = backend.ReportBackend(config)
 | 
						|
        self._layoutmanager = LayoutManager()
 | 
						|
 | 
						|
        self._layout_toggle_var = Tkinter.StringVar()
 | 
						|
        self._layout_toggle_var.set('<')
 | 
						|
        # events
 | 
						|
        self.on_report_updated = Event()
 | 
						|
        self.on_report_store_updated = Event()
 | 
						|
        self.on_show_report = Event()
 | 
						|
        self.on_run_tests = Event()
 | 
						|
 | 
						|
        self.createwidgets()
 | 
						|
        self.timer_update()
 | 
						|
        self.report_window = Null()
 | 
						|
        self.report_frame = Null()
 | 
						|
 | 
						|
 | 
						|
    def createwidgets(self):
 | 
						|
        add = self._layoutmanager.add
 | 
						|
        self._buttonframe = Tkinter.Frame(self._parent)
 | 
						|
        self._layoutbutton = Tkinter.Button(self._buttonframe, padx=0,
 | 
						|
                                            relief=Tkinter.GROOVE,
 | 
						|
                                            textvariable=self._layout_toggle_var,
 | 
						|
                                            command=self.toggle_layout)        
 | 
						|
        add(self._layoutbutton, [0,1], side= Tkinter.LEFT)
 | 
						|
        self._entry = LabelEntry(self._buttonframe)
 | 
						|
        self._entry.label.configure(text = 'Enter test name:')
 | 
						|
        self._entry.entry.bind('<Return>', self.start_tests)
 | 
						|
        add(self._entry, [0], side = Tkinter.LEFT, fill = Tkinter.X,
 | 
						|
            expand = Tkinter.YES)
 | 
						|
 | 
						|
        self._run_stop_button = Tkinter.Button(self._buttonframe, text = 'Run',
 | 
						|
                               command = self.toggle_action, font = self.font)
 | 
						|
        add(self._run_stop_button, [0], side = Tkinter.RIGHT)
 | 
						|
 | 
						|
        self._minimalbutton = MinimalButton(self._buttonframe, font = self.font,
 | 
						|
                                            command = self.toggle_action)
 | 
						|
        add(self._minimalbutton, [1], side = Tkinter.RIGHT,
 | 
						|
            fill = Tkinter.X, expand = Tkinter.YES)
 | 
						|
        add(self._buttonframe, [0,1], side = Tkinter.TOP, fill = Tkinter.X)
 | 
						|
 | 
						|
        self._statusbar = StatusBar(self._parent)
 | 
						|
        self._statusbar.set_filter_args_callback(self.filter_args_changed)
 | 
						|
        add(self._statusbar, [0,1], side= Tkinter.BOTTOM, fill=Tkinter.X)
 | 
						|
 | 
						|
        self._reportlist = ReportListBox(self._parent)
 | 
						|
        add(self._reportlist, [0], side = Tkinter.TOP, fill = Tkinter.BOTH,
 | 
						|
            expand = Tkinter.YES)
 | 
						|
        self._reportlist.set_callback(self.show_report)
 | 
						|
        self._report_frame = ReportFrame(self._parent)
 | 
						|
        add(self._report_frame, [0], side = Tkinter.TOP, fill = Tkinter.BOTH,
 | 
						|
            expand = Tkinter.YES)
 | 
						|
        
 | 
						|
        #self.on_show_report.subscribe(self.show_report)
 | 
						|
        self.on_report_updated.subscribe(self._reportlist.update_label)
 | 
						|
        self.on_report_store_updated.subscribe(self._reportlist.update_list)
 | 
						|
        self.on_report_store_updated.subscribe(self._minimalbutton.update_label)
 | 
						|
        self.on_report_store_updated.subscribe(self.update_status)
 | 
						|
 | 
						|
        self._layoutmanager.set_layout(0)        
 | 
						|
        self.update_status(self.backend.get_store())
 | 
						|
        self.messages_callback(None)
 | 
						|
        
 | 
						|
    def toggle_layout(self):
 | 
						|
        if self._layout_toggle_var.get() == '>':
 | 
						|
            self._layout_toggle_var.set('<')
 | 
						|
            self._layoutmanager.set_layout(0)
 | 
						|
        else:
 | 
						|
            self._layout_toggle_var.set('>')
 | 
						|
            self._layoutmanager.set_layout(1)
 | 
						|
        self._parent.geometry('')
 | 
						|
 | 
						|
    def filter_args_changed(self, **kwargs):
 | 
						|
        self._reportlist.set_filter_kwargs(**kwargs)
 | 
						|
        self._reportlist.update_list(self.backend.get_store())
 | 
						|
 | 
						|
    def show_report(self, report_id):
 | 
						|
        if report_id is None:
 | 
						|
            self._report_frame.clear()
 | 
						|
        else:
 | 
						|
            report = self.backend.get_store().get(id = report_id)[0]
 | 
						|
            self._report_frame.set_report(report)
 | 
						|
 | 
						|
    def show_error_window(self, report_id):
 | 
						|
        report = self.backend.get_store().get(id = report_id)[0]
 | 
						|
        if not self.report_window:
 | 
						|
            self.report_window = Tkinter.Toplevel(self._parent)
 | 
						|
            self.report_window.protocol('WM_DELETE_WINDOW',
 | 
						|
                                        self.report_window.withdraw)
 | 
						|
            b = Tkinter.Button(self.report_window, text="Close",
 | 
						|
                               command=self.report_window.withdraw)
 | 
						|
            b.pack(side=Tkinter.BOTTOM)
 | 
						|
            #b.focus_set()
 | 
						|
            self.report_frame = ReportFrame(self.report_window)
 | 
						|
            self.report_frame.pack()
 | 
						|
        elif self.report_window.state() != Tkinter.NORMAL:
 | 
						|
            self.report_window.deiconify()
 | 
						|
            
 | 
						|
        self.report_window.title(report.label)    
 | 
						|
        self.report_frame.set_report(report)
 | 
						|
 | 
						|
 | 
						|
    def timer_update(self):
 | 
						|
        self.backend.update()
 | 
						|
        if self.backend.running:
 | 
						|
            action = 'Stop'
 | 
						|
        else:
 | 
						|
            action = 'Run'
 | 
						|
        self._run_stop_button.configure(text = action)
 | 
						|
        self._minimalbutton.configure(text = action)
 | 
						|
        self._parent.after(200, self.timer_update)
 | 
						|
 | 
						|
    def start_tests(self, dont_care_event=None):
 | 
						|
        if self.backend.running:
 | 
						|
            return
 | 
						|
        paths = [path.strip() for path in self._entry.entry.get().split(',')]
 | 
						|
        self.backend.set_messages_callback(self.messages_callback)
 | 
						|
        self.backend.set_message_callback(self.message_callback)
 | 
						|
        self.backend.start_tests(args = paths)
 | 
						|
 | 
						|
        self.show_report(None)
 | 
						|
 | 
						|
    def update_status(self, reportstore):
 | 
						|
        self._statusbar.update_all(reportstore = reportstore, ids = [])
 | 
						|
        self._entry.update(reportstore = reportstore, ids = [])
 | 
						|
                
 | 
						|
    def messages_callback(self, report_ids):
 | 
						|
        if not report_ids:
 | 
						|
            return
 | 
						|
        self.on_report_store_updated(self.backend.get_store())
 | 
						|
 | 
						|
    def message_callback(self, report_id):
 | 
						|
        if report_id is None:
 | 
						|
            report = Null()
 | 
						|
        else:
 | 
						|
            report = self.backend.get_store().get(id = report_id)[0]
 | 
						|
        self.on_report_updated(report)
 | 
						|
        
 | 
						|
    def set_paths(self, paths):
 | 
						|
        self._paths = paths
 | 
						|
        self._entry.entry.insert(Tkinter.END, ', '.join(paths))
 | 
						|
 | 
						|
    def toggle_action(self):
 | 
						|
        if self.backend.running:
 | 
						|
            self.stop()
 | 
						|
        else:
 | 
						|
            self.start_tests()
 | 
						|
 | 
						|
    def stop(self):
 | 
						|
        self.backend.shutdown()
 | 
						|
        self.backend.update()
 | 
						|
        self.messages_callback([None])
 | 
						|
        self.message_callback(None)
 | 
						|
 | 
						|
    def shutdown(self):
 | 
						|
        self.should_stop = True
 | 
						|
        self.backend.shutdown()
 | 
						|
        py.std.sys.exit()
 | 
						|
 |