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.py679
1 files changed, 679 insertions, 0 deletions
diff --git a/src/jarabe/desktop/meshbox.py b/src/jarabe/desktop/meshbox.py
new file mode 100644
index 0000000..20dc413
--- /dev/null
+++ b/src/jarabe/desktop/meshbox.py
@@ -0,0 +1,679 @@
+# 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
+# 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
+
+from gettext import gettext as _
+import logging
+
+import dbus
+import hippo
+import glib
+import gobject
+import gtk
+import gconf
+
+from sugar.graphics.icon import CanvasIcon, Icon
+from sugar.graphics import style
+from sugar.graphics import palette
+from sugar.graphics import iconentry
+from sugar.graphics.menuitem import MenuItem
+
+from jarabe.model import neighborhood
+from jarabe.model.buddy import get_owner_instance
+from jarabe.view.buddyicon import BuddyIcon
+from jarabe.desktop.snowflakelayout import SnowflakeLayout
+from jarabe.desktop.spreadlayout import SpreadLayout
+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 AccessPoint
+from jarabe.model.olpcmesh import OlpcMeshManager
+from jarabe.model.adhoc import get_adhoc_manager_instance
+from jarabe.journal import misc
+
+
+_AP_ICON_NAME = 'network-wireless'
+_OLPC_MESH_ICON_NAME = 'network-mesh'
+
+_AUTOSEARCH_TIMEOUT = 1000
+_FILTERED_ALPHA = 0.33
+
+
+class _ActivityIcon(CanvasIcon):
+ def __init__(self, model, file_name, xo_color,
+ size=style.STANDARD_ICON_SIZE):
+ CanvasIcon.__init__(self, file_name=file_name,
+ xo_color=xo_color,
+ size=size)
+ self._model = model
+ self.connect('activated', self._clicked_cb)
+
+ def create_palette(self):
+ primary_text = glib.markup_escape_text(self._model.bundle.get_name())
+ secondary_text = glib.markup_escape_text(self._model.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=primary_text,
+ secondary_text=secondary_text,
+ icon=p_icon)
+
+ private = self._model.props.private
+ joined = get_owner_instance() in self._model.props.buddies
+
+ if joined:
+ item = MenuItem(_('Resume'), 'activity-start')
+ item.connect('activate', self._clicked_cb)
+ item.show()
+ p.menu.append(item)
+ elif not private:
+ item = MenuItem(_('Join'), 'activity-start')
+ item.connect('activate', self._clicked_cb)
+ item.show()
+ p.menu.append(item)
+
+ return p
+
+ def _clicked_cb(self, item):
+ bundle = self._model.get_bundle()
+ misc.launch(bundle, activity_id=self._model.activity_id,
+ color=self._model.get_color())
+
+
+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._layout = SnowflakeLayout()
+ self.set_layout(self._layout)
+
+ self._icon = self._create_icon()
+ self._layout.add(self._icon, center=True)
+
+ self._icon.palette_invoker.cache_palette = False
+
+ for buddy in self._model.props.current_buddies:
+ self._add_buddy(buddy)
+
+ def _create_icon(self):
+ icon = _ActivityIcon(self._model,
+ file_name=self._model.bundle.get_icon(),
+ xo_color=self._model.get_color(),
+ size=style.STANDARD_ICON_SIZE)
+ return icon
+
+ def has_buddy_icon(self, key):
+ return key in self._icons
+
+ 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 __buddy_removed_cb(self, activity, buddy):
+ icon = self._icons[buddy.props.key]
+ del self._icons[buddy.props.key]
+ icon.destroy()
+
+ def set_filter(self, query):
+ text_to_check = self._model.bundle.get_name().lower() + \
+ self._model.bundle.get_bundle_id().lower()
+ self._icon.props.xo_color = self._model.get_color()
+ if text_to_check.find(query) == -1:
+ self._icon.alpha = _FILTERED_ALPHA
+ else:
+ self._icon.alpha = 1.0
+ for icon in self._icons.itervalues():
+ if hasattr(icon, 'set_filter'):
+ icon.set_filter(query)
+
+
+class MeshToolbar(gtk.Toolbar):
+ __gtype_name__ = 'MeshToolbar'
+
+ __gsignals__ = {
+ 'query-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([str])),
+ }
+
+ def __init__(self):
+ gtk.Toolbar.__init__(self)
+
+ self._query = None
+ self._autosearch_timer = None
+
+ self._add_separator()
+
+ tool_item = gtk.ToolItem()
+ self.insert(tool_item, -1)
+ tool_item.show()
+
+ self.search_entry = iconentry.IconEntry()
+ self.search_entry.set_icon_from_name(iconentry.ICON_ENTRY_PRIMARY,
+ 'system-search')
+ self.search_entry.add_clear_button()
+ self.search_entry.set_width_chars(25)
+ self.search_entry.connect('activate', self._entry_activated_cb)
+ self.search_entry.connect('changed', self._entry_changed_cb)
+ tool_item.add(self.search_entry)
+ self.search_entry.show()
+
+ self._add_separator(expand=True)
+
+ def _add_separator(self, expand=False):
+ separator = gtk.SeparatorToolItem()
+ separator.props.draw = False
+ if expand:
+ separator.set_expand(True)
+ else:
+ separator.set_size_request(style.GRID_CELL_SIZE,
+ style.GRID_CELL_SIZE)
+ self.insert(separator, -1)
+ separator.show()
+
+ def _entry_activated_cb(self, entry):
+ if self._autosearch_timer:
+ gobject.source_remove(self._autosearch_timer)
+ new_query = entry.props.text
+ if self._query != new_query:
+ self._query = new_query
+ self.emit('query-changed', self._query)
+
+ def _entry_changed_cb(self, entry):
+ if not entry.props.text:
+ entry.activate()
+ return
+
+ if self._autosearch_timer:
+ gobject.source_remove(self._autosearch_timer)
+ self._autosearch_timer = gobject.timeout_add(_AUTOSEARCH_TIMEOUT,
+ self._autosearch_timer_cb)
+
+ def _autosearch_timer_cb(self):
+ logging.debug('_autosearch_timer_cb')
+ self._autosearch_timer = None
+ self.search_entry.activate()
+ return False
+
+
+class DeviceObserver(gobject.GObject):
+ __gsignals__ = {
+ 'access-point-added': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([gobject.TYPE_PYOBJECT])),
+ 'access-point-removed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([gobject.TYPE_PYOBJECT])),
+ }
+
+ def __init__(self, device):
+ gobject.GObject.__init__(self)
+ self._bus = dbus.SystemBus()
+ self.device = device
+
+ wireless = dbus.Interface(device, network.NM_WIRELESS_IFACE)
+ wireless.GetAccessPoints(
+ reply_handler=self._get_access_points_reply_cb,
+ error_handler=self._get_access_points_error_cb)
+
+ self._bus.add_signal_receiver(self.__access_point_added_cb,
+ signal_name='AccessPointAdded',
+ path=device.object_path,
+ dbus_interface=network.NM_WIRELESS_IFACE)
+ self._bus.add_signal_receiver(self.__access_point_removed_cb,
+ signal_name='AccessPointRemoved',
+ path=device.object_path,
+ dbus_interface=network.NM_WIRELESS_IFACE)
+
+ def _get_access_points_reply_cb(self, access_points_o):
+ for ap_o in access_points_o:
+ ap = self._bus.get_object(network.NM_SERVICE, ap_o)
+ self.emit('access-point-added', ap)
+
+ def _get_access_points_error_cb(self, err):
+ logging.error('Failed to get access points: %s', err)
+
+ def __access_point_added_cb(self, access_point_o):
+ ap = self._bus.get_object(network.NM_SERVICE, access_point_o)
+ self.emit('access-point-added', ap)
+
+ def __access_point_removed_cb(self, access_point_o):
+ self.emit('access-point-removed', access_point_o)
+
+ def disconnect(self):
+ self._bus.remove_signal_receiver(self.__access_point_added_cb,
+ signal_name='AccessPointAdded',
+ path=self.device.object_path,
+ dbus_interface=network.NM_WIRELESS_IFACE)
+ self._bus.remove_signal_receiver(self.__access_point_removed_cb,
+ signal_name='AccessPointRemoved',
+ path=self.device.object_path,
+ dbus_interface=network.NM_WIRELESS_IFACE)
+
+
+class NetworkManagerObserver(object):
+
+ _SHOW_ADHOC_GCONF_KEY = '/desktop/sugar/network/adhoc'
+
+ def __init__(self, box):
+ self._box = box
+ self._bus = None
+ self._devices = {}
+ self._netmgr = None
+ self._olpc_mesh_device_o = None
+
+ client = gconf.client_get_default()
+ self._have_adhoc_networks = client.get_bool(self._SHOW_ADHOC_GCONF_KEY)
+
+ def listen(self):
+ try:
+ self._bus = dbus.SystemBus()
+ self._netmgr = network.get_manager()
+ except dbus.DBusException:
+ logging.debug('NetworkManager not available')
+ return
+
+ self._netmgr.GetDevices(reply_handler=self.__get_devices_reply_cb,
+ error_handler=self.__get_devices_error_cb)
+
+ self._bus.add_signal_receiver(self.__device_added_cb,
+ signal_name='DeviceAdded',
+ dbus_interface=network.NM_IFACE)
+ self._bus.add_signal_receiver(self.__device_removed_cb,
+ signal_name='DeviceRemoved',
+ dbus_interface=network.NM_IFACE)
+ self._bus.add_signal_receiver(self.__properties_changed_cb,
+ signal_name='PropertiesChanged',
+ dbus_interface=network.NM_IFACE)
+
+ secret_agent = network.get_secret_agent()
+ if secret_agent is not None:
+ secret_agent.secrets_request.connect(self.__secrets_request_cb)
+
+ def __secrets_request_cb(self, **kwargs):
+ # FIXME It would be better to do all of this async, but I cannot think
+ # of a good way to. NM could really use some love here.
+
+ netmgr_props = dbus.Interface(self._netmgr, dbus.PROPERTIES_IFACE)
+ active_connections_o = netmgr_props.Get(network.NM_IFACE, 'ActiveConnections')
+
+ for conn_o in active_connections_o:
+ obj = self._bus.get_object(network.NM_IFACE, conn_o)
+ props = dbus.Interface(obj, dbus.PROPERTIES_IFACE)
+ state = props.Get(network.NM_ACTIVE_CONN_IFACE, 'State')
+ if state == network.NM_ACTIVE_CONNECTION_STATE_ACTIVATING:
+ ap_o = props.Get(network.NM_ACTIVE_CONN_IFACE, 'SpecificObject')
+ found = False
+ if ap_o != '/':
+ for net in self._box.wireless_networks.values():
+ if net.find_ap(ap_o) is not None:
+ found = True
+ net.create_keydialog(kwargs['response'])
+ if not found:
+ raise Exception('Could not determine AP for specific object'
+ ' %s' % conn_o)
+
+ def __get_devices_reply_cb(self, devices_o):
+ for dev_o in devices_o:
+ self._check_device(dev_o)
+
+ def __get_devices_error_cb(self, err):
+ logging.error('Failed to get devices: %s', err)
+
+ def _check_device(self, device_o):
+ device = self._bus.get_object(network.NM_SERVICE, device_o)
+ props = dbus.Interface(device, dbus.PROPERTIES_IFACE)
+
+ device_type = props.Get(network.NM_DEVICE_IFACE, 'DeviceType')
+ if device_type == network.NM_DEVICE_TYPE_WIFI:
+ if device_o in self._devices:
+ return
+ self._devices[device_o] = DeviceObserver(device)
+ self._devices[device_o].connect('access-point-added',
+ self.__ap_added_cb)
+ self._devices[device_o].connect('access-point-removed',
+ self.__ap_removed_cb)
+ if self._have_adhoc_networks:
+ self._box.add_adhoc_networks(device)
+ elif device_type == network.NM_DEVICE_TYPE_OLPC_MESH:
+ if device_o == self._olpc_mesh_device_o:
+ return
+ self._olpc_mesh_device_o = device_o
+ self._box.enable_olpc_mesh(device)
+
+ def _get_device_path_error_cb(self, err):
+ logging.error('Failed to get device type: %s', err)
+
+ def __device_added_cb(self, device_o):
+ self._check_device(device_o)
+
+ def __device_removed_cb(self, device_o):
+ if device_o in self._devices:
+ observer = self._devices[device_o]
+ observer.disconnect()
+ del self._devices[device_o]
+ if self._have_adhoc_networks:
+ self._box.remove_adhoc_networks()
+ return
+
+ if self._olpc_mesh_device_o == device_o:
+ self._box.disable_olpc_mesh(device_o)
+ self._olpc_mesh_device_o = None
+
+ def __ap_added_cb(self, device_observer, access_point):
+ self._box.add_access_point(device_observer.device, access_point)
+
+ def __ap_removed_cb(self, device_observer, access_point_o):
+ self._box.remove_access_point(access_point_o)
+
+ def __properties_changed_cb(self, properties):
+ if 'WirelessHardwareEnabled' in properties:
+ if properties['WirelessHardwareEnabled']:
+ if not self._have_adhoc_networks:
+ self._box.remove_adhoc_networks()
+ elif properties['WirelessHardwareEnabled']:
+ for device in self._devices:
+ if self._have_adhoc_networks:
+ self._box.add_adhoc_networks(device)
+
+
+class MeshBox(gtk.VBox):
+ __gtype_name__ = 'SugarMeshBox'
+
+ def __init__(self):
+ logging.debug('STARTUP: Loading the mesh view')
+
+ gobject.GObject.__init__(self)
+
+ self.wireless_networks = {}
+ self._adhoc_manager = None
+ self._adhoc_networks = []
+
+ self._model = neighborhood.get_model()
+ self._buddies = {}
+ self._activities = {}
+ self._mesh = []
+ self._buddy_to_activity = {}
+ self._suspended = True
+ self._query = ''
+ self._owner_icon = None
+
+ self._toolbar = MeshToolbar()
+ self._toolbar.connect('query-changed', self._toolbar_query_changed_cb)
+ self.pack_start(self._toolbar, expand=False)
+ self._toolbar.show()
+
+ canvas = hippo.Canvas()
+ self.add(canvas)
+ canvas.show()
+
+ self._layout_box = hippo.CanvasBox( \
+ background_color=style.COLOR_WHITE.get_int())
+ canvas.set_root(self._layout_box)
+
+ self._layout = SpreadLayout()
+ self._layout_box.set_layout(self._layout)
+
+ for buddy_model in self._model.get_buddies():
+ self._add_buddy(buddy_model)
+
+ self._model.connect('buddy-added', self._buddy_added_cb)
+ self._model.connect('buddy-removed', self._buddy_removed_cb)
+
+ for activity_model in self._model.get_activities():
+ self._add_activity(activity_model)
+
+ self._model.connect('activity-added', self._activity_added_cb)
+ self._model.connect('activity-removed', self._activity_removed_cb)
+
+ netmgr_observer = NetworkManagerObserver(self)
+ netmgr_observer.listen()
+
+ def do_size_allocate(self, allocation):
+ width = allocation.width
+ height = allocation.height
+
+ min_w_, icon_width = self._owner_icon.get_width_request()
+ min_h_, icon_height = self._owner_icon.get_height_request(icon_width)
+ x = (width - icon_width) / 2
+ y = (height - icon_height) / 2 - style.GRID_CELL_SIZE
+ self._layout.move(self._owner_icon, x, y)
+
+ gtk.VBox.do_size_allocate(self, allocation)
+
+ def _buddy_added_cb(self, model, buddy_model):
+ self._add_buddy(buddy_model)
+
+ def _buddy_removed_cb(self, model, buddy_model):
+ self._remove_buddy(buddy_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_buddy(self, buddy_model):
+ 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
+ self._layout.add(icon)
+
+ if hasattr(icon, 'set_filter'):
+ icon.set_filter(self._query)
+
+ self._buddies[buddy_model.props.key] = icon
+
+ 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.props.key]
+ icon.destroy()
+
+ 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)
+ self._layout.add(icon)
+
+ if hasattr(icon, 'set_filter'):
+ icon.set_filter(self._query)
+
+ self._activities[activity_model.activity_id] = icon
+
+ def _remove_activity(self, activity_model):
+ icon = self._activities[activity_model.activity_id]
+ self._layout.remove(icon)
+ del self._activities[activity_model.activity_id]
+ icon.destroy()
+
+ # add AP to its corresponding network icon on the desktop,
+ # creating one if it doesn't already exist
+ def _add_ap_to_network(self, ap):
+ hash_value = ap.network_hash()
+ if hash_value in self.wireless_networks:
+ self.wireless_networks[hash_value].add_ap(ap)
+ else:
+ # this is a new network
+ icon = WirelessNetworkView(ap)
+ self.wireless_networks[hash_value] = icon
+ self._layout.add(icon)
+ if hasattr(icon, 'set_filter'):
+ icon.set_filter(self._query)
+
+ def _remove_net_if_empty(self, net, hash_value):
+ # remove a network if it has no APs left
+ if net.num_aps() == 0:
+ net.disconnect()
+ self._layout.remove(net)
+ del self.wireless_networks[hash_value]
+
+ def _ap_props_changed_cb(self, ap, old_hash_value):
+ # if we have mesh hardware, ignore OLPC mesh networks that appear as
+ # normal wifi networks
+ if len(self._mesh) > 0 and ap.mode == network.NM_802_11_MODE_ADHOC \
+ and ap.ssid == 'olpc-mesh':
+ logging.debug('ignoring OLPC mesh IBSS')
+ ap.disconnect()
+ return
+
+ if self._adhoc_manager is not None and \
+ network.is_sugar_adhoc_network(ap.ssid) and \
+ ap.mode == network.NM_802_11_MODE_ADHOC:
+ if old_hash_value is None:
+ # new Ad-hoc network finished initializing
+ self._adhoc_manager.add_access_point(ap)
+ # we are called as well in other cases but we do not need to
+ # act here as we don't display signal strength for Ad-hoc networks
+ return
+
+ if old_hash_value is None:
+ # new AP finished initializing
+ self._add_ap_to_network(ap)
+ return
+
+ hash_value = ap.network_hash()
+ if old_hash_value == hash_value:
+ # no change in network identity, so just update signal strengths
+ self.wireless_networks[hash_value].update_strength()
+ return
+
+ # properties change includes a change of the identity of the network
+ # that it is on. so create this as a new network.
+ self.wireless_networks[old_hash_value].remove_ap(ap)
+ self._remove_net_if_empty(self.wireless_networks[old_hash_value],
+ old_hash_value)
+ self._add_ap_to_network(ap)
+
+ def add_access_point(self, device, ap_o):
+ ap = AccessPoint(device, ap_o)
+ ap.connect('props-changed', self._ap_props_changed_cb)
+ ap.initialize()
+
+ def remove_access_point(self, ap_o):
+ if self._adhoc_manager is not None:
+ if self._adhoc_manager.is_sugar_adhoc_access_point(ap_o):
+ self._adhoc_manager.remove_access_point(ap_o)
+ return
+
+ # we don't keep an index of ap object path to network, but since
+ # we'll only ever have a handful of networks, just try them all...
+ for net in self.wireless_networks.values():
+ ap = net.find_ap(ap_o)
+ if not ap:
+ continue
+
+ ap.disconnect()
+ net.remove_ap(ap)
+ self._remove_net_if_empty(net, ap.network_hash())
+ return
+
+ # it's not an error if the AP isn't found, since we might have ignored
+ # it (e.g. olpc-mesh adhoc network)
+ logging.debug('Can not remove access point %s', ap_o)
+
+ def add_adhoc_networks(self, device):
+ if self._adhoc_manager is None:
+ self._adhoc_manager = get_adhoc_manager_instance()
+ self._adhoc_manager.start_listening(device)
+ self._add_adhoc_network_icon(1)
+ self._add_adhoc_network_icon(6)
+ self._add_adhoc_network_icon(11)
+ self._adhoc_manager.autoconnect()
+
+ def remove_adhoc_networks(self):
+ for icon in self._adhoc_networks:
+ self._layout.remove(icon)
+ self._adhoc_networks = []
+ self._adhoc_manager.stop_listening()
+
+ def _add_adhoc_network_icon(self, channel):
+ icon = SugarAdhocView(channel)
+ self._layout.add(icon)
+ self._adhoc_networks.append(icon)
+
+ def _add_olpc_mesh_icon(self, mesh_mgr, channel):
+ icon = OlpcMeshView(mesh_mgr, channel)
+ self._layout.add(icon)
+ self._mesh.append(icon)
+
+ def enable_olpc_mesh(self, mesh_device):
+ mesh_mgr = OlpcMeshManager(mesh_device)
+ self._add_olpc_mesh_icon(mesh_mgr, 1)
+ self._add_olpc_mesh_icon(mesh_mgr, 6)
+ self._add_olpc_mesh_icon(mesh_mgr, 11)
+
+ # the OLPC mesh can be recognised as a "normal" wifi network. remove
+ # any such normal networks if they have been created
+ for hash_value, net in self.wireless_networks.iteritems():
+ if not net.is_olpc_mesh():
+ continue
+
+ logging.debug('removing OLPC mesh IBSS')
+ net.remove_all_aps()
+ net.disconnect()
+ self._layout.remove(net)
+ del self.wireless_networks[hash_value]
+
+ def disable_olpc_mesh(self, mesh_device):
+ for icon in self._mesh:
+ icon.disconnect()
+ self._layout.remove(icon)
+ self._mesh = []
+
+ def suspend(self):
+ if not self._suspended:
+ self._suspended = True
+ for net in self.wireless_networks.values() + self._mesh:
+ net.props.paused = True
+
+ def resume(self):
+ if self._suspended:
+ self._suspended = False
+ for net in self.wireless_networks.values() + self._mesh:
+ net.props.paused = False
+
+ def _toolbar_query_changed_cb(self, toolbar, query):
+ self._query = query.lower()
+ for icon in self._layout_box.get_children():
+ if hasattr(icon, 'set_filter'):
+ icon.set_filter(self._query)
+
+ def focus_search_entry(self):
+ self._toolbar.search_entry.grab_focus()