class GUIBeeTop(GlassWindow, Observable): # messages to the observers OBS_WHEEL = 0 OBS_CLOSE = 1 OBS_MOVE = 2 OBS_MENU = 3 OBS_CLICK = 4 def __init__(self): super(GUIBeeTop, self).__init__() # flag indicating whether this window is currently being dragged self.__is_dragging = 0 self.__drag_offset = (0, 0) self.set_icon_from_file(_config["icon"]) self.set_title("Beetop") self.set_size_request(_config["window_w"], _config["window_h"] + _config['window_eh'] * len(_config['tasks'])) self.set_position(gtk.WIN_POS_MOUSE) # self.set_decorated(False) # self.set_resizable(True) self.stick() self.connect("key-press-event", self.__on_key) self.connect("destroy", gtk.main_quit) self.connect("scroll-event", self.__on_mouse_wheel) # window moving self.connect("button-press-event", self.__on_button_press) self.connect("button-release-event", self.__on_button_release) gobject.idle_add(self.set_property, "skip-taskbar-hint", 1) gobject.idle_add(self.set_property, "skip-pager-hint", 1) # keep window below others self.connect("focus-in-event", self.__lower_window) self.connect_after("button-press-event", self.__lower_window) self.add_events(gtk.gdk.SCROLL_MASK | gtk.gdk.POINTER_MOTION_MASK | # gtk.gdk.POINTER_MOTION_HINT_MASK | gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK) self.set_bg_image(_config['bg_img'], _config['bg_img_alpha']) self.update_bg() vbox_app = gtk.VBox(False, 0) self.add(vbox_app) vbox_app.show() self._show_day = None self._calendar = TextCalendar(mycal.firstweekday) self._lb_month_year = gtk.Label("") self._lb_month_year.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(_config['month_year_color'])) self._lb_month_year.show() self._lb_week = CalLabel(7, 1, True) self._lb_week.show() self._lb_days = CalLabel(7, 6, True) self._lb_days.show() self._lb_uptime = gtk.Label("") self._lb_uptime.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(_config['uptime_color'])) self._lb_uptime.show() self._lb_tasks = [] self._task_tooltips = [] for _ in _config['tasks']: tlab = gtk.Label("") tlab.show() self._lb_tasks.append(tlab) ttip = gtk.Tooltips() ttip.set_delay(200) self._task_tooltips.append(ttip) self._task_results = [None] * len(self._lb_tasks) vbox_app.pack_start(self._lb_month_year, False, False, 3) vbox_app.pack_start(self._lb_week, False, False, 2) vbox_app.pack_start(self._lb_days, False, False, 1) vbox_app.pack_start(self._lb_uptime, False, False, 2) for tlab in self._lb_tasks: vbox_app.pack_start(tlab, False, False, 1) self.task_fonts = [] self.task_fonts.append(pango.FontDescription(_config["task_error_font"])) self.task_fonts.append(pango.FontDescription(_config["task_norm_font"])) self.task_fonts.append(pango.FontDescription(_config["task_strong_font"])) self.task_colors = [] self.task_colors.append(_config["task_error_color"]) self.task_colors.append(_config["task_norm_color"]) self.task_colors.append(_config["task_strong_color"]) self.__popup_menu = Menu([ ["_mycal.py", self.edit_file, ["mycal.py"]], ["_beetask.py", self.edit_file, ["beetask.py"]], ["_config.json", self.edit_file, ["config.json"]], ["_README", self.edit_file, ["README"]], [], ["_Move", self.move_window, []], ["_Quit", self.__cmd_quit, []]]) # desktop.watch_bg(self.__on_bg_change) self.add_observer(self.__on_window) self.show() if _config['position_x'] == 0: _config['position_x'] = gtk.gdk.screen_width() - _config["window_w"] - 5 self.move(_config["position_x"] , _config["position_y"]) self.after_runs = 0 self._after_run() # self.move_window() def _after_run(self): today = datetime.date.today() if self._show_day != today: self._show_day = today self._set_cal() d2 = os.popen('uptime').read().strip() i = d2.rfind(', ') self._lb_uptime.set_label(d2[:i] + "\n" + d2[(i + 3):]) t = 0 for task, delay in _config['tasks']: if self.after_runs % delay == 0: self._run_task(t, task) t += 1 gobject.timeout_add(_config['interval'], self._after_run) self.after_runs += 1 def _set_cal(self): data = self._calendar.formatmonth(self._show_day.year, self._show_day.month).strip().split('\n') self._lb_month_year.set_text("%s %d" % (mycal.monthname[self._show_day.month - 1], self._show_day.year)) # ws = data[1].split() #decode error? i = 0 wd = [] for d in self._calendar.iterweekdays(): wd.append(d) week = self._lb_week.get_label(i) week.set_text(mycal.weekname[d]) week.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(_config['week_color'])) i += 1 i = 0 today = datetime.date.today() cday = "%d-%d-%d" % (today.year, today.month, today.day) ym = "%d-%d" % (self._show_day.year, self._show_day.month) for dat in data[2:]: # print dat, i ds = dat.strip().split() if i == 0 and len(ds) < 7: # the first ds = [" "] * (7 - len(ds)) + ds if len(ds) < 7: # the last ds = ds + [" "] * (7 - len(ds)) for j in range(7): lday, ltip = self._lb_days.get_labeltip_at(j, i) lday.set_text(ds[j]) mday = "%s-%s" % (ym, ds[j]) if (not ds[j].isspace()) and (wd[j] in mycal.weekevent or mday in mycal.dayevent): lday.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(_config['event_day_color'])) tips = [] if wd[j] in mycal.weekevent: tips.append(mycal.weekevent[wd[j]]) if mday in mycal.dayevent: tips.append(mycal.dayevent[mday]) ltip.set_tip(lday, "\n".join(tips), tip_private=None) else: lday.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(_config['norm_day_color'])) ltip.set_tip(lday, "", tip_private=None) # clear if cday == mday: # lday.modify_font(font_month) lday.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(_config['today_color'])) i += 1 if i < 6: # clean others for j in range(7): lday, ltip = self._lb_days.get_labeltip_at(j, i) lday.set_text("") lday.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(_config['norm_day_color'])) ltip.set_tip(lday, "", tip_private=None) # clear i += 1 def _run_task(self, t, task=None): if not task: task, delay = _config['tasks'][t] self._task_results[t] = beetask.__dict__[task]() status, title, tip, _ = self._task_results[t] self._lb_tasks[t].set_label(title) if status < 0: status = -1 elif status > 0: status = 1 self._lb_tasks[t].modify_font(self.task_fonts[status + 1]) self._lb_tasks[t].modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.task_colors[status + 1])) self._task_tooltips[t].set_tip(self._lb_tasks[t], tip, tip_private=None) def edit_file(self, ifile): os.system("%s %s >/dev/null 2>&1 &" % (_config['editor'], os.path.join(sys.path[0], ifile))) # # Reacts on key presses. # def __on_key(self, src, event): key = gtk.gdk.keyval_name(event.keyval) # SPACE updates the background if (key == "space"): self.update_bg() # F10 opens the menu elif (key == "F10"): # self.update_observer(self.OBS_MENU, 0, event.time) self.move_window() # # Reacts on closing the window. # def __on_close(self, src, event): self.update_observer(self.OBS_CLOSE) # # Updates the background. # def update_bg(self, noscreenshot=0): GlassWindow.update_bg(self, noscreenshot) self.stick() # # Reacts on changes to the background image. # def __on_bg_change(self, src, cmd): self.update_bg() # # Reacts on pressing a mouse button. # def __on_button_press(self, src, event): button = event.button modifiers = event.state if (button == 1): x, y = self.get_pointer() self.update_observer(self.OBS_CLICK, x, y) if (button == 2): x, y = self.get_pointer() self.__is_dragging = 1 self.__drag_offset = (x, y) self.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.FLEUR)) gobject.timeout_add(20, self.__on_move) # # Reacts on releasing a mouse button. # def __on_button_release(self, src, event): if (self.__is_dragging): self.__is_dragging = 0 self.window.set_cursor(None) self.update_bg() elif (event.button == 3): self.update_observer(self.OBS_MENU, event.button, event.time) # # Reacts on mouse wheel. # def __on_mouse_wheel(self, src, event): if (event.direction == gtk.gdk.SCROLL_UP): step = -1 elif (event.direction == gtk.gdk.SCROLL_DOWN): step = 1 else: step = 0 self.update_observer(self.OBS_WHEEL, step) # # Keeps the window below others. # def __lower_window(self, src, event): if (self.window): self.window.lower() return True # # Reacts on window events. # def __on_window(self, src, cmd, *args): if (cmd == src.OBS_WHEEL): step = args[0] m = self._show_day.month + step if m > 12: self._show_day = datetime.date(self._show_day.year + 1, 1, self._show_day.day) elif m < 1: self._show_day = datetime.date(self._show_day.year - 1, 12, self._show_day.day) else: self._show_day = datetime.date(self._show_day.year, m, self._show_day.day) self._set_cal() elif (cmd == src.OBS_CLICK): x, y = args _, ly = self._lb_month_year.get_layout_offsets() if y > ly and y < ly + 20: today = datetime.date.today() if self._show_day != today: self._show_day = today self._set_cal() else: for i in range(len(self._lb_tasks) - 1, -1, -1): lx, ly = self._lb_tasks[i].get_layout_offsets() if y >= ly: # print _config['tasks'][i] cmd = self._task_results[i] if cmd != None: cmd = self._task_results[i][-1] if x < 30 and cmd: os.system(cmd) else: self._run_task(i) # run it now break elif (cmd == src.OBS_CLOSE): self.__cmd_quit() elif (cmd == src.OBS_MOVE): x, y = args[0] print x, y # self.__config.set([conf.GEOMETRY, conf.WINDOW, conf.X], str(x)) # self.__config.set([conf.GEOMETRY, conf.WINDOW, conf.Y], str(y)) elif (cmd == src.OBS_MENU): button = args[0] etime = args[1] self.__popup_menu.popup(button, etime) # # Reacts on moving the mouse pointer. # def __on_move(self): if (self.__is_dragging): offx, offy = self.__drag_offset winx, winy = self.get_position() # print winx, winy x, y = self.get_pointer() x += winx; y += winy self.move(x - offx, y - offy) return True else: return False # # Switches to window move mode. # def move_window(self): x, y = self.get_pointer() width, height = self.window.get_size() x = max(4, min(x, width - 4)) y = max(4, min(y, height - 4)) self.__is_dragging = 1 self.__drag_offset = (x, y) gobject.timeout_add(20, self.__on_move) def __cmd_quit(self): # self.__config.save() gtk.main_quit() def main(self): gtk.main()