Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src/jarabe/desktop/meshbox.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/jarabe/desktop/meshbox.py')
-rw-r--r--src/jarabe/desktop/meshbox.py815
1 files changed, 55 insertions, 760 deletions
diff --git a/src/jarabe/desktop/meshbox.py b/src/jarabe/desktop/meshbox.py
index ae63ad2..cf72053 100644
--- a/src/jarabe/desktop/meshbox.py
+++ b/src/jarabe/desktop/meshbox.py
@@ -1,6 +1,7 @@
# Copyright (C) 2006-2007 Red Hat, Inc.
# Copyright (C) 2009 Tomeu Vizoso, Simon Schampijer
# Copyright (C) 2009-2010 One Laptop per Child
+# Copyright (C) 2010 Collabora Ltd. <http://www.collabora.co.uk/>
#
# 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
@@ -18,7 +19,6 @@
from gettext import gettext as _
import logging
-import hashlib
import dbus
import hippo
@@ -28,30 +28,20 @@ import gtk
import gconf
from sugar.graphics.icon import CanvasIcon, Icon
-from sugar.graphics.xocolor import XoColor
-from sugar.graphics import xocolor
from sugar.graphics import style
-from sugar.graphics.icon import get_icon_state
from sugar.graphics import palette
from sugar.graphics import iconentry
from sugar.graphics.menuitem import MenuItem
-from sugar.activity.activityhandle import ActivityHandle
-from sugar.activity import activityfactory
-from sugar.util import unique_id
-from sugar import profile
from jarabe.model import neighborhood
+from jarabe.model.buddy import get_owner_instance
from jarabe.view.buddyicon import BuddyIcon
-from jarabe.view.pulsingicon import CanvasPulsingIcon
-from jarabe.view import launcher
from jarabe.desktop.snowflakelayout import SnowflakeLayout
from jarabe.desktop.spreadlayout import SpreadLayout
-from jarabe.desktop import keydialog
-from jarabe.model import bundleregistry
+from jarabe.desktop.networkviews import WirelessNetworkView
+from jarabe.desktop.networkviews import OlpcMeshView
+from jarabe.desktop.networkviews import SugarAdhocView
from jarabe.model import network
-from jarabe.model.network import Settings
-from jarabe.model.network import IP4Config
-from jarabe.model.network import WirelessSecurity
from jarabe.model.network import AccessPoint
from jarabe.model.olpcmesh import OlpcMeshManager
from jarabe.model.adhoc import get_adhoc_manager_instance
@@ -69,673 +59,14 @@ _NM_ACTIVE_CONN_IFACE = 'org.freedesktop.NetworkManager.Connection.Active'
_AP_ICON_NAME = 'network-wireless'
_OLPC_MESH_ICON_NAME = 'network-mesh'
-
-class WirelessNetworkView(CanvasPulsingIcon):
- def __init__(self, initial_ap):
- CanvasPulsingIcon.__init__(self, size=style.STANDARD_ICON_SIZE,
- cache=True)
- self._bus = dbus.SystemBus()
- self._access_points = {initial_ap.model.object_path: initial_ap}
- self._active_ap = None
- self._device = initial_ap.device
- self._palette_icon = None
- self._disconnect_item = None
- self._connect_item = None
- self._greyed_out = False
- self._name = initial_ap.name
- self._mode = initial_ap.mode
- self._strength = initial_ap.strength
- self._flags = initial_ap.flags
- self._wpa_flags = initial_ap.wpa_flags
- self._rsn_flags = initial_ap.rsn_flags
- self._device_caps = 0
- self._device_state = None
- self._connection = None
- self._color = None
-
- if self._mode == network.NM_802_11_MODE_ADHOC and \
- network.is_sugar_adhoc_network(self._name):
- self._color = profile.get_color()
- else:
- sha_hash = hashlib.sha1()
- data = self._name + hex(self._flags)
- sha_hash.update(data)
- digest = hash(sha_hash.digest())
- index = digest % len(xocolor.colors)
-
- self._color = xocolor.XoColor('%s,%s' %
- (xocolor.colors[index][0],
- xocolor.colors[index][1]))
-
- self.connect('button-release-event', self.__button_release_event_cb)
-
- pulse_color = XoColor('%s,%s' % (style.COLOR_BUTTON_GREY.get_svg(),
- style.COLOR_TRANSPARENT.get_svg()))
- self.props.pulse_color = pulse_color
-
- self._palette = self._create_palette()
- self.set_palette(self._palette)
- self._palette_icon.props.xo_color = self._color
-
- if self._mode != network.NM_802_11_MODE_ADHOC:
- if network.find_connection_by_ssid(self._name) is not None:
- self.props.badge_name = "emblem-favorite"
- self._palette_icon.props.badge_name = "emblem-favorite"
- elif self._flags == network.NM_802_11_AP_FLAGS_PRIVACY:
- self.props.badge_name = "emblem-locked"
- self._palette_icon.props.badge_name = "emblem-locked"
- else:
- self.props.badge_name = None
- self._palette_icon.props.badge_name = None
- else:
- self.props.badge_name = None
- self._palette_icon.props.badge_name = None
-
- interface_props = dbus.Interface(self._device,
- 'org.freedesktop.DBus.Properties')
- interface_props.Get(_NM_DEVICE_IFACE, 'State',
- reply_handler=self.__get_device_state_reply_cb,
- error_handler=self.__get_device_state_error_cb)
- interface_props.Get(_NM_WIRELESS_IFACE, 'WirelessCapabilities',
- reply_handler=self.__get_device_caps_reply_cb,
- error_handler=self.__get_device_caps_error_cb)
- interface_props.Get(_NM_WIRELESS_IFACE, 'ActiveAccessPoint',
- reply_handler=self.__get_active_ap_reply_cb,
- error_handler=self.__get_active_ap_error_cb)
-
- self._bus.add_signal_receiver(self.__device_state_changed_cb,
- signal_name='StateChanged',
- path=self._device.object_path,
- dbus_interface=_NM_DEVICE_IFACE)
- self._bus.add_signal_receiver(self.__wireless_properties_changed_cb,
- signal_name='PropertiesChanged',
- path=self._device.object_path,
- dbus_interface=_NM_WIRELESS_IFACE)
-
- def _create_palette(self):
- icon_name = get_icon_state(_AP_ICON_NAME, self._strength)
- self._palette_icon = Icon(icon_name=icon_name,
- icon_size=style.STANDARD_ICON_SIZE,
- badge_name=self.props.badge_name)
-
- p = palette.Palette(primary_text=glib.markup_escape_text(self._name),
- icon=self._palette_icon)
-
- self._connect_item = MenuItem(_('Connect'), 'dialog-ok')
- self._connect_item.connect('activate', self.__connect_activate_cb)
- p.menu.append(self._connect_item)
-
- self._disconnect_item = MenuItem(_('Disconnect'), 'media-eject')
- self._disconnect_item.connect('activate',
- self._disconnect_activate_cb)
- p.menu.append(self._disconnect_item)
-
- return p
-
- def __device_state_changed_cb(self, new_state, old_state, reason):
- self._device_state = new_state
- self._update_state()
-
- def __update_active_ap(self, ap_path):
- if ap_path in self._access_points:
- # save reference to active AP, so that we always display the
- # strength of that one
- self._active_ap = self._access_points[ap_path]
- self.update_strength()
- self._update_state()
- elif self._active_ap is not None:
- # revert to showing state of strongest AP again
- self._active_ap = None
- self.update_strength()
- self._update_state()
-
- def __wireless_properties_changed_cb(self, properties):
- if 'ActiveAccessPoint' in properties:
- self.__update_active_ap(properties['ActiveAccessPoint'])
-
- def __get_active_ap_reply_cb(self, ap_path):
- self.__update_active_ap(ap_path)
-
- def __get_active_ap_error_cb(self, err):
- logging.error('Error getting the active access point: %s', err)
-
- def __get_device_caps_reply_cb(self, caps):
- self._device_caps = caps
-
- def __get_device_caps_error_cb(self, err):
- logging.error('Error getting the wireless device properties: %s', err)
-
- def __get_device_state_reply_cb(self, state):
- self._device_state = state
- self._update()
-
- def __get_device_state_error_cb(self, err):
- logging.error('Error getting the device state: %s', err)
-
- def _update(self):
- self._update_state()
- self._update_color()
-
- def _update_state(self):
- if self._active_ap is not None:
- state = self._device_state
- else:
- state = network.DEVICE_STATE_UNKNOWN
-
- if self._mode == network.NM_802_11_MODE_ADHOC and \
- network.is_sugar_adhoc_network(self._name):
- channel = max([1] + [ap.channel for ap in
- self._access_points.values()])
- if state == network.DEVICE_STATE_ACTIVATED:
- icon_name = 'network-adhoc-%s-connected' % channel
- else:
- icon_name = 'network-adhoc-%s' % channel
- self.props.icon_name = icon_name
- icon = self._palette.props.icon
- icon.props.icon_name = icon_name
- else:
- if state == network.DEVICE_STATE_ACTIVATED:
- connection = network.find_connection_by_ssid(self._name)
- if connection is not None:
- if self._mode == network.NM_802_11_MODE_INFRA:
- connection.set_connected()
- icon_name = '%s-connected' % _AP_ICON_NAME
- else:
- icon_name = _AP_ICON_NAME
-
- icon_name = get_icon_state(icon_name, self._strength)
- if icon_name:
- self.props.icon_name = icon_name
- icon = self._palette.props.icon
- icon.props.icon_name = icon_name
-
- if state == network.DEVICE_STATE_PREPARE or \
- state == network.DEVICE_STATE_CONFIG or \
- state == network.DEVICE_STATE_NEED_AUTH or \
- state == network.DEVICE_STATE_IP_CONFIG:
- if self._disconnect_item:
- self._disconnect_item.show()
- self._connect_item.hide()
- self._palette.props.secondary_text = _('Connecting...')
- self.props.pulsing = True
- elif state == network.DEVICE_STATE_ACTIVATED:
- if self._disconnect_item:
- self._disconnect_item.show()
- self._connect_item.hide()
- self._palette.props.secondary_text = _('Connected')
- self.props.pulsing = False
- else:
- if self._disconnect_item:
- self._disconnect_item.hide()
- self._connect_item.show()
- self._palette.props.secondary_text = None
- self.props.pulsing = False
-
- def _update_color(self):
- if self._greyed_out:
- self.props.pulsing = False
- self.props.base_color = XoColor('#D5D5D5,#D5D5D5')
- else:
- self.props.base_color = self._color
-
- def _disconnect_activate_cb(self, item):
- pass
-
- def _add_ciphers_from_flags(self, flags, pairwise):
- ciphers = []
- if pairwise:
- if flags & network.NM_802_11_AP_SEC_PAIR_TKIP:
- ciphers.append("tkip")
- if flags & network.NM_802_11_AP_SEC_PAIR_CCMP:
- ciphers.append("ccmp")
- else:
- if flags & network.NM_802_11_AP_SEC_GROUP_WEP40:
- ciphers.append("wep40")
- if flags & network.NM_802_11_AP_SEC_GROUP_WEP104:
- ciphers.append("wep104")
- if flags & network.NM_802_11_AP_SEC_GROUP_TKIP:
- ciphers.append("tkip")
- if flags & network.NM_802_11_AP_SEC_GROUP_CCMP:
- ciphers.append("ccmp")
- return ciphers
-
- def _get_security(self):
- if not (self._flags & network.NM_802_11_AP_FLAGS_PRIVACY) and \
- (self._wpa_flags == network.NM_802_11_AP_SEC_NONE) and \
- (self._rsn_flags == network.NM_802_11_AP_SEC_NONE):
- # No security
- return None
-
- if (self._flags & network.NM_802_11_AP_FLAGS_PRIVACY) and \
- (self._wpa_flags == network.NM_802_11_AP_SEC_NONE) and \
- (self._rsn_flags == network.NM_802_11_AP_SEC_NONE):
- # Static WEP, Dynamic WEP, or LEAP
- wireless_security = WirelessSecurity()
- wireless_security.key_mgmt = 'none'
- return wireless_security
-
- if (self._mode != network.NM_802_11_MODE_INFRA):
- # Stuff after this point requires infrastructure
- logging.error('The infrastructure mode is not supoorted'
- ' by your wireless device.')
- return None
-
- if (self._rsn_flags & network.NM_802_11_AP_SEC_KEY_MGMT_PSK) and \
- (self._device_caps & network.NM_802_11_DEVICE_CAP_RSN):
- # WPA2 PSK first
- pairwise = self._add_ciphers_from_flags(self._rsn_flags, True)
- group = self._add_ciphers_from_flags(self._rsn_flags, False)
- wireless_security = WirelessSecurity()
- wireless_security.key_mgmt = 'wpa-psk'
- wireless_security.proto = 'rsn'
- wireless_security.pairwise = pairwise
- wireless_security.group = group
- return wireless_security
-
- if (self._wpa_flags & network.NM_802_11_AP_SEC_KEY_MGMT_PSK) and \
- (self._device_caps & network.NM_802_11_DEVICE_CAP_WPA):
- # WPA PSK
- pairwise = self._add_ciphers_from_flags(self._wpa_flags, True)
- group = self._add_ciphers_from_flags(self._wpa_flags, False)
- wireless_security = WirelessSecurity()
- wireless_security.key_mgmt = 'wpa-psk'
- wireless_security.proto = 'wpa'
- wireless_security.pairwise = pairwise
- wireless_security.group = group
- return wireless_security
-
- def __connect_activate_cb(self, icon):
- self._connect()
-
- def __button_release_event_cb(self, icon, event):
- self._connect()
-
- def _connect(self):
- connection = network.find_connection_by_ssid(self._name)
- if connection is None:
- settings = Settings()
- settings.connection.id = 'Auto ' + self._name
- uuid = settings.connection.uuid = unique_id()
- settings.connection.type = '802-11-wireless'
- settings.wireless.ssid = self._name
-
- if self._mode == network.NM_802_11_MODE_INFRA:
- settings.wireless.mode = 'infrastructure'
- elif self._mode == network.NM_802_11_MODE_ADHOC:
- settings.wireless.mode = 'adhoc'
- settings.wireless.band = 'bg'
- settings.ip4_config = IP4Config()
- settings.ip4_config.method = 'link-local'
-
- wireless_security = self._get_security()
- settings.wireless_security = wireless_security
-
- if wireless_security is not None:
- settings.wireless.security = '802-11-wireless-security'
-
- connection = network.add_connection(uuid, settings)
-
- obj = self._bus.get_object(_NM_SERVICE, _NM_PATH)
- netmgr = dbus.Interface(obj, _NM_IFACE)
-
- netmgr.ActivateConnection(network.SETTINGS_SERVICE, connection.path,
- self._device.object_path,
- "/",
- reply_handler=self.__activate_reply_cb,
- error_handler=self.__activate_error_cb)
-
- def __activate_reply_cb(self, connection):
- logging.debug('Connection activated: %s', connection)
-
- def __activate_error_cb(self, err):
- logging.error('Failed to activate connection: %s', err)
-
- def set_filter(self, query):
- self._greyed_out = self._name.lower().find(query) == -1
- self._update_state()
- self._update_color()
-
- def create_keydialog(self, settings, response):
- keydialog.create(self._name, self._flags, self._wpa_flags,
- self._rsn_flags, self._device_caps, settings, response)
-
- def update_strength(self):
- if self._active_ap is not None:
- # display strength of AP that we are connected to
- new_strength = self._active_ap.strength
- else:
- # display the strength of the strongest AP that makes up this
- # network, also considering that there may be no APs
- new_strength = max([0] + [ap.strength for ap in
- self._access_points.values()])
-
- if new_strength != self._strength:
- self._strength = new_strength
- self._update_state()
-
- def add_ap(self, ap):
- self._access_points[ap.model.object_path] = ap
- self.update_strength()
-
- def remove_ap(self, ap):
- path = ap.model.object_path
- if path not in self._access_points:
- return
- del self._access_points[path]
- if self._active_ap == ap:
- self._active_ap = None
- self.update_strength()
-
- def num_aps(self):
- return len(self._access_points)
-
- def find_ap(self, ap_path):
- if ap_path not in self._access_points:
- return None
- return self._access_points[ap_path]
-
- def is_olpc_mesh(self):
- return self._mode == network.NM_802_11_MODE_ADHOC \
- and self.name == "olpc-mesh"
-
- def remove_all_aps(self):
- for ap in self._access_points.values():
- ap.disconnect()
- self._access_points = {}
- self._active_ap = None
- self.update_strength()
-
- def disconnect(self):
- self._bus.remove_signal_receiver(self.__device_state_changed_cb,
- signal_name='StateChanged',
- path=self._device.object_path,
- dbus_interface=_NM_DEVICE_IFACE)
- self._bus.remove_signal_receiver(self.__wireless_properties_changed_cb,
- signal_name='PropertiesChanged',
- path=self._device.object_path,
- dbus_interface=_NM_WIRELESS_IFACE)
-
-class SugarAdhocView(CanvasPulsingIcon):
- """To mimic the mesh behavior on devices where mesh hardware is
- not available we support the creation of an Ad-hoc network on
- three channels 1, 6, 11. This is the class for an icon
- representing a channel in the neighborhood view.
-
- """
-
- _ICON_NAME = 'network-adhoc-'
- _NAME = 'Ad-hoc Network '
-
- def __init__(self, channel):
- CanvasPulsingIcon.__init__(self,
- icon_name=self._ICON_NAME + str(channel),
- size=style.STANDARD_ICON_SIZE, cache=True)
- self._bus = dbus.SystemBus()
- self._channel = channel
- self._disconnect_item = None
- self._connect_item = None
- self._palette_icon = None
- self._greyed_out = False
-
- get_adhoc_manager_instance().connect('members-changed',
- self.__members_changed_cb)
- get_adhoc_manager_instance().connect('state-changed',
- self.__state_changed_cb)
-
- self.connect('button-release-event', self.__button_release_event_cb)
-
- pulse_color = XoColor('%s,%s' % (style.COLOR_BUTTON_GREY.get_svg(),
- style.COLOR_TRANSPARENT.get_svg()))
- self.props.pulse_color = pulse_color
- self._state_color = XoColor('%s,%s' % \
- (profile.get_color().get_stroke_color(),
- style.COLOR_TRANSPARENT.get_svg()))
- self.props.base_color = self._state_color
- self._palette = self._create_palette()
- self.set_palette(self._palette)
- self._palette_icon.props.xo_color = self._state_color
-
- def _create_palette(self):
- self._palette_icon = Icon( \
- icon_name=self._ICON_NAME + str(self._channel),
- icon_size=style.STANDARD_ICON_SIZE)
-
- palette_ = palette.Palette(_("Ad-hoc Network %d") % self._channel,
- icon=self._palette_icon)
-
- self._connect_item = MenuItem(_('Connect'), 'dialog-ok')
- self._connect_item.connect('activate', self.__connect_activate_cb)
- palette_.menu.append(self._connect_item)
-
- self._disconnect_item = MenuItem(_('Disconnect'), 'media-eject')
- self._disconnect_item.connect('activate',
- self.__disconnect_activate_cb)
- palette_.menu.append(self._disconnect_item)
-
- return palette_
-
- def __button_release_event_cb(self, icon, event):
- get_adhoc_manager_instance().activate_channel(self._channel)
-
- def __connect_activate_cb(self, icon):
- get_adhoc_manager_instance().activate_channel(self._channel)
-
- def __disconnect_activate_cb(self, icon):
- get_adhoc_manager_instance().deactivate_active_channel()
-
- def __state_changed_cb(self, adhoc_manager, channel, device_state):
- if self._channel == channel:
- state = device_state
- else:
- state = network.DEVICE_STATE_UNKNOWN
-
- if state == network.DEVICE_STATE_ACTIVATED:
- icon_name = '%s-connected' % (self._ICON_NAME + str(self._channel))
- else:
- icon_name = self._ICON_NAME + str(self._channel)
-
- self.props.base_color = self._state_color
- self._palette_icon.props.xo_color = self._state_color
-
- if icon_name is not None:
- self.props.icon_name = icon_name
- icon = self._palette.props.icon
- icon.props.icon_name = icon_name
-
- if state in [network.DEVICE_STATE_PREPARE,
- network.DEVICE_STATE_CONFIG,
- network.DEVICE_STATE_NEED_AUTH,
- network.DEVICE_STATE_IP_CONFIG]:
- if self._disconnect_item:
- self._disconnect_item.show()
- self._connect_item.hide()
- self._palette.props.secondary_text = _('Connecting...')
- self.props.pulsing = True
- elif state == network.DEVICE_STATE_ACTIVATED:
- if self._disconnect_item:
- self._disconnect_item.show()
- self._connect_item.hide()
- self._palette.props.secondary_text = _('Connected')
- self.props.pulsing = False
- else:
- if self._disconnect_item:
- self._disconnect_item.hide()
- self._connect_item.show()
- self._palette.props.secondary_text = None
- self.props.pulsing = False
-
- def _update_color(self):
- if self._greyed_out:
- self.props.base_color = XoColor('#D5D5D5,#D5D5D5')
- else:
- self.props.base_color = self._state_color
-
- def __members_changed_cb(self, adhoc_manager, channel, has_members):
- if channel == self._channel:
- if has_members == True:
- self._state_color = profile.get_color()
- self.props.base_color = self._state_color
- self._palette_icon.props.xo_color = self._state_color
- else:
- color = '%s,%s' % (profile.get_color().get_stroke_color(),
- style.COLOR_TRANSPARENT.get_svg())
- self._state_color = XoColor(color)
- self.props.base_color = self._state_color
- self._palette_icon.props.xo_color = self._state_color
-
- def set_filter(self, query):
- name = self._NAME + str(self._channel)
- self._greyed_out = name.lower().find(query) == -1
- self._update_color()
-
-
-class OlpcMeshView(CanvasPulsingIcon):
- def __init__(self, mesh_mgr, channel):
- CanvasPulsingIcon.__init__(self, icon_name=_OLPC_MESH_ICON_NAME,
- size=style.STANDARD_ICON_SIZE, cache=True)
- self._bus = dbus.SystemBus()
- self._channel = channel
- self._mesh_mgr = mesh_mgr
- self._disconnect_item = None
- self._connect_item = None
- self._greyed_out = False
- self._name = ''
- self._device_state = None
- self._connection = None
- self._active = False
- device = mesh_mgr.mesh_device
-
- self.connect('button-release-event', self.__button_release_event_cb)
-
- interface_props = dbus.Interface(device,
- 'org.freedesktop.DBus.Properties')
- interface_props.Get(_NM_DEVICE_IFACE, 'State',
- reply_handler=self.__get_device_state_reply_cb,
- error_handler=self.__get_device_state_error_cb)
- interface_props.Get(_NM_OLPC_MESH_IFACE, 'ActiveChannel',
- reply_handler=self.__get_active_channel_reply_cb,
- error_handler=self.__get_active_channel_error_cb)
-
- self._bus.add_signal_receiver(self.__device_state_changed_cb,
- signal_name='StateChanged',
- path=device.object_path,
- dbus_interface=_NM_DEVICE_IFACE)
- self._bus.add_signal_receiver(self.__wireless_properties_changed_cb,
- signal_name='PropertiesChanged',
- path=device.object_path,
- dbus_interface=_NM_OLPC_MESH_IFACE)
-
- pulse_color = XoColor('%s,%s' % (style.COLOR_BUTTON_GREY.get_svg(),
- style.COLOR_TRANSPARENT.get_svg()))
- self.props.pulse_color = pulse_color
- self.props.base_color = profile.get_color()
- self._palette = self._create_palette()
- self.set_palette(self._palette)
-
- def _create_palette(self):
- _palette = palette.Palette(_("Mesh Network %d") % self._channel)
-
- self._connect_item = MenuItem(_('Connect'), 'dialog-ok')
- self._connect_item.connect('activate', self.__connect_activate_cb)
- _palette.menu.append(self._connect_item)
-
- return _palette
-
- def __get_device_state_reply_cb(self, state):
- self._device_state = state
- self._update()
-
- def __get_device_state_error_cb(self, err):
- logging.error('Error getting the device state: %s', err)
-
- def __device_state_changed_cb(self, new_state, old_state, reason):
- self._device_state = new_state
- self._update()
-
- def __get_active_channel_reply_cb(self, channel):
- self._active = (channel == self._channel)
- self._update()
-
- def __get_active_channel_error_cb(self, err):
- logging.error('Error getting the active channel: %s', err)
-
- def __wireless_properties_changed_cb(self, properties):
- if 'ActiveChannel' in properties:
- channel = properties['ActiveChannel']
- self._active = (channel == self._channel)
- self._update()
-
- def _update(self):
- if self._active:
- state = self._device_state
- else:
- state = network.DEVICE_STATE_UNKNOWN
-
- if state in [network.DEVICE_STATE_PREPARE,
- network.DEVICE_STATE_CONFIG,
- network.DEVICE_STATE_NEED_AUTH,
- network.DEVICE_STATE_IP_CONFIG]:
- if self._disconnect_item:
- self._disconnect_item.show()
- self._connect_item.hide()
- self._palette.props.secondary_text = _('Connecting...')
- self.props.pulsing = True
- elif state == network.DEVICE_STATE_ACTIVATED:
- if self._disconnect_item:
- self._disconnect_item.show()
- self._connect_item.hide()
- self._palette.props.secondary_text = _('Connected')
- self.props.pulsing = False
- else:
- if self._disconnect_item:
- self._disconnect_item.hide()
- self._connect_item.show()
- self._palette.props.secondary_text = None
- self.props.pulsing = False
-
- def _update_color(self):
- if self._greyed_out:
- self.props.base_color = XoColor('#D5D5D5,#D5D5D5')
- else:
- self.props.base_color = profile.get_color()
-
- def __connect_activate_cb(self, icon):
- self._connect()
-
- def __button_release_event_cb(self, icon, event):
- self._connect()
-
- def _connect(self):
- self._mesh_mgr.user_activate_channel(self._channel)
-
- def __activate_reply_cb(self, connection):
- logging.debug('Connection activated: %s', connection)
-
- def __activate_error_cb(self, err):
- logging.error('Failed to activate connection: %s', err)
-
- def set_filter(self, query):
- self._greyed_out = (query != '')
- self._update_color()
-
- def disconnect(self):
- device_object_path = self._mesh_mgr.mesh_device.object_path
-
- self._bus.remove_signal_receiver(self.__device_state_changed_cb,
- signal_name='StateChanged',
- path=device_object_path,
- dbus_interface=_NM_DEVICE_IFACE)
- self._bus.remove_signal_receiver(self.__wireless_properties_changed_cb,
- signal_name='PropertiesChanged',
- path=device_object_path,
- dbus_interface=_NM_OLPC_MESH_IFACE)
-
-
class ActivityView(hippo.CanvasBox):
def __init__(self, model):
hippo.CanvasBox.__init__(self)
self._model = model
+ self._model.connect('current-buddy-added', self.__buddy_added_cb)
+ self._model.connect('current-buddy-removed', self.__buddy_removed_cb)
+
self._icons = {}
self._palette = None
@@ -745,33 +76,30 @@ class ActivityView(hippo.CanvasBox):
self._icon = self._create_icon()
self._layout.add(self._icon, center=True)
- self._update_palette()
+ self._palette = self._create_palette()
+ self._icon.set_palette(self._palette)
- activity = self._model.activity
- activity.connect('notify::name', self._name_changed_cb)
- activity.connect('notify::color', self._color_changed_cb)
- activity.connect('notify::private', self._private_changed_cb)
- activity.connect('joined', self._joined_changed_cb)
- #FIXME: 'joined' signal not working, see #5032
+ for buddy in self._model.props.current_buddies:
+ self._add_buddy(buddy)
def _create_icon(self):
- icon = CanvasIcon(file_name=self._model.get_icon_name(),
+ icon = CanvasIcon(file_name=self._model.bundle.get_icon(),
xo_color=self._model.get_color(), cache=True,
size=style.STANDARD_ICON_SIZE)
icon.connect('activated', self._clicked_cb)
return icon
def _create_palette(self):
- p_text = glib.markup_escape_text(self._model.activity.props.name)
- p_icon = Icon(file=self._model.get_icon_name(),
+ p_text = glib.markup_escape_text(self._model.bundle.get_name())
+ p_icon = Icon(file=self._model.bundle.get_icon(),
xo_color=self._model.get_color())
p_icon.props.icon_size = gtk.ICON_SIZE_LARGE_TOOLBAR
p = palette.Palette(None,
primary_text=p_text,
icon=p_icon)
- private = self._model.activity.props.private
- joined = self._model.activity.props.joined
+ private = self._model.props.private
+ joined = get_owner_instance() in self._model.props.buddies
if joined:
item = MenuItem(_('Resume'), 'activity-start')
@@ -786,32 +114,30 @@ class ActivityView(hippo.CanvasBox):
return p
- def _update_palette(self):
- self._palette = self._create_palette()
- self._icon.set_palette(self._palette)
-
def has_buddy_icon(self, key):
return self._icons.has_key(key)
- def add_buddy_icon(self, key, icon):
- self._icons[key] = icon
+ def __buddy_added_cb(self, activity, buddy):
+ self._add_buddy(buddy)
+
+ def _add_buddy(self, buddy):
+ icon = BuddyIcon(buddy, style.STANDARD_ICON_SIZE)
+ self._icons[buddy.props.key] = icon
self._layout.add(icon)
- def remove_buddy_icon(self, key):
- icon = self._icons[key]
- del self._icons[key]
+ def __buddy_removed_cb(self, activity, buddy):
+ icon = self._icons[buddy.props.key]
+ del self._icons[buddy.props.key]
icon.destroy()
def _clicked_cb(self, item):
- bundle_id = self._model.get_bundle_id()
- bundle = bundleregistry.get_registry().get_bundle(bundle_id)
-
- misc.launch(bundle, activity_id=self._model.get_id(),
- color=self._model.get_color())
+ bundle = self._model.get_bundle()
+ misc.launch(bundle, activity_id=self._model.activity_id,
+ color=self._model.get_color())
def set_filter(self, query):
- text_to_check = self._model.activity.props.name.lower() + \
- self._model.activity.props.type.lower()
+ text_to_check = self._model.bundle.get_name().lower() + \
+ self._model.bundle.get_bundle_id().lower()
if text_to_check.find(query) == -1:
self._icon.props.stroke_color = '#D5D5D5'
self._icon.props.fill_color = style.COLOR_TRANSPARENT.get_svg()
@@ -822,21 +148,6 @@ class ActivityView(hippo.CanvasBox):
if hasattr(icon, 'set_filter'):
icon.set_filter(query)
- def _name_changed_cb(self, activity, pspec):
- self._update_palette()
-
- def _color_changed_cb(self, activity, pspec):
- self._layout.remove(self._icon)
- self._icon = self._create_icon()
- self._layout.add(self._icon, center=True)
- self._icon.set_palette(self._palette)
-
- def _private_changed_cb(self, activity, pspec):
- self._update_palette()
-
- def _joined_changed_cb(self, widget, event):
- logging.debug('ActivityView._joined_changed_cb')
-
_AUTOSEARCH_TIMEOUT = 1000
@@ -1122,11 +433,10 @@ class MeshBox(gtk.VBox):
self._layout_box.set_layout(self._layout)
for buddy_model in self._model.get_buddies():
- self._add_alone_buddy(buddy_model)
+ self._add_buddy(buddy_model)
self._model.connect('buddy-added', self._buddy_added_cb)
self._model.connect('buddy-removed', self._buddy_removed_cb)
- self._model.connect('buddy-moved', self._buddy_moved_cb)
for activity_model in self._model.get_activities():
self._add_activity(activity_model)
@@ -1150,24 +460,23 @@ class MeshBox(gtk.VBox):
gtk.VBox.do_size_allocate(self, allocation)
def _buddy_added_cb(self, model, buddy_model):
- self._add_alone_buddy(buddy_model)
+ self._add_buddy(buddy_model)
def _buddy_removed_cb(self, model, buddy_model):
self._remove_buddy(buddy_model)
- def _buddy_moved_cb(self, model, buddy_model, activity_model):
- # Owner doesn't move from the center
- if buddy_model.is_owner():
- return
- self._move_buddy(buddy_model, activity_model)
-
def _activity_added_cb(self, model, activity_model):
self._add_activity(activity_model)
def _activity_removed_cb(self, model, activity_model):
self._remove_activity(activity_model)
- def _add_alone_buddy(self, buddy_model):
+ def _add_buddy(self, buddy_model):
+ logging.debug('MeshBox._add_buddy %r', buddy_model.props.key)
+ buddy_model.connect('notify::current-activity',
+ self.__buddy_notify_current_activity_cb)
+ if buddy_model.props.current_activity is not None:
+ return
icon = BuddyIcon(buddy_model)
if buddy_model.is_owner():
self._owner_icon = icon
@@ -1176,36 +485,23 @@ class MeshBox(gtk.VBox):
if hasattr(icon, 'set_filter'):
icon.set_filter(self._query)
- self._buddies[buddy_model.get_buddy().object_path()] = icon
+ self._buddies[buddy_model.props.key] = icon
- def _remove_alone_buddy(self, buddy_model):
- icon = self._buddies[buddy_model.get_buddy().object_path()]
+ def _remove_buddy(self, buddy_model):
+ logging.debug('MeshBox._remove_buddy')
+ icon = self._buddies[buddy_model.props.key]
self._layout.remove(icon)
- del self._buddies[buddy_model.get_buddy().object_path()]
+ del self._buddies[buddy_model.props.key]
icon.destroy()
- def _remove_buddy(self, buddy_model):
- object_path = buddy_model.get_buddy().object_path()
- if self._buddies.has_key(object_path):
- self._remove_alone_buddy(buddy_model)
- else:
- for activity in self._activities.values():
- if activity.has_buddy_icon(object_path):
- activity.remove_buddy_icon(object_path)
-
- def _move_buddy(self, buddy_model, activity_model):
- self._remove_buddy(buddy_model)
-
- if activity_model == None:
- self._add_alone_buddy(buddy_model)
- elif activity_model.get_id() in self._activities:
- activity = self._activities[activity_model.get_id()]
-
- icon = BuddyIcon(buddy_model, style.STANDARD_ICON_SIZE)
- activity.add_buddy_icon(buddy_model.get_buddy().object_path(), icon)
-
- if hasattr(icon, 'set_filter'):
- icon.set_filter(self._query)
+ def __buddy_notify_current_activity_cb(self, buddy_model, pspec):
+ logging.debug('MeshBox.__buddy_notify_current_activity_cb %s',
+ buddy_model.props.current_activity)
+ if buddy_model.props.current_activity is None:
+ if not buddy_model.props.key in self._buddies:
+ self._add_buddy(buddy_model)
+ elif buddy_model.props.key in self._buddies:
+ self._remove_buddy(buddy_model)
def _add_activity(self, activity_model):
icon = ActivityView(activity_model)
@@ -1214,12 +510,12 @@ class MeshBox(gtk.VBox):
if hasattr(icon, 'set_filter'):
icon.set_filter(self._query)
- self._activities[activity_model.get_id()] = icon
+ self._activities[activity_model.activity_id] = icon
def _remove_activity(self, activity_model):
- icon = self._activities[activity_model.get_id()]
+ icon = self._activities[activity_model.activity_id]
self._layout.remove(icon)
- del self._activities[activity_model.get_id()]
+ del self._activities[activity_model.activity_id]
icon.destroy()
# add AP to its corresponding network icon on the desktop,
@@ -1315,7 +611,6 @@ class MeshBox(gtk.VBox):
def remove_adhoc_networks(self):
for icon in self._adhoc_networks:
- icon.disconnect()
self._layout.remove(icon)
self._adhoc_networks = []