From b6db5b8af0af7ebfdd44cb53b09d63b819989338 Mon Sep 17 00:00:00 2001 From: Julio Reyes Date: Fri, 05 Jul 2013 14:13:11 +0000 Subject: Initial Commit --- (limited to 'extensions/deviceicon/battery.py') diff --git a/extensions/deviceicon/battery.py b/extensions/deviceicon/battery.py new file mode 100644 index 0000000..a70458a --- /dev/null +++ b/extensions/deviceicon/battery.py @@ -0,0 +1,260 @@ +# Copyright (C) 2006-2007, Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +import logging +from gettext import gettext as _ +import sys + +import gconf +import glib +import gobject +import gtk +import dbus + +from sugar.graphics import style +from sugar.graphics.icon import get_icon_state +from sugar.graphics.tray import TrayIcon +from sugar.graphics.palette import Palette +from sugar.graphics.xocolor import XoColor + +from jarabe.frame.frameinvoker import FrameWidgetInvoker + + +_ICON_NAME = 'battery' + +_STATUS_CHARGING = 0 +_STATUS_DISCHARGING = 1 +_STATUS_FULLY_CHARGED = 2 +_STATUS_NOT_PRESENT = 3 + +_UP_DEVICE_IFACE = 'org.freedesktop.UPower.Device' + +_UP_TYPE_BATTERY = 2 + +_UP_STATE_UNKNOWN = 0 +_UP_STATE_CHARGING = 1 +_UP_STATE_DISCHARGING = 2 +_UP_STATE_EMPTY = 3 +_UP_STATE_FULL = 4 +_UP_STATE_CHARGE_PENDING = 5 +_UP_STATE_DISCHARGE_PENDING = 6 + +_WARN_MIN_PERCENTAGE = 15 + + +class DeviceView(TrayIcon): + + FRAME_POSITION_RELATIVE = 102 + + def __init__(self, battery): + client = gconf.client_get_default() + self._color = XoColor(client.get_string('/desktop/sugar/user/color')) + + TrayIcon.__init__(self, icon_name=_ICON_NAME, xo_color=self._color) + + self.set_palette_invoker(FrameWidgetInvoker(self)) + + self._model = DeviceModel(battery) + self.palette = BatteryPalette(glib.markup_escape_text(_('My Battery'))) + self.palette.set_group_id('frame') + self._model.connect('updated', + self.__battery_status_changed_cb) + self._update_info() + + def _update_info(self): + name = _ICON_NAME + current_level = self._model.props.level + xo_color = self._color + badge_name = None + + if not self._model.props.present: + status = _STATUS_NOT_PRESENT + badge_name = None + xo_color = XoColor('%s,%s' % (style.COLOR_WHITE.get_svg(), + style.COLOR_WHITE.get_svg())) + elif self._model.props.charging: + status = _STATUS_CHARGING + name += '-charging' + xo_color = XoColor('%s,%s' % (style.COLOR_WHITE.get_svg(), + style.COLOR_WHITE.get_svg())) + elif self._model.props.discharging: + status = _STATUS_DISCHARGING + if current_level <= _WARN_MIN_PERCENTAGE: + badge_name = 'emblem-warning' + else: + status = _STATUS_FULLY_CHARGED + + self.icon.props.icon_name = get_icon_state(name, current_level, + step=-5) + self.icon.props.xo_color = xo_color + self.icon.props.badge_name = badge_name + + self.palette.set_info(current_level, self._model.props.time_remaining, + status) + + def __battery_status_changed_cb(self, model): + self._update_info() + + +class BatteryPalette(Palette): + + def __init__(self, primary_text): + Palette.__init__(self, primary_text) + self._level = 0 + self._time = 0 + self._status = _STATUS_NOT_PRESENT + self._progress_bar = gtk.ProgressBar() + self._progress_bar.set_size_request( + style.zoom(style.GRID_CELL_SIZE * 4), -1) + self._progress_bar.show() + self._status_label = gtk.Label() + self._status_label.show() + + vbox = gtk.VBox() + vbox.pack_start(self._progress_bar) + vbox.pack_start(self._status_label) + vbox.show() + + self._progress_widget = vbox + self.set_content(self._progress_widget) + + def set_info(self, percentage, seconds, status): + self._level = percentage + self._time = seconds + self._status = status + self._progress_bar.set_fraction(percentage / 100.0) + self._update_secondary() + + def _update_secondary(self): + secondary_text = '' + status_text = '%s%%' % (self._level, ) + + progress_widget = self._progress_widget + if self._status == _STATUS_NOT_PRESENT: + secondary_text = _('Removed') + progress_widget = None + elif self._status == _STATUS_CHARGING: + secondary_text = _('Charging') + elif self._status == _STATUS_DISCHARGING: + if self._level <= _WARN_MIN_PERCENTAGE: + secondary_text = _('Very little power remaining') + else: + minutes_remaining = self._time // 60 + remaining_hourpart = minutes_remaining // 60 + remaining_minpart = minutes_remaining % 60 + # TRANS: do not translate %(hour)d:%(min).2d it is a variable, + # only translate the word "remaining" + secondary_text = _('%(hour)d:%(min).2d remaining') % \ + {'hour': remaining_hourpart, 'min': remaining_minpart} + else: + secondary_text = _('Charged') + + self.set_content(progress_widget) + + self.props.secondary_text = glib.markup_escape_text(secondary_text) + self._status_label.set_text(status_text) + + +class DeviceModel(gobject.GObject): + __gproperties__ = { + 'level': (int, None, None, 0, 100, 0, gobject.PARAM_READABLE), + 'time-remaining': (int, None, None, 0, sys.maxint, 0, + gobject.PARAM_READABLE), # unit: seconds + 'charging': (bool, None, None, False, gobject.PARAM_READABLE), + 'discharging': (bool, None, None, False, gobject.PARAM_READABLE), + 'present': (bool, None, None, False, gobject.PARAM_READABLE), + } + + __gsignals__ = { + 'updated': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), + } + + def __init__(self, battery): + gobject.GObject.__init__(self) + self._battery = battery + self._battery_props_iface = dbus.Interface(self._battery, + dbus.PROPERTIES_IFACE) + self._battery.connect_to_signal('Changed', + self.__battery_properties_changed_cb, + dbus_interface=_UP_DEVICE_IFACE) + self._fetch_properties_from_upower() + + def _fetch_properties_from_upower(self): + """Get current values from UPower.""" + # pylint: disable=W0201 + try: + dbus_props = self._battery_props_iface.GetAll(_UP_DEVICE_IFACE) + except dbus.DBusException: + logging.error('Cannot access battery properties') + dbus_props = {} + + self._level = dbus_props.get('Percentage', 0) + self._state = dbus_props.get('State', _UP_STATE_UNKNOWN) + self._present = dbus_props.get('IsPresent', False) + self._time_to_empty = dbus_props.get('TimeToEmpty', 0) + self._time_to_full = dbus_props.get('TimeToFull', 0) + + def do_get_property(self, pspec): + """Return current value of given GObject property.""" + if pspec.name == 'level': + return self._level + if pspec.name == 'charging': + return self._state == _UP_STATE_CHARGING + if pspec.name == 'discharging': + return self._state == _UP_STATE_DISCHARGING + if pspec.name == 'present': + return self._present + if pspec.name == 'time-remaining': + if self._state == _UP_STATE_CHARGING: + return self._time_to_full + if self._state == _UP_STATE_DISCHARGING: + return self._time_to_empty + return 0 + + def get_type(self): + return 'battery' + + def __battery_properties_changed_cb(self): + old_level = self._level + old_state = self._state + old_present = self._present + old_time = self.props.time_remaining + self._fetch_properties_from_upower() + if self._level != old_level: + self.notify('level') + if self._state != old_state: + self.notify('charging') + self.notify('discharging') + if self._present != old_present: + self.notify('present') + if self.props.time_remaining != old_time: + self.notify('time-remaining') + + self.emit('updated') + + +def setup(tray): + bus = dbus.Bus(dbus.Bus.TYPE_SYSTEM) + up_proxy = bus.get_object('org.freedesktop.UPower', + '/org/freedesktop/UPower') + upower = dbus.Interface(up_proxy, 'org.freedesktop.UPower') + + for device_path in upower.EnumerateDevices(): + device = bus.get_object('org.freedesktop.UPower', device_path) + device_prop_iface = dbus.Interface(device, dbus.PROPERTIES_IFACE) + device_type = device_prop_iface.Get(_UP_DEVICE_IFACE, 'Type') + if device_type == _UP_TYPE_BATTERY: + tray.add_device(DeviceView(device)) -- cgit v0.9.1