Beispiel #1
0
class MainApplication():
    def __init__(self, master):

        self.filename = ""
        self.confg = ""
        self.master = master
        #setting color.
        bkc = "floral white"
        fgc = "RosyBrown4"
        bgc = "misty rose"

        self.FontForButton = tkFont.Font(family="Verdana", size=12)
        self.FontForLabel = tkFont.Font(family="Verdana", weight="bold")
        self.frame = tk.Frame(self.master, bg=bkc)
        self.frame.pack()
        self.chose_button = tk.Button(self.frame, text = u"選擇檔案", command = self.open_file, font=self.FontForButton, width = 20, bg=bgc, fg=fgc)
        self.chose_button.pack(padx = 5, pady = 10, side = tk.TOP)
        self.chose_confg_button = tk.Button(self.frame, text = u"選擇設定檔", command = self.get_confg, font=self.FontForButton, width = 20, bg=bgc, fg=fgc)
        self.chose_confg_button.pack(padx = 5, pady = 10, side = tk.TOP)
        self.run_button = tk.Button(self.frame, text = u"執行", command = self.run, font=self.FontForButton, width = 20, bg=bgc, fg=fgc)
        self.run_button.pack(padx = 5, pady = 10, side = tk.TOP)
        self.text = ScrolledText(self.frame)
        self.text.pack()
        self.mdby = tk.Label(self.frame, text="\nPowered By MITLab", font=self.FontForLabel, fg="SkyBlue1", bg=bkc)
        self.mdby.pack(side='bottom')

    def open_file(self):
        self.filename = tkFileDialog.askopenfilename()
        if self.filename :
            setup_env.display_message(u"選擇檔案: " + self.filename)

    def get_confg(self):
        self.confg = tkFileDialog.askopenfilename()
        if self.confg :
            setup_env.display_message(u"選擇設定檔案: " + self.confg)

    def write(self, massage):
        self.text.insert(tk.END, massage)
        self.text.see(tk.END)
        self.text.update_idletasks()#display message real time

    def run(self):
        try:
            if not self.filename or not self.confg:
                raise Exception('請選擇檔案!')
            setup_env.display_message(u"開始執行...")
            setup_env.set_environment(self.confg)
            table = rw_data.read_excel(self.filename, 0)
            rw_data.get_title_col(table)
            cmp_data.filter_data(table)
            cmp_data.cmp_data()
        except Exception as e:
            setup_env.display_message(e.message)
        finally:
            setup_env.clean_envirnoment()
Beispiel #2
0
class SigBridgeUI(Tk):
    server = None
    server_thread = None

    def __init__(self):
        Tk.__init__(self)

        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)

        # 2 rows: firts with settings, second with registrar data
        self.main_frame = Frame(self)
        # Commands row doesn't expands
        self.main_frame.rowconfigure(0, weight=0)
        # Logs row will grow
        self.main_frame.rowconfigure(1, weight=1)
        # Main frame can enlarge
        self.main_frame.columnconfigure(0, weight=1)
        self.main_frame.columnconfigure(1, weight=1)
        self.main_frame.grid(row=0, column=0)

        # Run/Stop button
        self.server_button = Button(self.main_frame, text="Connect", command=self.start_server)
        self.server_button.grid(row=0, column=0)

        # Clear button
        self.clear_button = Button(self.main_frame, text="Clear Log", command=self.clear_log)
        self.clear_button.grid(row=0, column=1)

        # Logs Widget
        self.log_widget = ScrolledText(self.main_frame)
        self.log_widget.grid(row=1, column=0, columnspan=2)
        # made not editable
        self.log_widget.config(state='disabled')

        # Queue where the logging handler will write
        self.log_queue = Queue.Queue()

        # Setup the logger
        self.uilogger = logging.getLogger('SigBridgeUI')
        self.uilogger.setLevel(logging.INFO)
        formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')

        # Use the QueueLogger as Handler
        hl = QueueLogger(queue=self.log_queue)
        hl.setFormatter(formatter)
        self.uilogger.addHandler(hl)

        # self.log_widget.update_idletasks()
        self.set_geometry()

        # Setup the update_widget callback reading logs from the queue
        self.start_log()

    def clear_log(self):
        self.log_widget.config(state='normal')
        self.log_widget.delete(0.0, END)
        self.log_widget.config(state='disabled')

    def start_log(self):
        self.uilogger.info("SigBridge Started.")
        self.update_widget()
        # self.control_log_button.configure(text="Pause Log", command=self.stop_log)

    def update_widget(self):
        self.log_widget.config(state='normal')
        # Read from the Queue and add to the log widger
        while not self.log_queue.empty():
            line = self.log_queue.get()
            tag = "error" if " ERROR " in line else 'info'
            self.log_widget.insert(END, line, tag)
            self.log_widget.see(END)  # Scroll to the bottom
            self.log_widget.update_idletasks()
        self.log_widget.tag_config('error', foreground="red")
        self.log_widget.config(state='disabled')
        self.log_widget.after(10, self.update_widget)

    def set_geometry(self):
        # set position in window
        w = 600  # width for the Tk
        h = 300  # height for the Tk

        # get screen width and height
        ws = self.winfo_screenwidth()   # width of the screen
        hs = self.winfo_screenheight()  # height of the screen

        # calculate x and y coordinates for the Tk window
        x = (ws/2) - (w/2)
        y = (hs/2) - (h/2)

        # set the dimensions of the screen 
        # and where it is placed
        self.geometry('%dx%d+%d+%d' % (w, h, x, y))

    def start_server(self):
        try:
            self.server = SigServer(('0.0.0.0', 25), None, self.uilogger)
            self.server_thread = threading.Thread(name='server', target=self.server.run)
            self.server_thread.daemon = True
            self.server_thread.start()
            self.server_button.configure(text="Disconnect", command=self.stop_server)
        except Exception as err:
            self.uilogger("Cannot start the server: %s" % err.message)

        # self.label_variable.set(self.entry_variable.get()+"(Started Signal Server)")
        # self.entry.focus_set()
        # self.entry.selection_range(0, END)

    def stop_server(self):
        self.server.shutdown()
        self.server_button.configure(text="Connect", command=self.start_server)
        self.server = None
Beispiel #3
0
class facades_main(Tkinter.Tk):
    
    def __init__(self, parent):
        Tkinter.Tk.__init__(self, parent)
        self.parent = parent

        self.initialize()
        self.clock_tick()

    def update_val_from_entry(self):
          global G_RUN_STATUS
          global G_SHUTDOWN_DELAY
          global G_WAKEUP_AFTER
          global G_LOOP_NUMBER
          global G_LONGRUN_ACTION
          G_SHUTDOWN_DELAY = int(self.entry_second.get(), base=10)
          G_WAKEUP_AFTER = int(self.entry_wakeafter.get(), base=10)
          G_LOOP_NUMBER = int(self.entry_loop.get(), base=10)
          G_LONGRUN_ACTION = self.var_action.get()

    def reset_rtcdata(self):
        efiapi = WinApiEfiVariables()
        rtcdata = efiapi.read(UEFI_VAR_NAME, UEFI_VAR_GUID)
        data = RtcWakeData(*struct.unpack_from(RTC_WAKE_DATA_FORMAT, rtcdata))
        #just reset to not wake up
        data2 = data._replace(Alarm_Wake=3,Alarm_Week=0, \
                          RtcWakeTime_Hour= 0, \
                          RtcWakeTime_Minute= 0, \
                          RtcWakeTime_Second= 0
                          )
        rtcdata = data2.packstring()
        efiapi.write(UEFI_VAR_NAME, UEFI_VAR_GUID, rtcdata)
        
    def func_shutdown(self):
        global G_CURRENT_LOOPNUM 
        G_CURRENT_LOOPNUM += 1
        self.confighandle.set_config('run_status', 'True')
        self.confighandle.set_config('current_loop', str(G_CURRENT_LOOPNUM))
        self.confighandle.update_file()
        
        if (G_LONGRUN_ACTION == 4):
          print "reboot"
          Hour = int(time.strftime("%H"), 10)
          Minute = int(time.strftime("%M"), 10)
          Second = int(time.strftime("%S"), 10)
          self.logger.info("reboot time: %d:%d:%d" %(Hour, Minute, Second))
          os.system('shutdown /r /f /t 0')
          while(1):
            pass

        efiapi = WinApiEfiVariables()
        rtcdata = efiapi.read(UEFI_VAR_NAME, UEFI_VAR_GUID)
        data = RtcWakeData(*struct.unpack_from(RTC_WAKE_DATA_FORMAT, rtcdata))

        (Hour, Minute, Second) = self.CalAlarmTimer()
        data2 = data._replace(Alarm_Wake=1,Alarm_Week=0, \
                          RtcWakeTime_Hour= Hour, \
                          RtcWakeTime_Minute= Minute, \
                          RtcWakeTime_Second= Second
                          )
        rtcdata = data2.packstring()
        efiapi.write(UEFI_VAR_NAME, UEFI_VAR_GUID, rtcdata)

        
        if (G_LONGRUN_ACTION == 3):
          print "shutdown"
          os.system('shutdown /s /f /t 0')
          
        if (G_LONGRUN_ACTION == 2):
          print "suspend"
          os.system('rundll32.exe PowrProf.dll,SetSuspendState')
        if (G_LONGRUN_ACTION == 1):
          print "sleep"
          os.system('rundll32.exe powrprof.dll,SetSuspendState 0,1,0')
        
    def CalAlarmTimer(self):
        Hour = int(time.strftime("%H"), 10)
        Minute = int(time.strftime("%M"), 10)
        Second = int(time.strftime("%S"), 10)
        print "current time:", Hour, Minute, Second
        print "wake after:", G_WAKEUP_AFTER
        self.logger.info("current time: %d:%d:%d" %(Hour, Minute, Second))
        #
        total_secs = Hour*3600 + Minute*60 + Second
        total_secs += G_WAKEUP_AFTER
        total_secs += G_SHUTDOWN_DELAY
        #
        Hour = total_secs / 3600
        Minute = (total_secs % 3600) / 60
        Second = (total_secs % 3600) % 60
        if Hour >= 24:
            Hour = 0
        print "wake time: %d:%d:%d" %(Hour, Minute, Second)
        self.logger.info("wake time: %d:%d:%d" %(Hour, Minute, Second))
        return (Hour,Minute,Second)

    def clock_tick(self):
        now = time.strftime("%H:%M:%S")
        self.label_ticker.configure(text=now)
        self.label_ticker.after(200, self.clock_tick)

    def clock_timeout(self):
        count = self.entry_second.get()
        #print count
        count = int(count, 10)
        print count
        if (G_RUN_STATUS):
          if (count > 0):
            self.count_second.set(count - 1)
            self._job = self.entry_second.after(1000, self.clock_timeout)
        if (count == 0):
            print "function to action!"
            self.func_shutdown()
        
    def initialize(self):
        global G_RUN_STATUS
        global G_SHUTDOWN_DELAY
        global G_WAKEUP_AFTER
        global G_LOOP_NUMBER
        global G_CURRENT_LOOPNUM
        global G_LONGRUN_ACTION
        self.geometry("400x450+300+100")
        self.minsize(350,250)
        self.grid()

        self._job = None
        self.confighandle = lrConfigParser(configfn)
        
        self.count_second = Tkinter.IntVar()
        self.str_action = Tkinter.StringVar()
        self.var_action = Tkinter.IntVar()
        self.loop_number = Tkinter.IntVar()
        self.current_loop = Tkinter.IntVar()
        self.wake_after = Tkinter.IntVar()
        self.str_start = Tkinter.StringVar()
              
        self.var_action.set(G_LONGRUN_ACTION )
        self.count_second.set(G_SHUTDOWN_DELAY)
        self.loop_number.set(G_LOOP_NUMBER)
        self.current_loop.set(G_CURRENT_LOOPNUM)
        self.wake_after.set(G_WAKEUP_AFTER)
        if (G_LONGRUN_ACTION == 4):
          self.str_action.set("reboot  ")
        if (G_LONGRUN_ACTION == 3):
          self.str_action.set("Shutdown")
        self.log_queue = Queue.Queue()
        
        self.label_blank = Tkinter.Label(self, text='')
        self.label_ticker = Tkinter.Label(self, text="test",anchor='e',font=('times', 20, 'bold'), bg='green')
        self.entry_second = Tkinter.Entry(self, text=self.count_second, font=('times', 20, 'bold'),width=5)
        self.label_str1 = Tkinter.Label(self, text='seconds to',font=('times', 20, 'bold'))
        self.label_str2 = Tkinter.Label(self, text='Loop',font=('times', 20, 'bold'))
        self.label_str3 = Tkinter.Label(self, text='seconds to',font=('times', 20, 'bold'))
        self.label_str4 = Tkinter.Label(self, text='wakeup', font=('times', 20, 'bold'))
        self.entry_wakeafter = Tkinter.Entry(self, text=self.wake_after, font=('times', 20, 'bold'),width=5)
        self.label_str_action = Tkinter.Label(self, textvariable=self.str_action, font=('times', 20, 'bold'))
        self.radiobtn_s3 = Tkinter.Radiobutton(self, text='S3',variable=self.var_action, value=1, command=self.radiobtn_callback, state='disabled')
        self.radiobtn_s4 = Tkinter.Radiobutton(self, text='S4',variable=self.var_action, value=2, command=self.radiobtn_callback, state='disabled')
        self.radiobtn_s5 = Tkinter.Radiobutton(self, text='S5',variable=self.var_action, value=3, command=self.radiobtn_callback)
        self.radiobtn_reboot = Tkinter.Radiobutton(self, text='reboot',variable=self.var_action, value=4, command=self.radiobtn_callback)
        self.entry_loop = Tkinter.Entry(self, text=self.loop_number, font=('times', 20, 'bold'),width=5)
        self.btn_start = Tkinter.Button(self, text="Start",bg="green",font=('times', 20, 'bold'), command=self.btn_start_callback)
        self.btn_edit = Tkinter.Button(self, text="Edit", font=('times', 20, 'bold'), state="disabled", command=self.btn_edit_callback)
        self.label_current_loop = Tkinter.Label(self, textvariable=self.current_loop, font=('times', 20, 'bold'))
        self.btn_clrlog = Tkinter.Button(self, text="Clear Log",font=('times', 15, 'bold'), command=self.btn_clearlog_callback)
        self.log_widget = ScrolledText(self, width = 50, heigh = 15)
        
        
        self.label_blank.grid(row=0,column=0,ipadx=20)
        self.label_ticker.grid(row=0,column=2,sticky='w')
        self.entry_second.grid(row=1,column=0)
        self.label_str1.grid(row=1,column=1,sticky='w')
        self.label_str_action.grid(row=1,column=2,sticky='w')
        self.entry_loop.grid(row=2,column=0)
        self.label_str2.grid(row=2, column=1,sticky='w')
        self.radiobtn_s3.grid(row=2,column=2,sticky='w')
        self.radiobtn_s4.grid(row=2,column=2,sticky='w', padx=40)
        self.radiobtn_s5.grid(row=2,column=2,sticky='w', padx=80)
        self.radiobtn_reboot.grid(row=2,column=2,sticky='w',padx=120)
        self.entry_wakeafter.grid(row=3, column=0)
        self.label_str3.grid(row=3, column=1)
        self.label_str4.grid(row=3, column=2,sticky='w')
        self.label_blank.grid(row=4,column=0)
        self.btn_start.grid(row=5, column=0)
        self.btn_edit.grid(row=5, column=1)
        self.btn_clrlog.grid(row=5,column=2,sticky='w')
        self.label_current_loop.grid(row=5, column=2,sticky='w',padx=120)
        self.log_widget.grid(row=6, column=0, columnspan=3, sticky='w')

        #init log queue
        self.logger = logging.getLogger(logfn)
        self.logger.setLevel(logging.INFO)
        logformat = logging.Formatter(LOG_FORMAT)
        hl = QueueLogger(queue=self.log_queue)
        hl.setFormatter(logformat)
        self.logger.addHandler(hl)

        self.start_logwidget()

        if G_CURRENT_LOOPNUM <= G_LOOP_NUMBER:
          if G_RUN_STATUS:
              print "auto run loop %d" %(G_CURRENT_LOOPNUM)
              self.logger.info("\ncurrent loop: %d" %(G_CURRENT_LOOPNUM))
              self.btn_start_callback()
        else:
          print "loop pass!"
          self.current_loop.set(G_CURRENT_LOOPNUM-1)
          
          if G_RUN_STATUS:
            print "reset run status here"
            G_RUN_STATUS = False
            G_CURRENT_LOOPNUM -= 1
            self.current_loop.set(str(G_CURRENT_LOOPNUM))
            self.confighandle.set_config('current_loop', str(G_CURRENT_LOOPNUM))
            self.confighandle.update_file()
            self.reset_rtcdata()

    def radiobtn_callback(self):
        global G_LONGRUN_ACTION
        seltmp = self.var_action.get()
        G_LONGRUN_ACTION = seltmp
        if (seltmp == 4):
            self.str_action.set("reboot")
        if (seltmp == 3):
            self.str_action.set("Shutdown")
        if (seltmp == 2):
            self.str_action.set("Suspend ")
        if (seltmp == 1):
            self.str_action.set("Sleep   ")

    def btn_clearlog_callback(self):
        global G_CURRENT_LOOPNUM
        self.log_widget.config(state='normal')
        self.log_widget.delete(0.0, Tkinter.END)
        self.log_widget.config(state='disabled')

        if os.path.isfile(logfn):
            with open(logfn, 'w'):
                pass
        #reset current loop to zero
        if G_CURRENT_LOOPNUM != 0:
          G_CURRENT_LOOPNUM = 0
          self.confighandle.set_config('current_loop', str(G_CURRENT_LOOPNUM))
          self.confighandle.update_file()
          self.current_loop.set(G_CURRENT_LOOPNUM)


    def btn_start_callback(self):
        global G_RUN_STATUS
        global G_EDITABLE
        if G_EDITABLE:
          G_EDITABLE = False
          print "set get from entry"
          self.update_val_from_entry()
          self.confighandle.set_config('shutdown_delay', str(G_SHUTDOWN_DELAY))
          self.confighandle.set_config('loop_number', str(G_LOOP_NUMBER))
          self.confighandle.set_config('wake_after', str(G_WAKEUP_AFTER))
          self.confighandle.set_config('longrun_action', str(G_LONGRUN_ACTION))
          self.confighandle.update_file()
        
        self.btn_start.config(text='Stop ', bg = "red", command=self.btn_stop_callback)
        self.entry_second.config(state='disabled')
        self.entry_loop.config(state='disabled')
        self.btn_edit.config(state='disabled')
        self.entry_wakeafter.config(state='disabled')
        G_EDITABLE = False

        if not G_RUN_STATUS:
          G_RUN_STATUS = True
        self.clock_timeout()
        

    def btn_stop_callback(self):
        global G_RUN_STATUS
        G_RUN_STATUS = False
        self.btn_start.config(text="Start", bg = "green", command=self.btn_start_callback)
        self.btn_edit.config(state='normal')
        
        self.confighandle.set_config('run_status', str(G_RUN_STATUS))
        self.confighandle.update_file()

        self.reset_rtcdata()


    def btn_edit_callback(self):
        global G_EDITABLE
        print "edit callback, to enable change variables"
        self.btn_edit.config(text="Apply", command=self.btn_apply_callback)
        self.entry_second.config(state='normal')
        self.entry_loop.config(state='normal')
        self.entry_wakeafter.config(state='normal')
        G_EDITABLE = True

    def btn_apply_callback(self):
        global G_EDITABLE
        print "apply callback, save changes to cfg file after edit"
        self.btn_edit.config(text="Edit", command=self.btn_edit_callback)
        self.entry_second.config(state='disabled')
        self.entry_loop.config(state='disabled')
        self.entry_wakeafter.config(state='disabled')
        G_EDITABLE = False
        
        self.update_val_from_entry()
        ##update into cfg file
        self.confighandle.set_config('shutdown_delay', str(G_SHUTDOWN_DELAY))
        self.confighandle.set_config('loop_number', str(G_LOOP_NUMBER))
        self.confighandle.set_config('wake_after', str(G_WAKEUP_AFTER))
        self.confighandle.set_config('longrun_action', str(G_LONGRUN_ACTION))
        self.confighandle.update_file()

    def start_logwidget(self):
        if os.path.isfile(logfn):
            self.log_widget.config(state='normal')
            print "read log file into log widget"
            with open(logfn) as fin:
                for line in fin:
                    self.log_widget.insert(Tkinter.END, line)
                    self.log_widget.see(Tkinter.END)
                    self.log_widget.update_idletasks()
            self.log_widget.config(state='disabled')

        self.update_logwidget(self.log_widget, self.log_queue)

    def update_logwidget(self, widget, queue):
        widget.config(state='normal')
        while not queue.empty():
            line = queue.get()
            widget.insert(Tkinter.END, line)
            widget.see(Tkinter.END)
            widget.update_idletasks()
        widget.config(state='disabled')
        self.logger_alarm = widget.after(10, self.update_logwidget, widget, queue)
Beispiel #4
0
class MainApplication():
    def __init__(self, master):

        self.filename = ""
        self.confg = ""
        self.master = master
        #setting color.
        bkc = "floral white"
        fgc = "RosyBrown4"
        bgc = "misty rose"

        self.FontForButton = tkFont.Font(family="Verdana", size=12)
        self.FontForLabel = tkFont.Font(family="Verdana", weight="bold")
        self.frame = tk.Frame(self.master, bg=bkc)
        self.frame.pack()
        self.chose_button = tk.Button(self.frame,
                                      text=u"選擇檔案",
                                      command=self.open_file,
                                      font=self.FontForButton,
                                      width=20,
                                      bg=bgc,
                                      fg=fgc)
        self.chose_button.pack(padx=5, pady=10, side=tk.TOP)
        self.chose_confg_button = tk.Button(self.frame,
                                            text=u"選擇設定檔",
                                            command=self.get_confg,
                                            font=self.FontForButton,
                                            width=20,
                                            bg=bgc,
                                            fg=fgc)
        self.chose_confg_button.pack(padx=5, pady=10, side=tk.TOP)
        self.run_button = tk.Button(self.frame,
                                    text=u"執行",
                                    command=self.run,
                                    font=self.FontForButton,
                                    width=20,
                                    bg=bgc,
                                    fg=fgc)
        self.run_button.pack(padx=5, pady=10, side=tk.TOP)
        self.text = ScrolledText(self.frame)
        self.text.pack()
        self.mdby = tk.Label(self.frame,
                             text="\nPowered By MITLab",
                             font=self.FontForLabel,
                             fg="SkyBlue1",
                             bg=bkc)
        self.mdby.pack(side='bottom')

    def open_file(self):
        self.filename = tkFileDialog.askopenfilename()
        if self.filename:
            setup_env.display_message(u"選擇檔案: " + self.filename)

    def get_confg(self):
        self.confg = tkFileDialog.askopenfilename()
        if self.confg:
            setup_env.display_message(u"選擇設定檔案: " + self.confg)

    def write(self, massage):
        self.text.insert(tk.END, massage)
        self.text.see(tk.END)
        self.text.update_idletasks()  #display message real time

    def run(self):
        try:
            if not self.filename or not self.confg:
                raise Exception('請選擇檔案!')
            setup_env.display_message(u"開始執行...")
            setup_env.set_environment(self.confg)
            table = rw_data.read_excel(self.filename, 0)
            rw_data.get_title_col(table)
            cmp_data.filter_data(table)
            cmp_data.cmp_data()
        except Exception as e:
            setup_env.display_message(e.message)
        finally:
            setup_env.clean_envirnoment()
Beispiel #5
0
class TermWindow(Frame):
    EOL = None

    ##
    # constructor method
    def __init__(self, master=None, **cnf):
        apply(Frame.__init__, (self, master), cnf)
        self.__create_widgets__()
        self.rxWaitPattern = ""
        self.localEcho = False
        self.logFile = None
        self.inQueue = Queue.Queue()
        self.outQueue = Queue.Queue()
        self.update_thread_safe()

    def update_thread_safe(self):
        while not self.inQueue.empty():
            element = self.inQueue.get_nowait()
            if element is not None:
                msg, tag = element
                self.__display__(msg, tag)
            self.st_trm.update_idletasks()
        self.st_trm.after(100, self.update_thread_safe)

    ##
    #
    def __create_widgets__(self):
        dfl_font = 'Courier 10'

        # the title frame of the terminal
        self.f_title = Frame(self)
        self.f_title.pack(fill=BOTH)
        self.f_title.configure(FRAMEBORDER)
        self.shVar = StringVar()
        # show/hide button
        self.b_sh = Button(self.f_title,
                           textvariable=self.shVar,
                           font=dfl_font)
        self.b_sh.pack(side=RIGHT)
        self.b_sh['command'] = self.show_hide_cont
        # clear screen button
        self.b_cls = Button(self.f_title,
                            text="CLS",
                            font=dfl_font,
                            underline=0)
        self.b_cls.pack(side=RIGHT)
        self.b_cls['command'] = self.clear_screen
        # echo on/off button
        self.al_echo = Label(self.f_title,
                             text="ECHO",
                             relief=RAISED,
                             font=dfl_font,
                             padx='3m',
                             pady='1m',
                             underline=0)
        self.al_echo.pack(side=RIGHT, padx=1, pady=1, fill=BOTH)
        self.al_echo.bind("<Button-1>", self.__echo_handler__)
        # log on/off button
        self.al_log = Label(self.f_title,
                            text="LOG",
                            relief=RAISED,
                            font=dfl_font,
                            padx='3m',
                            pady='1m',
                            underline=0)
        self.al_log.pack(side=RIGHT, padx=1, pady=1, fill=BOTH)
        self.al_log.bind("<Button-1>", self.__log_handler__)
        # device connect button
        self.al_connect = Label(self.f_title,
                                text="CONNECT",
                                relief=RAISED,
                                font=dfl_font,
                                padx='3m',
                                pady='1m',
                                underline=1)
        self.al_connect.pack(side=RIGHT, padx=1, pady=1, fill=BOTH)
        self.al_connect.bind("<Button-1>", self.__connect_handler__)

        self.mb_macros = Menubutton(self.f_title, text="Macros", relief=RAISED)
        self.mb_macros.pack(side=RIGHT, padx=1, pady=1, fill=BOTH)
        self.mb_macros.menu = Menu(self.mb_macros, tearoff=0)
        self.mb_macros["menu"] = self.mb_macros.menu

        # title of terminal window
        self.tVar = StringVar()
        self.l_title = Label(self.f_title, text="foo", font=dfl_font)
        self.l_title['textvariable'] = self.tVar
        self.l_title.pack(side=LEFT, expand=1, fill=X)
        self.l_title['width'] = 42
        self.update_title("------ XXX ------")
        # frame for scrolled text window
        # (this frame handle needs to be kept fo show_hide_cont())
        self.f_cont = Frame(self)
        # IO data scrolled text window
        self.st_trm = ScrolledText(self.f_cont,
                                   height=10,
                                   state=DISABLED,
                                   wrap=NONE)
        self.st_trm.pack(expand=1, fill=BOTH)
        self.st_trm['font'] = dfl_font
        self.st_trm.tag_config('E', foreground="blue")
        self.st_trm.tag_config('M', foreground="magenta")

        tframe = Frame(self.f_cont)
        tframe.pack(expand=0, fill=X)
        self.cmdVar = StringVar()
        self.ent_trm = Entry(tframe, textvariable=self.cmdVar, font=dfl_font)
        self.ent_trm.pack(side=LEFT, expand=1, fill=X)
        self.ent_trm.bind("<Control-l>", self.__log_handler__)
        self.ent_trm.bind("<Control-e>", self.__echo_handler__)
        self.ent_trm.bind("<Control-o>", self.__connect_handler__)
        self.ent_trm.bind("<Control-c>", self.clear_screen)
        self.ent_trm.bind("<Control-x>", self.show_hide_cont)
        self.ent_trm.bind("<Control-m>", lambda *args: self.do_macro("M"))
        self.ent_trm.bind("<KeyPress>", self.__input_handler__)

        self.gui_elements = [
            self.b_sh, self.b_cls, self.al_echo, self.al_log, self.al_connect,
            self.mb_macros, self.l_title, self.st_trm, self.ent_trm
        ]
        self.show_cont()

    def add_macro(self, id, title, text=None, function=None, params=None):
        if text:
            cmd = lambda *args: self.do_macro(text)
        if function:
            user_func = eval(function)
            if params:
                params = eval(str(params))
            else:
                params = {}
            cmd = lambda *args: user_func(self, DEVICES, **params)
        mb = self.mb_macros.menu.add_command(label=title, command=cmd)

    def _configure_(self, **args):
        for e in self.gui_elements:
            e.configure(args)

    def __input_handler__(self, *args):
        for i in args:
            self.terminal_device_write(i.char)

    def terminal_device_write(self, *args):
        for i in args:
            if self.localEcho:
                self.display(i, "E")
            if len(i):
                if i == "\r" or i == "\n":
                    self.device.write(self.EOL)
                    self.display(self.EOL, "E")
                    self.cmdVar.set("")
                else:
                    self.device.write(i)
        self.st_trm.update_idletasks()

    def __echo_handler__(self, *args):
        if self.localEcho:
            self.localEcho = False
            self.al_echo['relief'] = RAISED
            self.message("Local Echo OFF")
        else:
            self.localEcho = True
            self.al_echo['relief'] = SUNKEN
            self.message("Local Echo ON")

    def __log_handler__(self, *args):
        try:
            do_open = self.logFile.closed
            logname = self.logFile.name
        except:
            do_open = True
            logname = ""
        if do_open:
            if self.device.logname:
                logname = self.device.logname
                self.message("logfile from config file %s " % logname)
            else:
                fd = FileDialog(self)
                logname = fd.go(logname)
            try:
                if self.device.logmode not in "wa":
                    self.device.logmode = "a"
                    _print(3, "force _a_ppend")
                self.logFile = open(logname, self.device.logmode)
                self.al_log['relief'] = SUNKEN
                self.message("Logging ON: %s" % self.logFile.name)
            except:
                self.message("Error open logfile: %s" % logname)

        else:
            self.message("Logging OFF: %s" % self.logFile.name)
            self.logFile.flush()
            self.logFile.close()
            self.al_log['relief'] = RAISED

    def __connect_handler__(self, *args):
        if self.device.isConnected:
            self.device.disconnect()
            self.al_connect['relief'] = RAISED
            self.message("Disconnected")
        else:
            try:
                self.device.connect()
                self.al_connect['relief'] = SUNKEN
                self.message("Connected")
                self.al_connect['fg'] = "black"
            except:
                self.device.isConnected = False
                self.message(str(sys.exc_info()[1]))
                self.al_connect['fg'] = "red"

    def clear_screen(self, *args):
        self.st_trm['state'] = NORMAL
        self.st_trm.delete("0.0", END)
        self.st_trm['state'] = DISABLED

    def set_device(self, device):
        self.device = device
        self.device.configure(TxQueue=self.outQueue, RxQueue=self.inQueue)
        self.update_title(self.device)

        if self.device.log:
            self.__log_handler__()
        if self.device.auto_connect:
            self.__connect_handler__()

    def update_title(self, title):
        self.tVar.set(title)

    def show_cont(self):
        self.shVar.set("X")
        self.f_cont.pack(expand=1, fill=BOTH)

    def hide_cont(self):
        self.shVar.set("+")
        self.f_cont.pack_forget()

    def show_hide_cont(self, *args):
        if self.shVar.get() == "X":
            self.hide_cont()
        else:
            self.show_cont()

    def do_macro(self, *args):
        if self.localEcho:
            self.display(args[0] + "\n", "E")
        self.device.write(args[0] + "\n")

    def write(self, data):
        self.outQueue.put((data, None))

    def message(self, text, tag='M'):
        msg = "[%s:%s:%s]\n" % (time.asctime(), self.device.name, text)
        if self.st_trm.index(AtInsert()).find(".0") < 1:
            msg = "\n" + msg
        self.inQueue.put((msg, tag))

    def display(self, text, tag=None):
        self.inQueue.put((text, tag))

    def __display__(self, msg, tag=None):
        self.st_trm['state'] = NORMAL
        here = self.st_trm.index(AtInsert())
        for d in re.split("([\r\v\t\n])", msg):
            if len(d):
                if d != '\r':
                    self.st_trm.insert(END, d)
        if tag:
            self.st_trm.tag_add(tag, here, AtInsert())
        self.st_trm.see(END)
        self.st_trm['state'] = DISABLED
        try:
            self.logFile.write(msg)
            self.logFile.flush()
        except:
            pass