def on_b1_press_dt(self, event): item = self.device_tree.identify('item', event.x, event.y) if item: self.add_button.config(state="active") for widget in self.fr.winfo_children(): widget.destroy() dt_type = self.device_tree.item(item, "text") self.v = StringVar() self.v.set(dt_type) # initialize b = Radiobutton(self.fr, text=dt_type, variable=self.v, value=dt_type) b.pack(anchor="w") macros = self.device_tree.item(item, "values")[0] if not macros == "None": l = macros.split(" ") for mstr in l: b = Radiobutton(self.fr, text=mstr, variable=self.v, value=mstr) b.pack(anchor="w") b.select()
def _create_ui(self): '''Create the UI for this panel.''' self._ship_var = IntVar() self.ship_buttons = {} for i, ship in enumerate(Ship.SHORT_NAMES): b = Radiobutton(self, text=Ship.NAMES[ship].title(), value=i, variable=self._ship_var, indicatoron=False) b.pack(anchor=W, pady=10) b.grid(sticky=N + S + E + W) # and a sort-of experimental feature... b.ship_state = self.UNPLACED # save it self.ship_buttons[ship] = b
def init_gui(self): """init helper""" window = PanedWindow(self.root, orient="vertical") window.pack(side=TOP, fill=BOTH, expand=True) top_pane = Frame(window) window.add(top_pane) mid_pane = Frame(window) window.add(mid_pane) bottom_pane = Frame(window) window.add(bottom_pane) #setting up frames top_frame = Frame(top_pane) mid_frame = Frame(top_pane) history_frame = Frame(top_pane) radio_frame = Frame(mid_pane) rating_frame = Frame(mid_pane) res_frame = Frame(mid_pane) check_frame = Frame(bottom_pane) msg_frame = Frame(bottom_pane) btn_frame = Frame(bottom_pane) top_frame.pack(side=TOP, fill=X) mid_frame.pack(side=TOP, fill=X) history_frame.pack(side=TOP, fill=BOTH, expand=True) radio_frame.pack(side=TOP, fill=X) rating_frame.pack(side=TOP, fill=X) res_frame.pack(side=TOP, fill=BOTH, expand=True) check_frame.pack(side=TOP, fill=X) msg_frame.pack(side=TOP, fill=BOTH, expand=True) btn_frame.pack(side=TOP, fill=X) # Binding F5 application-wide to run lint self.root.bind('<F5>', self.run_lint) #Message ListBox rightscrollbar = Scrollbar(msg_frame) rightscrollbar.pack(side=RIGHT, fill=Y) bottomscrollbar = Scrollbar(msg_frame, orient=HORIZONTAL) bottomscrollbar.pack(side=BOTTOM, fill=X) self.lb_messages = Listbox( msg_frame, yscrollcommand=rightscrollbar.set, xscrollcommand=bottomscrollbar.set, bg="white") self.lb_messages.bind("<Double-Button-1>", self.show_sourcefile) self.lb_messages.pack(expand=True, fill=BOTH) rightscrollbar.config(command=self.lb_messages.yview) bottomscrollbar.config(command=self.lb_messages.xview) #History ListBoxes rightscrollbar2 = Scrollbar(history_frame) rightscrollbar2.pack(side=RIGHT, fill=Y) bottomscrollbar2 = Scrollbar(history_frame, orient=HORIZONTAL) bottomscrollbar2.pack(side=BOTTOM, fill=X) self.showhistory = Listbox( history_frame, yscrollcommand=rightscrollbar2.set, xscrollcommand=bottomscrollbar2.set, bg="white") self.showhistory.pack(expand=True, fill=BOTH) rightscrollbar2.config(command=self.showhistory.yview) bottomscrollbar2.config(command=self.showhistory.xview) self.showhistory.bind('<Double-Button-1>', self.select_recent_file) self.set_history_window() #status bar self.status = Label(self.root, text="", bd=1, relief=SUNKEN, anchor=W) self.status.pack(side=BOTTOM, fill=X) #labelbl_ratingls lbl_rating_label = Label(rating_frame, text='Rating:') lbl_rating_label.pack(side=LEFT) lbl_rating = Label(rating_frame, textvariable=self.rating) lbl_rating.pack(side=LEFT) Label(mid_frame, text='Recently Used:').pack(side=LEFT) Label(top_frame, text='Module or package').pack(side=LEFT) #file textbox self.txt_module = Entry(top_frame, background='white') self.txt_module.bind('<Return>', self.run_lint) self.txt_module.pack(side=LEFT, expand=True, fill=X) #results box rightscrollbar = Scrollbar(res_frame) rightscrollbar.pack(side=RIGHT, fill=Y) bottomscrollbar = Scrollbar(res_frame, orient=HORIZONTAL) bottomscrollbar.pack(side=BOTTOM, fill=X) self.results = Listbox( res_frame, yscrollcommand=rightscrollbar.set, xscrollcommand=bottomscrollbar.set, bg="white", font="Courier") self.results.pack(expand=True, fill=BOTH, side=BOTTOM) rightscrollbar.config(command=self.results.yview) bottomscrollbar.config(command=self.results.xview) #buttons Button(top_frame, text='Open', command=self.file_open).pack(side=LEFT) Button(top_frame, text='Open Package', command=(lambda: self.file_open(package=True))).pack(side=LEFT) self.btnRun = Button(top_frame, text='Run', command=self.run_lint) self.btnRun.pack(side=LEFT) Button(btn_frame, text='Quit', command=self.quit).pack(side=BOTTOM) #radio buttons self.information_box = IntVar() self.convention_box = IntVar() self.refactor_box = IntVar() self.warning_box = IntVar() self.error_box = IntVar() self.fatal_box = IntVar() i = Checkbutton(check_frame, text="Information", fg=COLORS['(I)'], variable=self.information_box, command=self.refresh_msg_window) c = Checkbutton(check_frame, text="Convention", fg=COLORS['(C)'], variable=self.convention_box, command=self.refresh_msg_window) r = Checkbutton(check_frame, text="Refactor", fg=COLORS['(R)'], variable=self.refactor_box, command=self.refresh_msg_window) w = Checkbutton(check_frame, text="Warning", fg=COLORS['(W)'], variable=self.warning_box, command=self.refresh_msg_window) e = Checkbutton(check_frame, text="Error", fg=COLORS['(E)'], variable=self.error_box, command=self.refresh_msg_window) f = Checkbutton(check_frame, text="Fatal", fg=COLORS['(F)'], variable=self.fatal_box, command=self.refresh_msg_window) i.select() c.select() r.select() w.select() e.select() f.select() i.pack(side=LEFT) c.pack(side=LEFT) r.pack(side=LEFT) w.pack(side=LEFT) e.pack(side=LEFT) f.pack(side=LEFT) #check boxes self.box = StringVar() # XXX should be generated report = Radiobutton( radio_frame, text="Report", variable=self.box, value="Report", command=self.refresh_results_window) raw_met = Radiobutton( radio_frame, text="Raw metrics", variable=self.box, value="Raw metrics", command=self.refresh_results_window) dup = Radiobutton( radio_frame, text="Duplication", variable=self.box, value="Duplication", command=self.refresh_results_window) ext = Radiobutton( radio_frame, text="External dependencies", variable=self.box, value="External dependencies", command=self.refresh_results_window) stat = Radiobutton( radio_frame, text="Statistics by type", variable=self.box, value="Statistics by type", command=self.refresh_results_window) msg_cat = Radiobutton( radio_frame, text="Messages by category", variable=self.box, value="Messages by category", command=self.refresh_results_window) msg = Radiobutton( radio_frame, text="Messages", variable=self.box, value="Messages", command=self.refresh_results_window) source_file = Radiobutton( radio_frame, text="Source File", variable=self.box, value="Source File", command=self.refresh_results_window) report.select() report.grid(column=0, row=0, sticky=W) raw_met.grid(column=1, row=0, sticky=W) dup.grid(column=2, row=0, sticky=W) msg.grid(column=3, row=0, sticky=W) stat.grid(column=0, row=1, sticky=W) msg_cat.grid(column=1, row=1, sticky=W) ext.grid(column=2, row=1, sticky=W) source_file.grid(column=3, row=1, sticky=W) #dictionary for check boxes and associated error term self.msg_type_dict = { 'I': lambda: self.information_box.get() == 1, 'C': lambda: self.convention_box.get() == 1, 'R': lambda: self.refactor_box.get() == 1, 'E': lambda: self.error_box.get() == 1, 'W': lambda: self.warning_box.get() == 1, 'F': lambda: self.fatal_box.get() == 1 } self.txt_module.focus_set()
def init_gui(self): """init helper""" window = PanedWindow(self.root, orient="vertical") window.pack(side=TOP, fill=BOTH, expand=True) top_pane = Frame(window) window.add(top_pane) mid_pane = Frame(window) window.add(mid_pane) bottom_pane = Frame(window) window.add(bottom_pane) #setting up frames top_frame = Frame(top_pane) mid_frame = Frame(top_pane) history_frame = Frame(top_pane) radio_frame = Frame(mid_pane) rating_frame = Frame(mid_pane) res_frame = Frame(mid_pane) check_frame = Frame(bottom_pane) msg_frame = Frame(bottom_pane) btn_frame = Frame(bottom_pane) top_frame.pack(side=TOP, fill=X) mid_frame.pack(side=TOP, fill=X) history_frame.pack(side=TOP, fill=BOTH, expand=True) radio_frame.pack(side=TOP, fill=X) rating_frame.pack(side=TOP, fill=X) res_frame.pack(side=TOP, fill=BOTH, expand=True) check_frame.pack(side=TOP, fill=X) msg_frame.pack(side=TOP, fill=BOTH, expand=True) btn_frame.pack(side=TOP, fill=X) # Binding F5 application-wide to run lint self.root.bind('<F5>', self.run_lint) #Message ListBox rightscrollbar = Scrollbar(msg_frame) rightscrollbar.pack(side=RIGHT, fill=Y) bottomscrollbar = Scrollbar(msg_frame, orient=HORIZONTAL) bottomscrollbar.pack(side=BOTTOM, fill=X) self.lb_messages = Listbox(msg_frame, yscrollcommand=rightscrollbar.set, xscrollcommand=bottomscrollbar.set, bg="white") self.lb_messages.bind("<Double-Button-1>", self.show_sourcefile) self.lb_messages.pack(expand=True, fill=BOTH) rightscrollbar.config(command=self.lb_messages.yview) bottomscrollbar.config(command=self.lb_messages.xview) #History ListBoxes rightscrollbar2 = Scrollbar(history_frame) rightscrollbar2.pack(side=RIGHT, fill=Y) bottomscrollbar2 = Scrollbar(history_frame, orient=HORIZONTAL) bottomscrollbar2.pack(side=BOTTOM, fill=X) self.showhistory = Listbox(history_frame, yscrollcommand=rightscrollbar2.set, xscrollcommand=bottomscrollbar2.set, bg="white") self.showhistory.pack(expand=True, fill=BOTH) rightscrollbar2.config(command=self.showhistory.yview) bottomscrollbar2.config(command=self.showhistory.xview) self.showhistory.bind('<Double-Button-1>', self.select_recent_file) self.set_history_window() #status bar self.status = Label(self.root, text="", bd=1, relief=SUNKEN, anchor=W) self.status.pack(side=BOTTOM, fill=X) #labelbl_ratingls lbl_rating_label = Label(rating_frame, text='Rating:') lbl_rating_label.pack(side=LEFT) lbl_rating = Label(rating_frame, textvariable=self.rating) lbl_rating.pack(side=LEFT) Label(mid_frame, text='Recently Used:').pack(side=LEFT) Label(top_frame, text='Module or package').pack(side=LEFT) #file textbox self.txt_module = Entry(top_frame, background='white') self.txt_module.bind('<Return>', self.run_lint) self.txt_module.pack(side=LEFT, expand=True, fill=X) #results box rightscrollbar = Scrollbar(res_frame) rightscrollbar.pack(side=RIGHT, fill=Y) bottomscrollbar = Scrollbar(res_frame, orient=HORIZONTAL) bottomscrollbar.pack(side=BOTTOM, fill=X) self.results = Listbox(res_frame, yscrollcommand=rightscrollbar.set, xscrollcommand=bottomscrollbar.set, bg="white", font="Courier") self.results.pack(expand=True, fill=BOTH, side=BOTTOM) rightscrollbar.config(command=self.results.yview) bottomscrollbar.config(command=self.results.xview) #buttons Button(top_frame, text='Open', command=self.file_open).pack(side=LEFT) Button(top_frame, text='Open Package', command=(lambda: self.file_open(package=True))).pack(side=LEFT) self.btnRun = Button(top_frame, text='Run', command=self.run_lint) self.btnRun.pack(side=LEFT) Button(btn_frame, text='Quit', command=self.quit).pack(side=BOTTOM) #radio buttons self.information_box = IntVar() self.convention_box = IntVar() self.refactor_box = IntVar() self.warning_box = IntVar() self.error_box = IntVar() self.fatal_box = IntVar() i = Checkbutton(check_frame, text="Information", fg=COLORS['(I)'], variable=self.information_box, command=self.refresh_msg_window) c = Checkbutton(check_frame, text="Convention", fg=COLORS['(C)'], variable=self.convention_box, command=self.refresh_msg_window) r = Checkbutton(check_frame, text="Refactor", fg=COLORS['(R)'], variable=self.refactor_box, command=self.refresh_msg_window) w = Checkbutton(check_frame, text="Warning", fg=COLORS['(W)'], variable=self.warning_box, command=self.refresh_msg_window) e = Checkbutton(check_frame, text="Error", fg=COLORS['(E)'], variable=self.error_box, command=self.refresh_msg_window) f = Checkbutton(check_frame, text="Fatal", fg=COLORS['(F)'], variable=self.fatal_box, command=self.refresh_msg_window) i.select() c.select() r.select() w.select() e.select() f.select() i.pack(side=LEFT) c.pack(side=LEFT) r.pack(side=LEFT) w.pack(side=LEFT) e.pack(side=LEFT) f.pack(side=LEFT) #check boxes self.box = StringVar() # XXX should be generated report = Radiobutton(radio_frame, text="Report", variable=self.box, value="Report", command=self.refresh_results_window) raw_met = Radiobutton(radio_frame, text="Raw metrics", variable=self.box, value="Raw metrics", command=self.refresh_results_window) dup = Radiobutton(radio_frame, text="Duplication", variable=self.box, value="Duplication", command=self.refresh_results_window) ext = Radiobutton(radio_frame, text="External dependencies", variable=self.box, value="External dependencies", command=self.refresh_results_window) stat = Radiobutton(radio_frame, text="Statistics by type", variable=self.box, value="Statistics by type", command=self.refresh_results_window) msg_cat = Radiobutton(radio_frame, text="Messages by category", variable=self.box, value="Messages by category", command=self.refresh_results_window) msg = Radiobutton(radio_frame, text="Messages", variable=self.box, value="Messages", command=self.refresh_results_window) source_file = Radiobutton(radio_frame, text="Source File", variable=self.box, value="Source File", command=self.refresh_results_window) report.select() report.grid(column=0, row=0, sticky=W) raw_met.grid(column=1, row=0, sticky=W) dup.grid(column=2, row=0, sticky=W) msg.grid(column=3, row=0, sticky=W) stat.grid(column=0, row=1, sticky=W) msg_cat.grid(column=1, row=1, sticky=W) ext.grid(column=2, row=1, sticky=W) source_file.grid(column=3, row=1, sticky=W) #dictionary for check boxes and associated error term self.msg_type_dict = { 'I': lambda: self.information_box.get() == 1, 'C': lambda: self.convention_box.get() == 1, 'R': lambda: self.refactor_box.get() == 1, 'E': lambda: self.error_box.get() == 1, 'W': lambda: self.warning_box.get() == 1, 'F': lambda: self.fatal_box.get() == 1 } self.txt_module.focus_set()
def __init__(self, master=None, work=WORK_TM, rest=REST_TM, server=HOST, port=PORT, mode='fascist'): """create the task widget and get things started""" self.lid_state = "open" self.lid_time = time.time() self.interrupt_count = 0 self.then = 0.0 self.old_work = 0.0 self.state = "working" self.cancel_rest = 0 self.log = logging.getLogger(__name__) Frame.__init__(*(self, master)) self.mode = StringVar() self.mode.set(mode) # "fascist" or "friendly" # create main interactor window self.workmeter = Meter(self, background="grey50") self.workmeter.pack() self.work_frame = Frame(self) self.work_frame.pack() self.work_label = Label(self.work_frame, text="Work time:") self.work_label.pack(side=LEFT) self.work_scl = Scale(self.work_frame, orient=HORIZONTAL, from_=1, to=max(45, work), command=self.reset_duration) self.work_scl.set(work) self.work_scl.pack(side=LEFT) self.rest_frame = Frame(self) self.rest_frame.pack() self.rest_label = Label(self.rest_frame, text="Rest time:") self.rest_label.pack(side=LEFT) self.rest_scl = Scale(self.rest_frame, orient=HORIZONTAL, from_=1, to=max(15, rest), command=self.reset_duration) self.rest_scl.set(rest) self.rest_scl.pack(side=LEFT) self.radio_frame = Frame(self) self.radio_frame.pack() self.dictator = Radiobutton(self.radio_frame, text="Fascist", variable=self.mode, value="fascist") self.friend = Radiobutton(self.radio_frame, text="Friendly", variable=self.mode, value="friendly") self.dictator.pack(side=LEFT) self.friend.pack(side=LEFT) self.button_frame = Frame(self) self.button_frame.pack() self.restb = Button(self.button_frame, text="Rest", command=self.rest) self.restb.pack(side=LEFT) self.stopb = Button(self.button_frame, text="Quit", command=self.quit) self.stopb.pack(side=LEFT) self.helpb = Button(self.button_frame, text="Help", command=self.help) self.helpb.pack(side=LEFT) # create the cover window self.cover = Toplevel(background="black") self.cover.withdraw() # user can't resize it self.cover.resizable(0, 0) # when displayed, it should cover all displays (w, h) = (self.winfo_vrootwidth(), self.winfo_vrootheight()) if self.log.getEffectiveLevel() <= logging.DEBUG: # but we reduce it while debugging w, h = (w / 5, h / 5) self.cover.geometry("%dx%d+0+0" % (w, h)) # and it's undecorated self.cover.overrideredirect(1) # cover contains a frame with rest message and meter f = Frame(self.cover, background="black") self.restnote = Label(f, background="black", foreground="white") self.restmeter = Meter(f, background="grey50", height=10, width=200) self.restnote.pack(pady=2) self.restmeter.pack(fill="x", expand=1, pady=2) self.cancel_button = Button(f, text="Cancel Rest", command=self.cancel) f.pack() # initialize interrupt information self.linux_interrupts = 0 # used by the default activity checker self.mouse = None self.setup_server(server, port) # self.last_int is the last time the server was alerted to activity # self.now is the server's notion of the current time # idle time is therefore max(0, self.now-self.last_int) (self.last_int, _w_time, _r_time, self.now) = self.server.get() self.idle = max(0, self.now - self.last_int) self.bgcolor = self["background"] # start the ball rolling self.after(CHK_INT, self.tick) self.work()
class Task(Frame): def __init__(self, master=None, work=WORK_TM, rest=REST_TM, server=HOST, port=PORT, mode='fascist'): """create the task widget and get things started""" self.lid_state = "open" self.lid_time = time.time() self.interrupt_count = 0 self.then = 0.0 self.old_work = 0.0 self.state = "working" self.cancel_rest = 0 self.log = logging.getLogger(__name__) Frame.__init__(*(self, master)) self.mode = StringVar() self.mode.set(mode) # "fascist" or "friendly" # create main interactor window self.workmeter = Meter(self, background="grey50") self.workmeter.pack() self.work_frame = Frame(self) self.work_frame.pack() self.work_label = Label(self.work_frame, text="Work time:") self.work_label.pack(side=LEFT) self.work_scl = Scale(self.work_frame, orient=HORIZONTAL, from_=1, to=max(45, work), command=self.reset_duration) self.work_scl.set(work) self.work_scl.pack(side=LEFT) self.rest_frame = Frame(self) self.rest_frame.pack() self.rest_label = Label(self.rest_frame, text="Rest time:") self.rest_label.pack(side=LEFT) self.rest_scl = Scale(self.rest_frame, orient=HORIZONTAL, from_=1, to=max(15, rest), command=self.reset_duration) self.rest_scl.set(rest) self.rest_scl.pack(side=LEFT) self.radio_frame = Frame(self) self.radio_frame.pack() self.dictator = Radiobutton(self.radio_frame, text="Fascist", variable=self.mode, value="fascist") self.friend = Radiobutton(self.radio_frame, text="Friendly", variable=self.mode, value="friendly") self.dictator.pack(side=LEFT) self.friend.pack(side=LEFT) self.button_frame = Frame(self) self.button_frame.pack() self.restb = Button(self.button_frame, text="Rest", command=self.rest) self.restb.pack(side=LEFT) self.stopb = Button(self.button_frame, text="Quit", command=self.quit) self.stopb.pack(side=LEFT) self.helpb = Button(self.button_frame, text="Help", command=self.help) self.helpb.pack(side=LEFT) # create the cover window self.cover = Toplevel(background="black") self.cover.withdraw() # user can't resize it self.cover.resizable(0, 0) # when displayed, it should cover all displays (w, h) = (self.winfo_vrootwidth(), self.winfo_vrootheight()) if self.log.getEffectiveLevel() <= logging.DEBUG: # but we reduce it while debugging w, h = (w / 5, h / 5) self.cover.geometry("%dx%d+0+0" % (w, h)) # and it's undecorated self.cover.overrideredirect(1) # cover contains a frame with rest message and meter f = Frame(self.cover, background="black") self.restnote = Label(f, background="black", foreground="white") self.restmeter = Meter(f, background="grey50", height=10, width=200) self.restnote.pack(pady=2) self.restmeter.pack(fill="x", expand=1, pady=2) self.cancel_button = Button(f, text="Cancel Rest", command=self.cancel) f.pack() # initialize interrupt information self.linux_interrupts = 0 # used by the default activity checker self.mouse = None self.setup_server(server, port) # self.last_int is the last time the server was alerted to activity # self.now is the server's notion of the current time # idle time is therefore max(0, self.now-self.last_int) (self.last_int, _w_time, _r_time, self.now) = self.server.get() self.idle = max(0, self.now - self.last_int) self.bgcolor = self["background"] # start the ball rolling self.after(CHK_INT, self.tick) self.work() def setup_server(self, server, port): if server is None: self.server = collector.Collector() self.log.debug("using private Collector()") return self.server = xmlrpc_client.ServerProxy("http://%s:%d" % (server, port)) try: self.server.get() self.log.debug("found existing server") except socket.error: if server in ["", "localhost", "127.0.0.1"]: cmd = "watch-server.py" args = ["-p", "%d" % port] pid = os.spawnvp(os.P_NOWAIT, cmd, args) # wait briefly for server to start time.sleep(0.2) self.server = xmlrpc_client.ServerProxy("http://%s:%d" % (server, port), allow_none=True) # try connecting for _i in range(10): try: self.server.get() atexit.register(os.kill, pid, signal.SIGHUP) self.log.debug("spawned server") return except socket.error: time.sleep(0.1) # nothing else worked, so fall back to an embedded collector self.server = collector.Collector() self.log.debug("using private Collector()") def reset_duration(self, _dummy=None): """reset work/rest interval lengths to current scale values""" wtime = self.work_scl.get() self.workmeter.set_range(self.workmeter.min_val, self.workmeter.min_val + wtime * 60) self.restmeter.set_range( self.restmeter.min_val, self.restmeter.min_val + self.rest_scl.get() * 60) # only time the user can fiddle the work/rest meters is during # the work phase, so the only scale change that matters for extending # or contracting the end of the interval is the work scale try: delta = wtime - self.old_work except AttributeError: delta = 0 self.log.debug(__("then: {} delta: {}m", hhmm(self.then), delta)) self.then = self.then + delta * 60 self.old_work = wtime self.server.put(self.work_scl.get(), self.rest_scl.get()) def work(self): """start the work period""" self.reset_warning() self.restmeter.reset() self.state = "working" self.then = self.now + self.work_scl.get() * 60 self.log.debug(__("work: then: {}", hhmm(self.then))) self.workmeter.set_range(self.now, self.then) self.workmeter.reset() self.cover.withdraw() def warn_work_end(self): """alert user that work period is almost up""" self.set_background("yellow") def reset_warning(self): """back to plain old grey bg""" self.set_background(self.bgcolor) def set_background(self, color): for w in (self, self.work_scl, self.rest_scl, self.dictator, self.friend, self.button_frame, self.stopb, self.restb, self.helpb, self.work_frame, self.rest_frame, self.radio_frame, self.work_label, self.rest_label): w["background"] = color def rest(self): """overlay the screen with a window, preventing typing""" self.cancel_rest = 0 self.workmeter.reset() self.state = "resting" # the user may not have been typing or mousing right up to the # work/rest threshold - give credit for whatever rest time has # already been accumulated resttime = self.rest_scl.get() * 60 - (self.now - self.last_int) if resttime < 0: self.work() return mins, secs = divmod(resttime, 60) self.then = self.now + resttime self.cover.deiconify() self.cover.tkraise() resttext = ("Rest for %dm%02ds please..." % (mins, secs)) self.restnote.configure(text=resttext) self.restmeter.set_range(self.now, self.then) self.restmeter.reset() if self.mode.get() == "friendly": self.cancel_button.pack(pady=2) else: self.cancel_button.pack_forget() self.log.debug( __("rest: state: {} now: {} then: {} active? {}", self.state, hhmm(self.now), hhmm(self.then), self.check_activity())) def help(self): Dialog(self.master, title="Help", content=usageText()) ### ---- define activity checkers here ---- ### # keyed by sys.platform or "default" to return a method that checks # for mouse/keyboard activity _dispatch = {} def check_activity(self): """check mouse/keyboard activity info where possible, call platform-dependent routine to get mouse and keyboard info, otherwise, just return mouse info in all cases, the value returned should evaluate to False if no activity was detected. """ active = False if self.lid_state == "open": dflt = self._dispatch["default"] checker = self._dispatch.get(sys.platform, dflt) active = checker(self) if active: self.server.tick() return active def check_mouse(self): """default checker, just compares current w/ saved mouse pos""" mouse = self.winfo_pointerxy() try: return mouse != self.mouse finally: self.mouse = mouse _dispatch["default"] = check_mouse def get_linux_interrupts(self): count = 0 # Can't seem to find mouse interrupts, so for now, just watch # keyboard and mix add get_mouseinfo() output as a substitute for # mouse interrupts. last_count = self.interrupt_count for line in open("/proc/interrupts"): fields = line.split() if fields[0] == "1:": count = sum(int(fields[n]) for n in range(1, 8)) self.interrupt_count = count break return self.check_mouse() or self.interrupt_count > last_count _dispatch["linux"] = get_linux_interrupts def check_lid_state(self): if os.path.exists(LID_STATE): for line in open(LID_STATE): fields = line.strip().split() if fields[0] == "state:": return self.maybe_change_lid_state(fields[1]) else: self.lid_state = "open" return 0 def maybe_change_lid_state(self, state): """Take necessary action when lid state changes. Return True if lid state changed. """ idle = 0 if state != self.lid_state: self.log.info(__("lid state changed: {}", state)) lid_time = time.time() if state == "open": idle = lid_time - self.lid_time self.log.info(__("idle for {}s", idle)) self.lid_state = state self.lid_time = lid_time return idle def tick(self): """perform periodic checks for activity or state switch""" try: self._tick() finally: self.after(CHK_INT, self.tick) def _tick(self): (self.last_int, work_time, rest_time, self.now) = self.server.get() # check for mouse or keyboard activity idle_time = self.check_lid_state() if idle_time > rest_time * 60: self.log.info( __("The lid is up! Back to work: {}", hhmm(idle_time))) self.work() return active = self.check_activity() idle = max(0, self.now - self.last_int) # check to see if the work/rest scales got adjusted by another # watch instance if (self.work_scl.get() != work_time or self.rest_scl.get() != rest_time): self.work_scl.set(work_time) self.rest_scl.set(rest_time) self.log.debug( __("work: state: {} now: {} then: {} active? {}", self.state, hhmm(self.now), hhmm(self.then), active)) if self.state == "resting": # user explicitly cancelled the rest or the idle period # exceeded the desired rest time if self.cancel_rest or idle > rest_time * 60: self.work() return # make sure the rest window is as far up the window stack as # possible self.cover.tkraise() if idle <= self.idle: # user moved something - extend rest by a second self.then += 1 self.restmeter.set_range(self.restmeter.min_val, self.then) self.restmeter.set(self.now) self.idle = idle # update message to reflect rest time remaining timeleft = int(round(self.then - self.now)) minleft, secleft = divmod(timeleft, 60) resttext = ("Rest for %dm%02ds please..." % (minleft, secleft)) self.restnote.configure(text=resttext) else: # if it's been at least the length of the rest interval # since last interrupt, reset the work interval if idle >= rest_time * 60: self.work() return self.idle = idle if self.now > self.then: # work period expired self.rest() return if self.now + 60 > self.then: # work period nearly expired - warn user self.warn_work_end() else: self.reset_warning() self.restmeter.set(self.now) self.workmeter.set(self.now) def cancel(self): self.cancel_rest = 1