class BatteryStatusApplet: """An applet which displays battery information. """ # State of the icon (a tuple containing the icon path and size) __previous_state = None def __init__(self, applet): self.applet = applet applet.tooltip.disable_toggle_on_click() self.backend = None for b in backends: if b.backend_useable(): self.backend = b() break self.setup_context_menu() if self.backend is not None: self.__message_handler = MessageHandler(self) applet.timing.register(self.check_status_cb, check_status_interval) self.check_status_cb() else: self.set_battery_missing() applet.connect_size_changed(self.size_changed_cb) def size_changed_cb(self): if self.backend is not None: self.check_status_cb() else: self.set_battery_missing() def set_battery_missing(self): self.applet.tooltip.set(_("No batteries")) icon = os.path.join(themes_dir, self.applet.settings["theme"], "battery-missing.svg") self.applet.icon.file(icon, size=awnlib.Icon.APPLET_SIZE) def setup_context_menu(self): prefs = gtk.Builder() prefs.add_from_file(ui_file) prefs.get_object("vbox-preferences").reparent( self.applet.dialog.new("preferences").vbox) """ Battery """ if self.backend is not None: batteries = self.backend.get_batteries() self.combobox_battery = prefs.get_object("combobox-battery") awnlib.add_cell_renderer_text(self.combobox_battery) for model in batteries.values(): self.combobox_battery.append_text(model) if self.applet.settings["battery-udi"] not in batteries: self.applet.settings["battery-udi"] = batteries.keys()[0] if len(self.applet.settings["low-level-unit"]) == 0: self.applet.settings["low-level-unit"] = _("Percent") battery_getter = lambda key_value: batteries[key_value] battery_setter = lambda widget_value: batteries.keys()[ batteries.values().index(widget_value)] else: frame = prefs.get_object("frame-battery") frame.hide_all() frame.set_no_show_all(True) battery_getter = lambda v: v battery_setter = lambda v: v """ Display """ # Only use themes that are likely to provide all the files self.themes = os.listdir(themes_dir) self.themes.sort() combobox_theme = prefs.get_object("combobox-theme") awnlib.add_cell_renderer_text(combobox_theme) for i in self.themes: combobox_theme.append_text(i) self.theme = self.applet.settings["theme"] if self.theme not in self.themes: self.applet.settings["theme"] = self.theme = default_theme """ Notifications """ if self.backend is not None: self.hbox_low_level = prefs.get_object("hbox-low-level") self.hbox_low_level.set_sensitive( self.applet.settings["warn-low-level"]) self.hbox_high_level = prefs.get_object("hbox-high-level") self.hbox_high_level.set_sensitive( self.applet.settings["notify-high-level"]) else: frame = prefs.get_object("frame-notifications") frame.hide_all() frame.set_no_show_all(True) refresh_message = lambda v: self.__message_handler.evaluate() binder = self.applet.settings.get_binder(prefs) binder.bind("theme", "combobox-theme", key_callback=self.combobox_theme_changed_cb) binder.bind("battery-udi", "combobox-battery", getter_transform=battery_getter, setter_transform=battery_setter, key_callback=self.combobox_battery_changed_cb) binder.bind("warn-low-level", "checkbutton-warn-low-level", key_callback=self.toggled_warn_low_level_cb) binder.bind("notify-high-level", "checkbutton-notify-high-level", key_callback=self.toggled_notify_high_level_cb) binder.bind("level-warn-low", "spinbutton-low-level", key_callback=refresh_message) binder.bind("level-notify-high", "spinbutton-high-level", key_callback=refresh_message) binder.bind("low-level-unit", "combobox-low-level", key_callback=self.combobox_low_level_unit_changed_cb) self.applet.settings.load_bindings(binder) def toggled_warn_low_level_cb(self, active): self.hbox_low_level.set_sensitive(active) self.__message_handler.evaluate() def toggled_notify_high_level_cb(self, active): self.hbox_high_level.set_sensitive(active) self.__message_handler.evaluate() def combobox_low_level_unit_changed_cb(self, value): self.__message_handler.evaluate() def combobox_battery_changed_cb(self, udi): batteries = self.backend.get_batteries() try: self.backend.set_active_udi(udi) self.check_status_cb() except ValueError: pass # TODO restore combobox # udi = self.backend.get_active_udi() # self.combobox_battery.set_active(batteries.values().index(batteries[udi])) def combobox_theme_changed_cb(self, value): if self.backend is not None: self.check_status_cb() else: self.set_battery_missing() def check_status_cb(self): if not self.backend.is_present(): self.set_battery_missing() return charge_percentage = self.backend.get_capacity_percentage() power_type = _("AC") if self.backend.is_on_ac_power() else _("battery") charge_message = _("Computer running on %s power") % power_type if self.backend.is_charged(): charge_message += "\n" + _("Battery charged") icon = os.path.join(themes_dir, self.applet.settings["theme"], "battery-charged.svg") else: is_charging = self.backend.is_charging() if is_charging: actoggle = "charging" time = self.backend.get_charge_time() title_message_suffix = _("until charged") else: actoggle = "discharging" time = self.backend.get_remaining_time() title_message_suffix = _("remaining") # May be None because charge rate is not always known (when switching between charging and discharging) if time is not None: charge_message += "\n" + self.format_time( time, suffix=title_message_suffix) level = [ key for key, value in charge_ranges.iteritems() if charge_percentage <= value[0] and charge_percentage >= value[1] ][0] icon = os.path.join(themes_dir, self.applet.settings["theme"], "battery-" + actoggle + "-" + level + ".svg") self.applet.tooltip.set(" ".join( [charge_message, "(" + str(charge_percentage) + "%)"])) self.draw_icon(icon) self.__message_handler.evaluate() def draw_icon(self, icon): new_state = (icon, self.applet.get_size()) if self.__previous_state == new_state: return self.__previous_state = new_state self.applet.icon.file(icon, size=awnlib.Icon.APPLET_SIZE) def is_battery_low(self): if not self.backend.is_discharging(): return False unit = self.applet.settings["low-level-unit"] if unit == _("Percent") and self.backend.get_capacity_percentage( ) <= self.applet.settings["level-warn-low"]: return True time = self.backend.get_remaining_time() if time is None: return None hours, minutes = time return unit == _( "Time Remaining" ) and hours == 0 and minutes <= self.applet.settings["level-warn-low"] def is_battery_high(self): if self.backend.is_discharging(): return False return self.backend.get_capacity_percentage( ) >= self.applet.settings["level-notify-high"] def format_time(self, time, suffix=""): hours, minutes = time message = [] time = [] if hours > 0: if hours > 1: message.append(_("%d hours")) else: message.append(_("%d hour")) time.append(hours) if minutes > 0: if minutes > 1: message.append(_("%d minutes")) else: message.append(_("%d minute")) time.append(minutes) message = " ".join(message) % tuple(time) return " ".join([message, suffix]).strip() if len(message) > 0 else ""
class BatteryStatusApplet: """An applet which displays battery information. """ # State of the icon (a tuple containing the icon path and size) __previous_state = None def __init__(self, applet): self.applet = applet applet.tooltip.disable_toggle_on_click() self.backend = None for b in backends: if b.backend_useable(): self.backend = b() break self.setup_context_menu() if self.backend is not None: self.__message_handler = MessageHandler(self) applet.timing.register(self.check_status_cb, check_status_interval) self.check_status_cb() else: self.set_battery_missing() applet.connect_size_changed(self.size_changed_cb) def size_changed_cb(self): if self.backend is not None: self.check_status_cb() else: self.set_battery_missing() def set_battery_missing(self): self.applet.tooltip.set(_("No batteries")) icon = os.path.join(themes_dir, self.applet.settings["theme"], "battery-missing.svg") self.applet.icon.file(icon, size=awnlib.Icon.APPLET_SIZE) def setup_context_menu(self): prefs = gtk.Builder() prefs.add_from_file(ui_file) prefs.get_object("vbox-preferences").reparent(self.applet.dialog.new("preferences").vbox) """ Battery """ if self.backend is not None: batteries = self.backend.get_batteries() self.combobox_battery = prefs.get_object("combobox-battery") awnlib.add_cell_renderer_text(self.combobox_battery) for model in batteries.values(): self.combobox_battery.append_text(model) if self.applet.settings["battery-udi"] not in batteries: self.applet.settings["battery-udi"] = batteries.keys()[0] if len(self.applet.settings["low-level-unit"]) == 0: self.applet.settings["low-level-unit"] = _("Percent") battery_getter = lambda key_value: batteries[key_value] battery_setter = lambda widget_value: batteries.keys()[batteries.values().index(widget_value)] else: frame = prefs.get_object("frame-battery") frame.hide_all() frame.set_no_show_all(True) battery_getter = lambda v: v battery_setter = lambda v: v """ Display """ # Only use themes that are likely to provide all the files self.themes = os.listdir(themes_dir) self.themes.sort() combobox_theme = prefs.get_object("combobox-theme") awnlib.add_cell_renderer_text(combobox_theme) for i in self.themes: combobox_theme.append_text(i) self.theme = self.applet.settings["theme"] if self.theme not in self.themes: self.applet.settings["theme"] = self.theme = default_theme """ Notifications """ if self.backend is not None: self.hbox_low_level = prefs.get_object("hbox-low-level") self.hbox_low_level.set_sensitive(self.applet.settings["warn-low-level"]) self.hbox_high_level = prefs.get_object("hbox-high-level") self.hbox_high_level.set_sensitive(self.applet.settings["notify-high-level"]) else: frame = prefs.get_object("frame-notifications") frame.hide_all() frame.set_no_show_all(True) refresh_message = lambda v: self.__message_handler.evaluate() binder = self.applet.settings.get_binder(prefs) binder.bind("theme", "combobox-theme", key_callback=self.combobox_theme_changed_cb) binder.bind("battery-udi", "combobox-battery", getter_transform=battery_getter, setter_transform=battery_setter, key_callback=self.combobox_battery_changed_cb) binder.bind("warn-low-level", "checkbutton-warn-low-level", key_callback=self.toggled_warn_low_level_cb) binder.bind("notify-high-level", "checkbutton-notify-high-level", key_callback=self.toggled_notify_high_level_cb) binder.bind("level-warn-low", "spinbutton-low-level", key_callback=refresh_message) binder.bind("level-notify-high", "spinbutton-high-level", key_callback=refresh_message) binder.bind("low-level-unit", "combobox-low-level", key_callback=self.combobox_low_level_unit_changed_cb) self.applet.settings.load_bindings(binder) def toggled_warn_low_level_cb(self, active): self.hbox_low_level.set_sensitive(active) self.__message_handler.evaluate() def toggled_notify_high_level_cb(self, active): self.hbox_high_level.set_sensitive(active) self.__message_handler.evaluate() def combobox_low_level_unit_changed_cb(self, value): self.__message_handler.evaluate() def combobox_battery_changed_cb(self, udi): batteries = self.backend.get_batteries() try: self.backend.set_active_udi(udi) self.check_status_cb() except ValueError: pass # TODO restore combobox # udi = self.backend.get_active_udi() # self.combobox_battery.set_active(batteries.values().index(batteries[udi])) def combobox_theme_changed_cb(self, value): if self.backend is not None: self.check_status_cb() else: self.set_battery_missing() def check_status_cb(self): if not self.backend.is_present(): self.set_battery_missing() return charge_percentage = self.backend.get_capacity_percentage() power_type = _("AC") if self.backend.is_on_ac_power() else _("battery") charge_message = _("Computer running on %s power") % power_type if self.backend.is_charged(): charge_message += "\n" + _("Battery charged") icon = os.path.join(themes_dir, self.applet.settings["theme"], "battery-charged.svg") else: is_charging = self.backend.is_charging() if is_charging: actoggle = "charging" time = self.backend.get_charge_time() title_message_suffix = _("until charged") else: actoggle = "discharging" time = self.backend.get_remaining_time() title_message_suffix = _("remaining") # May be None because charge rate is not always known (when switching between charging and discharging) if time is not None: charge_message += "\n" + self.format_time(time, suffix=title_message_suffix) level = [key for key, value in charge_ranges.iteritems() if charge_percentage <= value[0] and charge_percentage >= value[1]][0] icon = os.path.join(themes_dir, self.applet.settings["theme"], "battery-" + actoggle + "-" + level + ".svg") self.applet.tooltip.set(" ".join([charge_message, "(" + str(charge_percentage) + "%)"])) self.draw_icon(icon) self.__message_handler.evaluate() def draw_icon(self, icon): new_state = (icon, self.applet.get_size()) if self.__previous_state == new_state: return self.__previous_state = new_state self.applet.icon.file(icon, size=awnlib.Icon.APPLET_SIZE) def is_battery_low(self): if not self.backend.is_discharging(): return False unit = self.applet.settings["low-level-unit"] if unit == _("Percent") and self.backend.get_capacity_percentage() <= self.applet.settings["level-warn-low"]: return True time = self.backend.get_remaining_time() if time is None: return None hours, minutes = time return unit == _("Time Remaining") and hours == 0 and minutes <= self.applet.settings["level-warn-low"] def is_battery_high(self): if self.backend.is_discharging(): return False return self.backend.get_capacity_percentage() >= self.applet.settings["level-notify-high"] def format_time(self, time, suffix=""): hours, minutes = time message = [] time = [] if hours > 0: if hours > 1: message.append(_("%d hours")) else: message.append(_("%d hour")) time.append(hours) if minutes > 0: if minutes > 1: message.append(_("%d minutes")) else: message.append(_("%d minute")) time.append(minutes) message = " ".join(message) % tuple(time) return " ".join([message, suffix]).strip() if len(message) > 0 else ""