class NetworkManagerTreeView(Gtk.TreeView): __gtype_name__ = 'NetworkManagerTreeView' def __init__(self, state_changed=None): Gtk.TreeView.__init__(self) self.configure_icons() model = GtkNetworkStore() model.set_sort_column_id(0, Gtk.SortType.ASCENDING) # TODO eventually this will subclass GenericTreeModel. self.wifi_model = NetworkManager(model, GLibQueuedCaller, state_changed) self.nm_client = None self.nm_connection = None self.set_model(model) ssid_column = Gtk.TreeViewColumn('') cell_pixbuf = Gtk.CellRendererPixbuf() cell_text = Gtk.CellRendererText() ssid_column.pack_start(cell_pixbuf, False) ssid_column.pack_start(cell_text, True) ssid_column.set_cell_data_func(cell_text, self.data_func) ssid_column.set_cell_data_func(cell_pixbuf, self.pixbuf_func) self.connect('row-activated', self.row_activated) self.append_column(ssid_column) self.set_headers_visible(False) self.setup_row_expansion_handling(model) def setup_row_expansion_handling(self, model): """ If the user collapses a row, save that state. If all the APs go away and then return, such as when the user toggles the wifi kill switch, the UI should keep the row collapsed if it already was, or expand it. """ self.expand_all() self.rows_changed_id = None def queue_rows_changed(*args): if self.rows_changed_id: GLib.source_remove(self.rows_changed_id) self.rows_changed_id = GLib.idle_add(self.rows_changed) model.connect('row-inserted', queue_rows_changed) model.connect('row-deleted', queue_rows_changed) self.user_collapsed = {} def collapsed(self, iterator, path, collapse): udi = model[iterator][0] self.user_collapsed[udi] = collapse self.connect('row-collapsed', collapsed, True) self.connect('row-expanded', collapsed, False) def rows_changed(self, *args): model = self.get_model() i = model.get_iter_first() while i: udi = model[i][0] try: if not self.user_collapsed[udi]: path = model.get_path(i) self.expand_row(path, False) except KeyError: path = model.get_path(i) self.expand_row(path, False) i = model.iter_next(i) def row_activated(self, unused, path, column): self.connect_to_selection() def get_state(self): return self.wifi_model.get_state() def disconnect_from_ap(self): if self.nm_connection: if not self.nm_client: self.nm_client = NM.Client.new() self.nm_client.deactivate_connection(self.nm_connection) self.nm_connection = None else: self.wifi_model.disconnect_from_ap() def configure_icons(self): it = Gtk.IconTheme() default = Gtk.IconTheme.get_default() default = default.load_icon("image-missing", 22, 0) it.set_custom_theme('ubuntu-mono-light') self.icons = [] for n in ['nm-signal-00', 'nm-signal-25', 'nm-signal-50', 'nm-signal-75', 'nm-signal-100', 'nm-signal-00-secure', 'nm-signal-25-secure', 'nm-signal-50-secure', 'nm-signal-75-secure', 'nm-signal-100-secure']: ico = it.lookup_icon(n, 22, 0) if ico: ico = ico.load_icon() else: ico = default self.icons.append(ico) def pixbuf_func(self, column, cell, model, iterator, data): if not model.iter_parent(iterator): cell.set_property('pixbuf', None) return strength = model[iterator][2] if strength < 30: icon = 0 elif strength < 50: icon = 1 elif strength < 70: icon = 2 elif strength < 90: icon = 3 else: icon = 4 if model[iterator][1]: icon += 5 cell.set_property('pixbuf', self.icons[icon]) def data_func(self, column, cell, model, iterator, data): ssid = model[iterator][0] if not model.iter_parent(iterator): txt = '%s %s' % (model[iterator][1], model[iterator][2]) cell.set_property('text', txt) else: cell.set_property('text', ssid) def is_row_an_ap(self): model, iterator = self.get_selection().get_selected() if iterator is None: return False return model.iter_parent(iterator) is not None def is_row_connected(self): model, iterator = self.get_selection().get_selected() if iterator is None: return False ssid = model[iterator][0] parent = model.iter_parent(iterator) if parent and self.wifi_model.is_connected(model[parent][0], ssid): return True else: return False def find_ap(self, device, ssid): for ap in device.get_access_points(): ap_ssid = ap.get_ssid() if ap_ssid and decode_ssid(ap_ssid.get_data()) == ssid: return ap return None def connect_cb(self, client, result, user_data): self.nm_connection = client.add_and_activate_connection_finish(result) def connect_dialog_cb(self, dialog, response): if response == Gtk.ResponseType.OK: connection, device, ap = dialog.get_connection() if not self.nm_client: self.nm_client = NM.Client.new() self.nm_client.add_and_activate_connection_async( connection, device, None, None, self.connect_cb, None ) dialog.hide() def connect_to_selection(self): model, iterator = self.get_selection().get_selected() if iterator is None: return parent = model.iter_parent(iterator) if parent: try: devid = model[parent][0] ssid = model[iterator][0] if model[iterator][1]: if not self.nm_client: self.nm_client = NM.Client.new() device = self.nm_client.get_device_by_path(devid) ap = self.find_ap(device, ssid) connection = NM.SimpleConnection() connection.add_setting(NM.SettingConnection( uuid=NM.utils_uuid_generate() )) connection.add_setting(NM.SettingWireless( ssid=ap.get_property("ssid") )) dialog = NMA.WifiDialog.new( self.nm_client, connection, device, ap, False ) dialog.connect("response", self.connect_dialog_cb) dialog.run() else: self.wifi_model.connect_to_ap(devid, ssid) except Exception as e: dialog = Gtk.MessageDialog( None, Gtk.DialogFlags.MODAL, Gtk.MessageType.ERROR, Gtk.ButtonsType.CLOSE, "Failed to connect to wireless network" ) dialog.format_secondary_text("{}".format(e)) dialog.run() dialog.hide()
class NetworkManagerTreeView(Gtk.TreeView): __gtype_name__ = 'NetworkManagerTreeView' def __init__(self, password_entry=None, state_changed=None): Gtk.TreeView.__init__(self) self.password_entry = password_entry self.configure_icons() model = GtkNetworkStore() model.set_sort_column_id(0, Gtk.SortType.ASCENDING) # TODO eventually this will subclass GenericTreeModel. self.wifi_model = NetworkManager(model, GLibQueuedCaller, state_changed) self.set_model(model) ssid_column = Gtk.TreeViewColumn('') cell_pixbuf = Gtk.CellRendererPixbuf() cell_text = Gtk.CellRendererText() ssid_column.pack_start(cell_pixbuf, False) ssid_column.pack_start(cell_text, True) ssid_column.set_cell_data_func(cell_text, self.data_func) ssid_column.set_cell_data_func(cell_pixbuf, self.pixbuf_func) self.connect('row-activated', self.row_activated) self.append_column(ssid_column) self.set_headers_visible(False) self.setup_row_expansion_handling(model) def setup_row_expansion_handling(self, model): """ If the user collapses a row, save that state. If all the APs go away and then return, such as when the user toggles the wifi kill switch, the UI should keep the row collapsed if it already was, or expand it. """ self.expand_all() self.rows_changed_id = None def queue_rows_changed(*args): if self.rows_changed_id: GLib.source_remove(self.rows_changed_id) self.rows_changed_id = GLib.idle_add(self.rows_changed) model.connect('row-inserted', queue_rows_changed) model.connect('row-deleted', queue_rows_changed) self.user_collapsed = {} def collapsed(self, iterator, path, collapse): udi = model[iterator][0] self.user_collapsed[udi] = collapse self.connect('row-collapsed', collapsed, True) self.connect('row-expanded', collapsed, False) def rows_changed(self, *args): model = self.get_model() i = model.get_iter_first() while i: udi = model[i][0] try: if not self.user_collapsed[udi]: path = model.get_path(i) self.expand_row(path, False) except KeyError: path = model.get_path(i) self.expand_row(path, False) i = model.iter_next(i) def get_state(self): return self.wifi_model.get_state() def disconnect_from_ap(self): self.wifi_model.disconnect_from_ap() def row_activated(self, unused, path, column): passphrase = None if self.password_entry: passphrase = self.password_entry.get_text() self.connect_to_selection(passphrase) def configure_icons(self): it = Gtk.IconTheme() default = Gtk.IconTheme.get_default() default = default.load_icon(Gtk.STOCK_MISSING_IMAGE, 22, 0) it.set_custom_theme('ubuntu-mono-light') self.icons = [] for n in [ 'nm-signal-00', 'nm-signal-25', 'nm-signal-50', 'nm-signal-75', 'nm-signal-100', 'nm-signal-00-secure', 'nm-signal-25-secure', 'nm-signal-50-secure', 'nm-signal-75-secure', 'nm-signal-100-secure' ]: ico = it.lookup_icon(n, 22, 0) if ico: ico = ico.load_icon() else: ico = default self.icons.append(ico) def pixbuf_func(self, column, cell, model, iterator, data): if not model.iter_parent(iterator): cell.set_property('pixbuf', None) return strength = model[iterator][2] if strength < 30: icon = 0 elif strength < 50: icon = 1 elif strength < 70: icon = 2 elif strength < 90: icon = 3 else: icon = 4 if model[iterator][1]: icon += 5 cell.set_property('pixbuf', self.icons[icon]) def data_func(self, column, cell, model, iterator, data): ssid = model[iterator][0] if not model.iter_parent(iterator): txt = '%s %s' % (model[iterator][1], model[iterator][2]) cell.set_property('text', txt) else: cell.set_property('text', ssid) def get_passphrase(self, ssid): try: cached = self.wifi_model.passphrases_cache[ssid] except KeyError: return '' return cached def is_row_an_ap(self): model, iterator = self.get_selection().get_selected() if iterator is None: return False return model.iter_parent(iterator) is not None def is_row_connected(self): model, iterator = self.get_selection().get_selected() if iterator is None: return False ssid = model[iterator][0] parent = model.iter_parent(iterator) if parent and self.wifi_model.is_connected(model[parent][0], ssid): return True else: return False def connect_to_selection(self, passphrase): model, iterator = self.get_selection().get_selected() ssid = model[iterator][0] parent = model.iter_parent(iterator) if parent: self.wifi_model.connect_to_ap(model[parent][0], ssid, passphrase)
class NetworkManagerTreeView(Gtk.TreeView): __gtype_name__ = 'NetworkManagerTreeView' def __init__(self, password_entry=None, state_changed=None): Gtk.TreeView.__init__(self) self.password_entry = password_entry self.configure_icons() model = GtkNetworkStore() model.set_sort_column_id(0, Gtk.SortType.ASCENDING) # TODO eventually this will subclass GenericTreeModel. self.wifi_model = NetworkManager(model, GLibQueuedCaller, state_changed) self.set_model(model) ssid_column = Gtk.TreeViewColumn('') cell_pixbuf = Gtk.CellRendererPixbuf() cell_text = Gtk.CellRendererText() ssid_column.pack_start(cell_pixbuf, False) ssid_column.pack_start(cell_text, True) ssid_column.set_cell_data_func(cell_text, self.data_func) ssid_column.set_cell_data_func(cell_pixbuf, self.pixbuf_func) self.connect('row-activated', self.row_activated) self.append_column(ssid_column) self.set_headers_visible(False) self.setup_row_expansion_handling(model) def setup_row_expansion_handling(self, model): """ If the user collapses a row, save that state. If all the APs go away and then return, such as when the user toggles the wifi kill switch, the UI should keep the row collapsed if it already was, or expand it. """ self.expand_all() self.rows_changed_id = None def queue_rows_changed(*args): if self.rows_changed_id: GLib.source_remove(self.rows_changed_id) self.rows_changed_id = GLib.idle_add(self.rows_changed) model.connect('row-inserted', queue_rows_changed) model.connect('row-deleted', queue_rows_changed) self.user_collapsed = {} def collapsed(self, iterator, path, collapse): udi = model[iterator][0] self.user_collapsed[udi] = collapse self.connect('row-collapsed', collapsed, True) self.connect('row-expanded', collapsed, False) def rows_changed(self, *args): model = self.get_model() i = model.get_iter_first() while i: udi = model[i][0] try: if not self.user_collapsed[udi]: path = model.get_path(i) self.expand_row(path, False) except KeyError: path = model.get_path(i) self.expand_row(path, False) i = model.iter_next(i) def get_state(self): return self.wifi_model.get_state() def disconnect_from_ap(self): self.wifi_model.disconnect_from_ap() def row_activated(self, unused, path, column): passphrase = None if self.password_entry: passphrase = self.password_entry.get_text() self.connect_to_selection(passphrase) def configure_icons(self): it = Gtk.IconTheme() default = Gtk.IconTheme.get_default() default = default.load_icon(Gtk.STOCK_MISSING_IMAGE, 22, 0) it.set_custom_theme('ubuntu-mono-light') self.icons = [] for n in ['nm-signal-00', 'nm-signal-25', 'nm-signal-50', 'nm-signal-75', 'nm-signal-100', 'nm-signal-00-secure', 'nm-signal-25-secure', 'nm-signal-50-secure', 'nm-signal-75-secure', 'nm-signal-100-secure']: ico = it.lookup_icon(n, 22, 0) if ico: ico = ico.load_icon() else: ico = default self.icons.append(ico) def pixbuf_func(self, column, cell, model, iterator, data): if not model.iter_parent(iterator): cell.set_property('pixbuf', None) return strength = model[iterator][2] if strength < 30: icon = 0 elif strength < 50: icon = 1 elif strength < 70: icon = 2 elif strength < 90: icon = 3 else: icon = 4 if model[iterator][1]: icon += 5 cell.set_property('pixbuf', self.icons[icon]) def data_func(self, column, cell, model, iterator, data): ssid = model[iterator][0] if not model.iter_parent(iterator): txt = '%s %s' % (model[iterator][1], model[iterator][2]) cell.set_property('text', txt) else: cell.set_property('text', ssid) def get_passphrase(self, ssid): try: cached = self.wifi_model.passphrases_cache[ssid] except KeyError: return '' return cached def is_row_an_ap(self): model, iterator = self.get_selection().get_selected() if iterator is None: return False return model.iter_parent(iterator) is not None def is_row_connected(self): model, iterator = self.get_selection().get_selected() if iterator is None: return False ssid = model[iterator][0] parent = model.iter_parent(iterator) if parent and self.wifi_model.is_connected(model[parent][0], ssid): return True else: return False def connect_to_selection(self, passphrase): model, iterator = self.get_selection().get_selected() ssid = model[iterator][0] parent = model.iter_parent(iterator) if parent: self.wifi_model.connect_to_ap(model[parent][0], ssid, passphrase)