Beispiel #1
0
class GsmSettings(Gtk.Dialog):
    def __init__(self, bd_address):
        super(GsmSettings, self).__init__()

        self.set_name("GsmSettings")
        self.device = bd_address

        self.Builder = Gtk.Builder()
        self.Builder.set_translation_domain("blueman")
        bind_textdomain_codeset("blueman", "UTF-8")
        self.Builder.add_from_file(UI_PATH + "/gsm-settings.ui")

        gsm_grid = self.Builder.get_object("gsm_grid")

        self.config = Config("org.blueman.gsmsetting", "/org/blueman/gsmsettings/%s/" % bd_address)
        self.props.icon_name = "network-wireless"
        self.props.title = _("GSM Settings")

        self.props.resizable = False

        a = self.get_content_area()
        a.pack_start(gsm_grid, True, True, 0)
        gsm_grid.show()

        self.e_apn = self.Builder.get_object("e_apn")
        self.e_number = self.Builder.get_object("e_number")

        self.config.bind_to_widget("apn", self.e_apn, "text")
        self.config.bind_to_widget("number", self.e_number, "text")

        self.add_button("_Close", Gtk.ResponseType.CLOSE)
Beispiel #2
0
class Networking(AppletPlugin):
    __icon__ = "network"
    __description__ = _("Manages local network services, like NAP bridges")
    __author__ = "Walmis"

    _signal = None

    def on_load(self, applet):
        self.Applet = applet

        self.Config = Config("org.blueman.network")
        self.Config.connect("changed", self.on_config_changed)

        self.load_nap_settings()

    def on_manager_state_changed(self, state):
        if state:
            self.update_status()

    def load_nap_settings(self):
        dprint("Loading NAP settings")

        def reply():
            pass

        def err(excp):
            d = NetworkErrorDialog(excp, "You might not be able to connect to the Bluetooth network via this machine")
            d.expander.props.margin_left = 9

            d.run()
            d.destroy()

        m = Mechanism()
        m.ReloadNetwork(reply_handler=reply, error_handler=err)

    def on_unload(self):
        del self.Config

    def on_adapter_added(self, path):
        self.update_status()

    def update_status(self):
        self.set_nap(self.Config["nap-enable"])

    def on_config_changed(self, config, key):
        if key == "nap-enable":
            self.set_nap(config[key])

    def set_nap(self, on):
        dprint("set nap", on)
        if self.Applet.Manager != None:
            adapters = self.Applet.Manager.list_adapters()
            for adapter in adapters:
                s = NetworkServer(adapter.get_object_path())
                if on:
                    s.register("nap", "pan1")
                else:
                    s.unregister("nap")
class PersistentPluginManager(PluginManager):
    def __init__(self, *args):
        super(PersistentPluginManager, self).__init__(*args)

        self.__config = Config("org.blueman.general")

        self.__config.connect("changed::plugin-list", self.on_property_changed)

    def disable_plugin(self, plugin):
        plugins = self.__config["plugin-list"]
        return "!" + plugin in plugins

    def enable_plugin(self, plugin):
        plugins = self.__config["plugin-list"]
        return plugin in plugins

    def set_config(self, plugin, state):
        plugins = self.__config["plugin-list"]
        if plugin in plugins:
            plugins.remove(plugin)
        elif "!" + plugin in plugins:
            plugins.remove("!" + plugin)

        plugins.append(str("!" + plugin) if not state else str(plugin))
        self.__config["plugin-list"] = plugins

    @property
    def config_list(self):
        return self.__config["plugin-list"]

    def on_property_changed(self, config, key):
        for item in config[key]:
            disable = item.startswith("!")
            if disable:
                item = item.lstrip("!")

            try:
                cls = self.get_classes()[item]
                if not cls.__unloadable__ and disable:
                    logging.warning("warning: %s is not unloadable" % item)
                elif item in self.get_loaded() and disable:
                    self.unload_plugin(item)
                elif item not in self.get_loaded() and not disable:
                    try:
                        self.load_plugin(item, user_action=True)
                    except Exception as e:
                        logging.exception(e)
                        self.set_config(item, False)

            except KeyError:
                logging.warning("warning: Plugin %s not found" % item)
                continue
Beispiel #4
0
class PersistentPluginManager(PluginManager):
    def __init__(self, *args):
        super(PersistentPluginManager, self).__init__(*args)

        self.__config = Config("org.blueman.general")

        self.__config.connect("changed::plugin-list", self.on_property_changed)

    def Disabled(self, plugin):
        plugins = self.__config["plugin-list"]
        return "!" + plugin in plugins

    def Enabled(self, plugin):
        plugins = self.__config["plugin-list"]
        return plugin in plugins

    def SetConfig(self, plugin, state):
        plugins = self.__config["plugin-list"]
        if plugin in plugins:
            plugins.remove(plugin)
        elif "!" + plugin in plugins:
            plugins.remove("!" + plugin)

        plugins.append(str("!" + plugin) if not state else str(plugin))
        self.__config["plugin-list"] = plugins

    @property
    def config_list(self):
        return self.__config["plugin-list"]

    def on_property_changed(self, config, key):
        for item in config[key]:
            disable = item.startswith("!")
            if disable:
                item = item.lstrip("!")

            try:
                cls = self.GetClasses()[item]
                if not cls.__unloadable__ and disable:
                    print(YELLOW("warning:"), item, "is not unloadable")
                elif item in self.GetLoaded() and disable:
                    self.Unload(item)
                elif item not in self.GetLoaded() and not disable:
                    try:
                        self.Load(item, user_action=True)
                    except:
                        self.SetConfig(item, False)

            except KeyError:
                print(YELLOW("warning:"), "Plugin %s not found" % item)
                continue
Beispiel #5
0
    def setup_transfer(self):
        self.TransConf = Config("transfer")
        self.TransConf.connect("property-changed", self.on_property_changed)
        opp_enabled = self.Builder.get_object("opp_enabled")
        ftp_enabled = self.Builder.get_object("ftp_enabled")
        ftp_allow_write = self.Builder.get_object("ftp_allow_write")
        opp_accept = self.Builder.get_object("opp_accept")
        shared_path = self.Builder.get_object("shared_path")
        obex_cmd = self.Builder.get_object("e_obex_cmd")

        opp_enabled.props.active = self.TransConf.props.opp_enabled
        ftp_enabled.props.active = self.TransConf.props.ftp_enabled
        ftp_allow_write.props.active = self.TransConf.props.ftp_allow_write
        opp_accept.props.active = self.TransConf.props.opp_accept
        if self.TransConf.props.browse_command:
            obex_cmd.props.text = self.TransConf.props.browse_command

        if self.TransConf.props.shared_path is not None:
            shared_path.set_current_folder(self.TransConf.props.shared_path)

        obex_cmd.connect("changed", lambda x: setattr(self.TransConf.props, "browse_command", x.props.text))
        opp_enabled.connect("toggled", lambda x: setattr(self.TransConf.props, "opp_enabled", x.props.active))
        ftp_enabled.connect("toggled", lambda x: setattr(self.TransConf.props, "ftp_enabled", x.props.active))
        ftp_allow_write.connect("toggled", lambda x: setattr(self.TransConf.props, "ftp_allow_write", x.props.active))
        opp_accept.connect("toggled", lambda x: setattr(self.TransConf.props, "opp_accept", x.props.active))
        shared_path.connect("current-folder-changed",
                            lambda x: setattr(self.TransConf.props, "shared_path", x.get_filename()))
Beispiel #6
0
	def setup_transfer(self):
		a = AppletService()
		status = a.TransferStatus("opp")
		if status == -1:
			self.widget.props.sensitive = False
			self.widget.props.tooltip_text = _("obex-data-server not available")
		
		self.TransConf = Config("transfer")
		self.TransConf.connect("property-changed", self.on_property_changed)
		opp_enabled = self.Builder.get_object("opp_enabled")
		ftp_enabled = self.Builder.get_object("ftp_enabled")
		ftp_allow_write = self.Builder.get_object("ftp_allow_write")
		opp_accept = self.Builder.get_object("opp_accept")
		shared_path = self.Builder.get_object("shared_path")
		obex_cmd = self.Builder.get_object("e_obex_cmd")
	
		opp_enabled.props.active = self.TransConf.props.opp_enabled
		ftp_enabled.props.active = self.TransConf.props.ftp_enabled
		ftp_allow_write.props.active = self.TransConf.props.ftp_allow_write
		opp_accept.props.active = self.TransConf.props.opp_accept
		if self.TransConf.props.browse_command == None:
			self.TransConf.props.browse_command = DEF_BROWSE_COMMAND
		
		obex_cmd.props.text = self.TransConf.props.browse_command
		
		if self.TransConf.props.shared_path != None:
			shared_path.set_current_folder(self.TransConf.props.shared_path)
		
		obex_cmd.connect("changed", lambda x: setattr(self.TransConf.props, "browse_command", x.props.text))
		opp_enabled.connect("toggled", lambda x: setattr(self.TransConf.props, "opp_enabled", x.props.active))
		ftp_enabled.connect("toggled", lambda x: setattr(self.TransConf.props, "ftp_enabled", x.props.active))
		ftp_allow_write.connect("toggled", lambda x: setattr(self.TransConf.props, "ftp_allow_write", x.props.active))
		opp_accept.connect("toggled", lambda x: setattr(self.TransConf.props, "opp_accept", x.props.active))
		shared_path.connect("current-folder-changed", lambda x: setattr(self.TransConf.props, "shared_path", x.get_filename()))
Beispiel #7
0
    def on_load(self):
        self._registered = {}

        self.Config = Config("org.blueman.network")
        self.Config.connect("changed", self.on_config_changed)

        self.load_nap_settings()
Beispiel #8
0
    def __init__(self, bd_address):
        GObject.GObject.__init__(self)

        self.device = bd_address

        self.Builder = Gtk.Builder()
        self.Builder.set_translation_domain("blueman")
        self.Builder.add_from_file(UI_PATH + "/gsm-settings.ui")

        vbox = self.Builder.get_object("vbox1")

        self.config = Config("org.blueman.gsmsetting", "/org/blueman/gsmsettings/%s/" % bd_address)
        self.props.icon_name = "network-wireless"
        self.props.title = _("GSM Settings")

        self.props.resizable = False

        a = self.get_content_area()
        a.pack_start(vbox, True, True, 0)
        vbox.show()

        self.e_apn = self.Builder.get_object("e_apn")
        self.e_number = self.Builder.get_object("e_number")

        self.config.bind_to_widget("apn", self.e_apn, "text")
        self.config.bind_to_widget("number", self.e_number, "text")

        self.add_button("_Close", Gtk.ResponseType.CLOSE)
Beispiel #9
0
    def on_load(self, applet):
        self.Applet = applet

        self.Config = Config("org.blueman.network")
        self.Config.connect("changed", self.on_config_changed)

        self.load_nap_settings()
    def __init__(self, adapter=None, inst=None):
        cr = Gtk.CellRendererText()
        cr.props.ellipsize = Pango.EllipsizeMode.END
        tabledata = [
            # device picture
            {"id": "device_surface", "type": str, "renderer": Gtk.CellRendererPixbuf(),
             "render_attrs": {}, "celldata_func": (self._set_device_cell_data, None)},
            # device caption
            {"id": "caption", "type": str, "renderer": cr,
             "render_attrs": {"markup": 1}, "view_props": {"expand": True}},
            {"id": "rssi_pb", "type": GdkPixbuf.Pixbuf, "renderer": Gtk.CellRendererPixbuf(),
             "render_attrs": {"pixbuf": 2}, "view_props": {"spacing": 0}},
            {"id": "lq_pb", "type": GdkPixbuf.Pixbuf, "renderer": Gtk.CellRendererPixbuf(),
             "render_attrs": {"pixbuf": 3}, "view_props": {"spacing": 0}},
            {"id": "tpl_pb", "type": GdkPixbuf.Pixbuf, "renderer": Gtk.CellRendererPixbuf(),
             "render_attrs": {"pixbuf": 4}, "view_props": {"spacing": 0}},
            {"id": "alias", "type": str},  # used for quick access instead of device.GetProperties
            {"id": "connected", "type": bool},  # used for quick access instead of device.GetProperties
            {"id": "paired", "type": bool},  # used for quick access instead of device.GetProperties
            {"id": "trusted", "type": bool},  # used for quick access instead of device.GetProperties
            {"id": "objpush", "type": bool},  # used to set Send File button
            {"id": "rssi", "type": float},
            {"id": "lq", "type": float},
            {"id": "tpl", "type": float},
            {"id": "icon_info", "type": Gtk.IconInfo},
            {"id": "cell_fader", "type": GObject.TYPE_PYOBJECT},
            {"id": "row_fader", "type": GObject.TYPE_PYOBJECT},
            {"id": "levels_visible", "type": bool},
            {"id": "initial_anim", "type": bool},
        ]
        super(ManagerDeviceList, self).__init__(adapter, tabledata)
        self.set_name("ManagerDeviceList")
        self.set_headers_visible(False)
        self.props.has_tooltip = True
        self.Blueman = inst

        self.Config = Config("org.blueman.general")
        self.Config.connect('changed', self._on_settings_changed)
        # Set the correct sorting
        self._on_settings_changed(self.Config, "sort-by")
        self._on_settings_changed(self.Config, "sort-type")

        self.connect("query-tooltip", self.tooltip_query)
        self.tooltip_row = None
        self.tooltip_col = None

        self.connect("button_press_event", self.on_event_clicked)
        self.connect("button_release_event", self.on_event_clicked)

        self.menu = None

        self.connect("drag_data_received", self.drag_recv)
        self.connect("drag-motion", self.drag_motion)

        Gtk.Widget.drag_dest_set(self, Gtk.DestDefaults.ALL, [], Gdk.DragAction.COPY | Gdk.DragAction.DEFAULT)
        Gtk.Widget.drag_dest_add_uri_targets(self)

        self.set_search_equal_func(self.search_func, None)
Beispiel #11
0
    def __init__(self, *args):
        super(PersistentPluginManager, self).__init__(*args)

        self.__config = Config()

        if getattr(self.__config.props, self.plugin_class.__name__) == None:
            setattr(self.__config.props, self.plugin_class.__name__, [])

        self.__config.connect("property-changed", self.on_property_changed)
Beispiel #12
0
    def _setup_transfer(self):
        self._config = Config("org.blueman.transfer")
        self._config.connect("changed", self.on_property_changed)

        opp_accept = self.Builder.get_object("opp-accept")
        shared_path = self.Builder.get_object("shared-path")

        opp_accept.props.active = self._config["opp-accept"]
        if self._config["shared-path"]:
            shared_path.set_current_folder(self._config["shared-path"])

        opp_accept.connect("toggled", lambda x: self._config.set_boolean("opp-accept", x.props.active))

        shared_path.connect("file-set", lambda x: self._config.set_string("shared-path", x.get_filename()))
Beispiel #13
0
class PersistentPluginManager(PluginManager):
    def __init__(self, *args):
        super(PersistentPluginManager, self).__init__(*args)

        self.__config = Config()

        if getattr(self.__config.props, self.plugin_class.__name__) == None:
            setattr(self.__config.props, self.plugin_class.__name__, [])

        self.__config.connect("property-changed", self.on_property_changed)

    def Disabled(self, plugin):
        plugins = getattr(self.__config.props, self.plugin_class.__name__)
        return "!" + plugin in plugins

    def Enabled(self, plugin):
        plugins = getattr(self.__config.props, self.plugin_class.__name__)
        return plugin in plugins

    def SetConfig(self, plugin, state):
        plugins = self.__config.get(self.plugin_class.__name__)
        if plugin in plugins:
            plugins.remove(plugin)
        elif "!" + plugin in plugins:
            plugins.remove("!" + plugin)

        plugins.append(str("!" + plugin) if not state else str(plugin))
        self.__config.set(self.plugin_class.__name__, plugins)

    @property
    def config_list(self):
        return self.__config.get(self.plugin_class.__name__)

    def on_property_changed(self, config, key, value):
        if key == self.plugin_class.__name__:
            if type(value) == list:
                for item in value:
                    disable = item[0] == "!"
                    if disable:
                        item = item[1:]

                    try:
                        cls = self.GetClasses()[item]
                        if not cls.__unloadable__ and disable:
                            print(YELLOW("warning:"), item, "is not unloadable")
                        elif item in self.GetLoaded() and disable:
                            self.Unload(item)
                        elif item not in self.GetLoaded() and not disable:
                            try:
                                self.Load(item, user_action=True)
                            except:
                                self.SetConfig(item, False)

                    except KeyError:
                        print(YELLOW("warning:"), "Plugin %s not found" % item)
                        continue
Beispiel #14
0
class Transfer(ServicePlugin):
    __plugin_info__ = (_("Transfer"), "document-open")

    def on_load(self, container):

        self.Builder = Gtk.Builder()
        self.Builder.set_translation_domain("blueman")
        bind_textdomain_codeset("blueman", "UTF-8")
        self.Builder.add_from_file(UI_PATH + "/services-transfer.ui")
        self.widget = self.Builder.get_object("transfer")

        self.ignored_keys = []

        container.pack_start(self.widget, True, True, 0)
        a = AppletService()
        if "TransferService" in a.QueryPlugins():
            self._setup_transfer()
        else:
            self.widget.props.sensitive = False
            self.widget.props.tooltip_text = _("Applet's transfer service plugin is disabled")

        return True

    def on_enter(self):
        self.widget.props.visible = True

    def on_leave(self):
        self.widget.props.visible = False

    def on_property_changed(self, config, key):
        value = config[key]

        if key == "shared-path":
            self.Builder.get_object(key).set_current_folder(value)
            self.option_changed_notify(key, False)

    def on_apply(self):
        if self.on_query_apply_state():
            self.clear_options()
            logging.info("transfer apply")

    def on_query_apply_state(self):
        opts = self.get_options()
        if not opts:
            return False
        else:
            return True

    def _setup_transfer(self):
        self._config = Config("org.blueman.transfer")
        self._config.connect("changed", self.on_property_changed)

        opp_accept = self.Builder.get_object("opp-accept")
        shared_path = self.Builder.get_object("shared-path")

        opp_accept.props.active = self._config["opp-accept"]
        if self._config["shared-path"]:
            shared_path.set_current_folder(self._config["shared-path"])

        opp_accept.connect("toggled", lambda x: self._config.set_boolean("opp-accept", x.props.active))

        shared_path.connect("file-set", lambda x: self._config.set_string("shared-path", x.get_filename()))
class ManagerDeviceList(DeviceList):
    def __init__(self, adapter=None, inst=None):
        cr = Gtk.CellRendererText()
        cr.props.ellipsize = Pango.EllipsizeMode.END
        tabledata = [
            # device picture
            {"id": "device_surface", "type": str, "renderer": Gtk.CellRendererPixbuf(),
             "render_attrs": {}, "celldata_func": (self._set_device_cell_data, None)},
            # device caption
            {"id": "caption", "type": str, "renderer": cr,
             "render_attrs": {"markup": 1}, "view_props": {"expand": True}},
            {"id": "rssi_pb", "type": GdkPixbuf.Pixbuf, "renderer": Gtk.CellRendererPixbuf(),
             "render_attrs": {"pixbuf": 2}, "view_props": {"spacing": 0}},
            {"id": "lq_pb", "type": GdkPixbuf.Pixbuf, "renderer": Gtk.CellRendererPixbuf(),
             "render_attrs": {"pixbuf": 3}, "view_props": {"spacing": 0}},
            {"id": "tpl_pb", "type": GdkPixbuf.Pixbuf, "renderer": Gtk.CellRendererPixbuf(),
             "render_attrs": {"pixbuf": 4}, "view_props": {"spacing": 0}},
            {"id": "alias", "type": str},  # used for quick access instead of device.GetProperties
            {"id": "connected", "type": bool},  # used for quick access instead of device.GetProperties
            {"id": "paired", "type": bool},  # used for quick access instead of device.GetProperties
            {"id": "trusted", "type": bool},  # used for quick access instead of device.GetProperties
            {"id": "objpush", "type": bool},  # used to set Send File button
            {"id": "rssi", "type": float},
            {"id": "lq", "type": float},
            {"id": "tpl", "type": float},
            {"id": "icon_info", "type": Gtk.IconInfo},
            {"id": "cell_fader", "type": GObject.TYPE_PYOBJECT},
            {"id": "row_fader", "type": GObject.TYPE_PYOBJECT},
            {"id": "levels_visible", "type": bool},
            {"id": "initial_anim", "type": bool},
        ]
        super(ManagerDeviceList, self).__init__(adapter, tabledata)
        self.set_name("ManagerDeviceList")
        self.set_headers_visible(False)
        self.props.has_tooltip = True
        self.Blueman = inst

        self.Config = Config("org.blueman.general")
        self.Config.connect('changed', self._on_settings_changed)
        # Set the correct sorting
        self._on_settings_changed(self.Config, "sort-by")
        self._on_settings_changed(self.Config, "sort-type")

        self.connect("query-tooltip", self.tooltip_query)
        self.tooltip_row = None
        self.tooltip_col = None

        self.connect("button_press_event", self.on_event_clicked)
        self.connect("button_release_event", self.on_event_clicked)

        self.menu = None

        self.connect("drag_data_received", self.drag_recv)
        self.connect("drag-motion", self.drag_motion)

        Gtk.Widget.drag_dest_set(self, Gtk.DestDefaults.ALL, [], Gdk.DragAction.COPY | Gdk.DragAction.DEFAULT)
        Gtk.Widget.drag_dest_add_uri_targets(self)

        self.set_search_equal_func(self.search_func, None)

    def _on_settings_changed(self, settings, key):
        if key in ('sort-by', 'sort-order'):
            sort_by = settings['sort-by']
            sort_order = settings['sort-order']

            if sort_order == 'ascending':
                sort_type = Gtk.SortType.ASCENDING
            else:
                sort_type = Gtk.SortType.DESCENDING

            column_id = self.ids.setdefault(sort_by, None)

            if column_id:
                self.liststore.set_sort_column_id(column_id, sort_type)

    def on_icon_theme_changed(self, widget):
        for row in self.liststore:
            device = self.get(row.iter, "device")["device"]
            self.row_setup_event(row.iter, device)

    def do_device_found(self, device):
        tree_iter = self.find_device(device)
        if tree_iter:
            anim = TreeRowColorFade(self, self.props.model.get_path(tree_iter), Gdk.RGBA(0, 0, 1, 1))
            anim.animate(start=0.8, end=1.0)

    def search_func(self, model, column, key, tree_iter):
        row = self.get(tree_iter, "caption")
        if key.lower() in row["caption"].lower():
            return False
        logging.info("%s %s %s %s" % (model, column, key, tree_iter))
        return True

    def drag_recv(self, widget, context, x, y, selection, target_type, time):

        uris = list(selection.get_uris())

        context.finish(True, False, time)

        path = self.get_path_at_pos(x, y)
        if path:
            tree_iter = self.get_iter(path[0])
            device = self.get(tree_iter, "device")["device"]
            command = "blueman-sendto --device=%s" % device['Address']

            launch(command, uris, False, "blueman", _("File Sender"))
            context.finish(True, False, time)
        else:
            context.finish(False, False, time)

        return True

    def drag_motion(self, widget, drag_context, x, y, timestamp):
        result = self.get_path_at_pos(x, y)
        if result is not None:
            path = result[0]
            if not self.selection.path_is_selected(path):
                tree_iter = self.get_iter(path)
                has_obj_push = self._has_objpush(self.get(tree_iter, "device")["device"])
                if has_obj_push:
                    Gdk.drag_status(drag_context, Gdk.DragAction.COPY, timestamp)
                    self.set_cursor(path)
                    return True
                else:
                    Gdk.drag_status(drag_context, Gdk.DragAction.DEFAULT, timestamp)
                    return False
        else:
            Gdk.drag_status(drag_context, Gdk.DragAction.DEFAULT, timestamp)
            return False

    def on_event_clicked(self, widget, event):

        if event.type == Gdk.EventType.BUTTON_PRESS and event.button == 3:
            path = self.get_path_at_pos(int(event.x), int(event.y))
            if path is not None:
                row = self.get(path[0], "device")

                if row:
                    if self.Blueman is not None:
                        if self.menu is None:
                            self.menu = ManagerDeviceMenu(self.Blueman)

                        self.menu.popup(None, None, None, None, event.button, event.time)

    def get_icon_info(self, icon_name, size=48, fallback=True):
        if icon_name is None and not fallback:
            return None
        elif icon_name is None and fallback:
            icon_name = "image-missing"

        icon_info = self.icon_theme.lookup_icon_for_scale(icon_name, size, self.get_scale_factor(),
                                                          Gtk.IconLookupFlags.FORCE_SIZE)

        return icon_info

    def make_device_icon(self, icon_info, is_paired=False, is_trusted=False):
        window = self.get_window()
        scale = self.get_scale_factor()
        target = icon_info.load_surface(window)
        ctx = cairo.Context(target)

        if is_paired:
            icon_info = self.get_icon_info("dialog-password", 16, False)
            paired_surface = icon_info.load_surface(window)
            ctx.set_source_surface(paired_surface, 1 / scale, 1 / scale)
            ctx.paint_with_alpha(0.8)

        if is_trusted:
            icon_info = self.get_icon_info("blueman-trust", 16, False)
            trusted_surface = icon_info.load_surface(window)
            height = target.get_height()
            mini_height = trusted_surface.get_height()
            y = height / scale - mini_height / scale - 1 / scale

            ctx.set_source_surface(trusted_surface, 1 / scale, y)
            ctx.paint_with_alpha(0.8)

        return target

    def device_remove_event(self, device, tree_iter):
        row_fader = self.get(tree_iter, "row_fader")["row_fader"]

        def on_finished(fader):

            fader.disconnect(signal)
            fader.freeze()
            super(ManagerDeviceList, self).device_remove_event(device, tree_iter)

        signal = row_fader.connect("animation-finished", on_finished)
        row_fader.thaw()
        self.emit("device-selected", None, None)
        row_fader.animate(start=row_fader.get_state(), end=0.0, duration=400)

    def device_add_event(self, device):
        self.add_device(device)

    def make_caption(self, name, klass, address):
        return "<span size='x-large'>%(0)s</span>\n<span size='small'>%(1)s</span>\n<i>%(2)s</i>" \
               % {"0": html.escape(name), "1": klass.capitalize(), "2": address}

    def get_device_class(self, device):
        klass = get_minor_class(device['Class'])
        if klass != "uncategorized":
            return get_minor_class(device['Class'], True)
        else:
            return get_major_class(device['Class'])

    def row_setup_event(self, tree_iter, device):
        if not self.get(tree_iter, "initial_anim")["initial_anim"]:
            cell_fader = CellFade(self, self.props.model.get_path(tree_iter), [2, 3, 4])
            row_fader = TreeRowFade(self, self.props.model.get_path(tree_iter))

            has_objpush = self._has_objpush(device)

            self.set(tree_iter, row_fader=row_fader, cell_fader=cell_fader, levels_visible=False, objpush=has_objpush)

            cell_fader.freeze()

            def on_finished(fader):
                fader.disconnect(signal)
                fader.freeze()

            signal = row_fader.connect("animation-finished", on_finished)
            row_fader.set_state(0.0)
            row_fader.animate(start=0.0, end=1.0, duration=500)

            self.set(tree_iter, initial_anim=True)

        klass = get_minor_class(device['Class'])
        # Bluetooth >= 4 devices use Appearance property
        appearance = device["Appearance"]
        if klass != "uncategorized" and klass != "unknown":
            # get translated version
            description = get_minor_class(device['Class'], True).capitalize()
        elif klass == "unknown" and appearance:
            description = gatt_appearance_to_name(appearance)
        else:
            description = get_major_class(device['Class']).capitalize()

        icon_info = self.get_icon_info(device["Icon"], 48, False)
        caption = self.make_caption(device['Alias'], description, device['Address'])

        self.set(tree_iter, caption=caption, icon_info=icon_info, alias=device['Alias'])

        try:
            self.row_update_event(tree_iter, "Trusted", device['Trusted'])
        except Exception as e:
            logging.exception(e)
        try:
            self.row_update_event(tree_iter, "Paired", device['Paired'])
        except Exception as e:
            logging.exception(e)
        try:
            self.row_update_event(tree_iter, "Connected", device["Connected"])
        except Exception as e:
            logging.exception(e)

    def row_update_event(self, tree_iter, key, value):
        logging.info("%s %s" % (key, value))

        if key == "Trusted":
            if value:
                self.set(tree_iter, trusted=True)
            else:
                self.set(tree_iter, trusted=False)

        elif key == "Paired":
            if value:
                self.set(tree_iter, paired=True)
            else:
                self.set(tree_iter, paired=False)

        elif key == "Alias":
            device = self.get(tree_iter, "device")["device"]
            c = self.make_caption(value, self.get_device_class(device), device['Address'])
            self.set(tree_iter, caption=c, alias=value)

        elif key == "UUIDs":
            device = self.get(tree_iter, "device")["device"]
            has_objpush = self._has_objpush(device)
            self.set(tree_iter, objpush=has_objpush)

        elif key == "Connected":
            self.set(tree_iter, connected=value)

    def level_setup_event(self, row_ref, device, cinfo):
        if not row_ref.valid():
            return

        tree_iter = self.get_iter(row_ref.get_path())
        row = self.get(tree_iter, "levels_visible", "cell_fader", "rssi", "lq", "tpl")
        if cinfo is not None:
            # cinfo init may fail for bluetooth devices version 4 and up
            # FIXME Workaround is horrible and we should show something better
            if cinfo.failed:
                rssi_perc = tpl_perc = lq_perc = 100
            else:
                try:
                    rssi = float(cinfo.get_rssi())
                except ConnInfoReadError:
                    rssi = 0
                try:
                    lq = float(cinfo.get_lq())
                except ConnInfoReadError:
                    lq = 0

                try:
                    tpl = float(cinfo.get_tpl())
                except ConnInfoReadError:
                    tpl = 0

                rssi_perc = 50 + (rssi / 127 / 2 * 100)
                tpl_perc = 50 + (tpl / 127 / 2 * 100)
                lq_perc = lq / 255 * 100

                if lq_perc < 10:
                    lq_perc = 10
                if rssi_perc < 10:
                    rssi_perc = 10
                if tpl_perc < 10:
                    tpl_perc = 10

            if not row["levels_visible"]:
                logging.info("animating up")
                self.set(tree_iter, levels_visible=True)
                fader = row["cell_fader"]
                fader.thaw()
                fader.set_state(0.0)
                fader.animate(start=0.0, end=1.0, duration=400)

                def on_finished(fader):
                    fader.freeze()
                    fader.disconnect(signal)

                signal = fader.connect("animation-finished", on_finished)

            to_store = {}
            if round(row["rssi"], -1) != round(rssi_perc, -1):
                icon_name = "blueman-rssi-%d.png" % round(rssi_perc, -1)
                icon = GdkPixbuf.Pixbuf.new_from_file(os.path.join(PIXMAP_PATH, icon_name))
                to_store.update({"rssi": rssi_perc, "rssi_pb": icon})

            if round(row["lq"], -1) != round(lq_perc, -1):
                icon_name = "blueman-lq-%d.png" % round(lq_perc, -1)
                icon = GdkPixbuf.Pixbuf.new_from_file(os.path.join(PIXMAP_PATH, icon_name))
                to_store.update({"lq": lq_perc, "lq_pb": icon})

            if round(row["tpl"], -1) != round(tpl_perc, -1):
                icon_name = "blueman-tpl-%d.png" % round(tpl_perc, -1)
                icon = GdkPixbuf.Pixbuf.new_from_file(os.path.join(PIXMAP_PATH, icon_name))
                to_store.update({"tpl": tpl_perc, "tpl_pb": icon})

            if to_store:
                self.set(tree_iter, **to_store)

        else:

            if row["levels_visible"]:
                logging.info("animating down")
                self.set(tree_iter, levels_visible=False,
                         rssi=-1,
                         lq=-1,
                         tpl=-1)
                fader = row["cell_fader"]
                fader.thaw()
                fader.set_state(1.0)
                fader.animate(start=fader.get_state(), end=0.0, duration=400)

                def on_finished(fader):
                    fader.disconnect(signal)
                    fader.freeze()
                    if row_ref.valid():
                        self.set(tree_iter, rssi_pb=None, lq_pb=None, tpl_pb=None)

                signal = fader.connect("animation-finished", on_finished)

    def tooltip_query(self, tw, x, y, kb, tooltip):
        path = self.get_path_at_pos(x, y)

        if path is not None:
            if path[0] != self.tooltip_row or path[1] != self.tooltip_col:
                self.tooltip_row = path[0]
                self.tooltip_col = path[1]
                return False

            if path[1] == self.columns["device_surface"]:
                tree_iter = self.get_iter(path[0])

                row = self.get(tree_iter, "trusted", "paired")
                trusted = row["trusted"]
                paired = row["paired"]
                if trusted and paired:
                    tooltip.set_markup(_("<b>Trusted and Paired</b>"))
                elif paired:
                    tooltip.set_markup(_("<b>Paired</b>"))
                elif trusted:
                    tooltip.set_markup(_("<b>Trusted</b>"))
                else:
                    return False

                self.tooltip_row = path[0]
                self.tooltip_col = path[1]
                return True

            if path[1] == self.columns["tpl_pb"] \
                    or path[1] == self.columns["lq_pb"] \
                    or path[1] == self.columns["rssi_pb"]:
                tree_iter = self.get_iter(path[0])

                dt = self.get(tree_iter, "connected")["connected"]
                if dt:
                    rssi = self.get(tree_iter, "rssi")["rssi"]
                    lq = self.get(tree_iter, "lq")["lq"]
                    tpl = self.get(tree_iter, "tpl")["tpl"]

                    if rssi < 30:
                        rssi_state = _("Poor")
                    elif rssi < 40:
                        rssi_state = _("Sub-optimal")
                    elif rssi < 60:
                        rssi_state = _("Optimal")
                    elif rssi < 70:
                        rssi_state = _("Much")
                    else:
                        rssi_state = _("Too much")

                    if tpl < 30:
                        tpl_state = _("Low")
                    elif tpl < 40:
                        tpl_state = _("Sub-optimal")
                    elif tpl < 60:
                        tpl_state = _("Optimal")
                    elif tpl < 70:
                        tpl_state = _("High")
                    else:
                        tpl_state = _("Very High")

                    tooltip_template = None
                    if path[1] == self.columns["tpl_pb"]:
                        tooltip_template = \
                            "<b>Connected</b>\nReceived Signal Strength: %(rssi)u%% <i>(%(rssi_state)s)</i>\n" \
                            "Link Quality: %(lq)u%%\n<b>Transmit Power Level: %(tpl)u%%</b> <i>(%(tpl_state)s)</i>"
                    elif path[1] == self.columns["lq_pb"]:
                        tooltip_template = \
                            "<b>Connected</b>\nReceived Signal Strength: %(rssi)u%% <i>(%(rssi_state)s)</i>\n" \
                            "<b>Link Quality: %(lq)u%%</b>\nTransmit Power Level: %(tpl)u%% <i>(%(tpl_state)s)</i>"
                    elif path[1] == self.columns["rssi_pb"]:
                        tooltip_template = \
                            "<b>Connected</b>\n<b>Received Signal Strength: %(rssi)u%%</b> <i>(%(rssi_state)s)</i>\n" \
                            "Link Quality: %(lq)u%%\nTransmit Power Level: %(tpl)u%% <i>(%(tpl_state)s)</i>"

                    state_dict = {"rssi_state": rssi_state, "rssi": rssi, "lq": lq, "tpl": tpl, "tpl_state": tpl_state}
                    tooltip.set_markup(tooltip_template % state_dict)
                    self.tooltip_row = path[0]
                    self.tooltip_col = path[1]
                    return True
        return False

    def _has_objpush(self, device):
        if device is None:
            return False

        for uuid in device["UUIDs"]:
            if ServiceUUID(uuid).short_uuid == OBEX_OBJPUSH_SVCLASS_ID:
                return True
        return False

    def _set_device_cell_data(self, col, cell, model, tree_iter, data):
        row = self.get(tree_iter, "icon_info", "trusted", "paired")
        surface = self.make_device_icon(row["icon_info"], row["paired"], row["trusted"])
        cell.set_property("surface", surface)
Beispiel #16
0
class Transfer(ServicePlugin):
    __plugin_info__ = (_("Transfer"), "document-open")

    def on_load(self, container):

        self.Builder = Gtk.Builder()
        self.Builder.set_translation_domain("blueman")
        self.Builder.add_from_file(UI_PATH + "/services-transfer.ui")
        self.widget = self.Builder.get_object("transfer")

        self.ignored_keys = []

        container.pack_start(self.widget, True, True, 0)
        a = AppletService()
        if "TransferService" in a.QueryPlugins():
            self._setup_transfer()
        else:
            self.widget.props.sensitive = False
            self.widget.props.tooltip_text = _("Applet's transfer service plugin is disabled")

        return True

    def on_enter(self):
        self.widget.props.visible = True

    def on_leave(self):
        self.widget.props.visible = False

    def on_property_changed(self, config, key):
        value = config[key]

        if key == "shared-path":
            self.Builder.get_object(key).set_current_folder(value)
            self.option_changed_notify(key, False)

    def on_apply(self):
        if self.on_query_apply_state():
            self.clear_options()
            dprint("transfer apply")

    def on_query_apply_state(self):
        opts = self.get_options()
        if not opts:
            return False
        else:
            return True

    def _setup_transfer(self):
        self._config = Config("org.blueman.transfer")
        self._config.connect("changed", self.on_property_changed)

        opp_accept = self.Builder.get_object("opp-accept")
        shared_path = self.Builder.get_object("shared-path")

        opp_accept.props.active = self._config["opp-accept"]
        if self._config["shared-path"]:
            shared_path.set_current_folder(self._config["shared-path"])

        opp_accept.connect("toggled", lambda x: self._config.set_boolean("opp-accept", x.props.active))

        shared_path.connect("file-set", lambda x: self._config.set_string("shared-path", x.get_filename()))
Beispiel #17
0
class Network(ServicePlugin):
    __plugin_info__ = (_("Network"), "network-workgroup")

    def on_load(self, container):

        self.Builder = Gtk.Builder()
        self.Builder.set_translation_domain("blueman")
        bind_textdomain_codeset("blueman", "UTF-8")
        self.Builder.add_from_file(UI_PATH + "/services-network.ui")
        self.widget = self.Builder.get_object("network_frame")

        container.pack_start(self.widget, True, True, 0)

        self.interfaces = []
        for iface in get_net_interfaces():
            if iface != "lo" and iface != "pan1":
                print(iface)
                ip = inet_aton(get_net_address(iface))
                mask = inet_aton(get_net_netmask(iface))
                self.interfaces.append((iface, ip, mask, mask_ip4_address(ip, mask)))

        self.setup_network()
        try:
            self.ip_check()
        except:
            pass
        return (_("Network"), "network-workgroup")

    def on_enter(self):
        self.widget.props.visible = True

    def on_leave(self):
        self.widget.props.visible = False

    def on_apply(self):

        if self.on_query_apply_state():
            dprint("network apply")

            m = Mechanism()
            nap_enable = self.Builder.get_object("nap-enable")
            if nap_enable.props.active:

                if self.Builder.get_object("r_dhcpd").props.active:
                    stype = "DhcpdHandler"
                elif self.Builder.get_object("r_dnsmasq").props.active:
                    stype = "DnsMasqHandler"
                elif self.Builder.get_object("r_udhcpd").props.active:
                    stype = "UdhcpdHandler"

                net_ip = self.Builder.get_object("net_ip")

                try:
                    m.EnableNetwork('(ayays)', inet_aton(net_ip.props.text), inet_aton("255.255.255.0"), stype)

                    if not self.Config["nap-enable"]:
                        self.Config["nap-enable"] = True
                except Exception as e:
                    d = NetworkErrorDialog(e, parent=self.widget.get_toplevel())

                    d.run()
                    d.destroy()
                    return
            else:
                self.Config["nap-enable"] = False
                m.DisableNetwork()

            self.clear_options()

    def ip_check(self):
        e = self.Builder.get_object("net_ip")
        address = e.props.text
        try:
            if address.count(".") != 3:
                raise Exception
            a = inet_aton(address)
        except:
            e.props.secondary_icon_name = "dialog-error"
            e.props.secondary_icon_tooltip_text = _("Invalid IP address")
            raise

        a_netmask = inet_aton("255.255.255.0")

        a_masked = mask_ip4_address(a, a_netmask)

        for iface, ip, netmask, masked in self.interfaces:
            # print mask_ip4_address(a, netmask).encode("hex_codec"), masked.encode("hex_codec")

            if a == ip:
                e.props.secondary_icon_name = "dialog-error"
                e.props.secondary_icon_tooltip_text = _("IP address conflicts with interface %s which has the same address" % iface)
                raise Exception

            elif mask_ip4_address(a, netmask) == masked:
                e.props.secondary_icon_name = "dialog-warning"
                e.props.secondary_icon_tooltip_text = _("IP address overlaps with subnet of interface"
                                                        " %s, which has the following configuration %s/%s\nThis may cause incorrect network behavior" % (iface, inet_ntoa(ip), inet_ntoa(netmask)))
                return

        e.props.secondary_icon_name = None

    def on_query_apply_state(self):
        changed = False
        opts = self.get_options()
        if not opts:
            return False
        else:
            if "ip" in opts:
                try:
                    self.ip_check()
                except Exception as e:
                    print(e)
                    return -1

            return True

    def setup_network(self):
        self.Config = Config("org.blueman.network")

        nap_enable = self.Builder.get_object("nap-enable")
        r_dnsmasq = self.Builder.get_object("r_dnsmasq")
        r_dhcpd = self.Builder.get_object("r_dhcpd")
        r_udhcpd = self.Builder.get_object("r_udhcpd")
        net_ip = self.Builder.get_object("net_ip")
        rb_nm = self.Builder.get_object("rb_nm")
        rb_blueman = self.Builder.get_object("rb_blueman")
        rb_dun_nm = self.Builder.get_object("rb_dun_nm")
        rb_dun_blueman = self.Builder.get_object("rb_dun_blueman")

        nap_frame = self.Builder.get_object("nap_frame")
        warning = self.Builder.get_object("warning")

        rb_blueman.props.active = self.Config["dhcp-client"]

        if not self.Config["nap-enable"]:
            nap_frame.props.sensitive = False

        nc = NetConf.get_default()
        if nc.ip4_address is not None:
            net_ip.props.text = inet_ntoa(nc.ip4_address)
            nap_enable.props.active = True
        else:
            net_ip.props.text = "10.%d.%d.1" % (randint(0, 255), randint(0, 255))

        if nc.get_dhcp_handler() is None:
            nap_frame.props.sensitive = False
            nap_enable.props.active = False
            r_dnsmasq.props.active = True
            self.Config["nap-enable"] = False

        if nc.get_dhcp_handler() == DnsMasqHandler:
            r_dnsmasq.props.active = True
        elif nc.get_dhcp_handler() == DhcpdHandler:
            r_dhcpd.props.active = True
        elif nc.get_dhcp_handler() == UdhcpdHandler:
            r_udhcpd.props.active = True

        if not have("dnsmasq") and not have("dhcpd3") and not have("dhcpd") and not have("udhcpd"):
            nap_frame.props.sensitive = False
            warning.props.visible = True
            warning.props.sensitive = True
            nap_enable.props.sensitive = False
            self.Config["nap-enable"] = False

        if not have("dnsmasq"):
            r_dnsmasq.props.sensitive = False
            r_dnsmasq.props.active = False

        if not have("dhcpd3") and not have("dhcpd"):
            r_dhcpd.props.sensitive = False
            r_dhcpd.props.active = False

        if not have("udhcpd"):
            r_udhcpd.props.sensitive = False
            r_udhcpd.props.active = False

        r_dnsmasq.connect("toggled", lambda x: self.option_changed_notify("dnsmasq"))
        r_udhcpd.connect("toggled", lambda x: self.option_changed_notify("udhcpd"))

        net_ip.connect("changed", lambda x: self.option_changed_notify("ip", False))
        nap_enable.connect("toggled", lambda x: self.option_changed_notify("nap_enable"))

        self.Config.bind_to_widget("nap-enable", nap_enable, "active", Gio.SettingsBindFlags.GET)

        nap_enable.bind_property("active", nap_frame, "sensitive", 0)

        applet = AppletService()

        avail_plugins = applet.QueryAvailablePlugins()
        active_plugins = applet.QueryPlugins()

        def dun_support_toggled(rb, x):
            if rb.props.active and x == "nm":
                applet.SetPluginConfig('(sb)', "PPPSupport", False)
                applet.SetPluginConfig('(sb)', "NMDUNSupport", True)
            elif rb.props.active and x == "blueman":
                applet.SetPluginConfig('(sb)', "NMDUNSupport", False)
                applet.SetPluginConfig('(sb)', "PPPSupport", True)

        def pan_support_toggled(rb, x):
            if rb.props.active and x == "nm":
                applet.SetPluginConfig('(sb)', "DhcpClient", False)
                applet.SetPluginConfig('(sb)', "NMPANSupport", True)

            elif rb.props.active and x == "blueman":
                applet.SetPluginConfig('(sb)', "NMPANSupport", False)
                applet.SetPluginConfig('(sb)', "DhcpClient", True)

        if "PPPSupport" in active_plugins:
            rb_dun_blueman.props.active = True

        if "NMDUNSupport" in avail_plugins:
            rb_dun_nm.props.sensitive = True
        else:
            rb_dun_nm.props.sensitive = False
            rb_dun_nm.props.tooltip_text = _("Not currently supported with this setup")

        if "NMPANSupport" in avail_plugins:
            rb_nm.props.sensitive = True
        else:
            rb_nm.props.sensitive = False
            rb_nm.props.tooltip_text = _("Not currently supported with this setup")

        if "NMPANSupport" in active_plugins:
            rb_nm.props.active = True

        if "NMDUNSupport" in active_plugins:
            rb_dun_nm.props.active = True

        rb_nm.connect("toggled", pan_support_toggled, "nm")
        rb_blueman.connect("toggled", pan_support_toggled, "blueman")

        rb_dun_nm.connect("toggled", dun_support_toggled, "nm")
        rb_dun_blueman.connect("toggled", dun_support_toggled, "blueman")
Beispiel #18
0
	def __init__(self, parent):
		if not Dialog.running:
			Dialog.running = True
		else:
			return
		self.config = None	
		self.parent = parent
		builder = gtk.Builder()
		builder.add_from_file(UI_PATH + "/net-usage.ui")
		builder.set_translation_domain("blueman")
		
		self.dialog = builder.get_object("dialog")
		self.dialog.connect("response", self.on_response)
		cr1 = gtk.CellRendererText()
		cr1.props.ellipsize = pango.ELLIPSIZE_END
		
		self.devices = {}
		self.signals = SignalTracker()
		
		self.signals.Handle(parent, "monitor-added", self.monitor_added)
		self.signals.Handle(parent, "monitor-removed", self.monitor_removed)
		self.signals.Handle(parent, "stats", self.on_stats)
		
		cr2 = gtk.CellRendererText()
		cr2.props.sensitive = False
		cr2.props.style = pango.STYLE_ITALIC
		
		self.liststore = gtk.ListStore(str, str, str, object)
		
		self.e_ul = builder.get_object("e_ul")
		self.e_dl = builder.get_object("e_dl")
		self.e_total = builder.get_object("e_total")
		
		self.l_started = builder.get_object("l_started")
		self.l_duration = builder.get_object("l_duration")
		
		self.b_reset = builder.get_object("b_reset")
		self.b_reset.connect("clicked", self.on_reset)
		
		self.cb_device = builder.get_object("cb_device")
		self.cb_device.props.model = self.liststore
		self.cb_device.connect("changed", self.on_selection_changed)
		
		self.cb_device.pack_start(cr1, True)
		self.cb_device.add_attribute(cr1, 'markup', 1)		
		
		self.cb_device.pack_start(cr2, False)
		self.cb_device.add_attribute(cr2, 'markup', 2)			
		
		c = Config("plugins/NetUsage")
		devs = c.list_dirs()

		added = False
		for d in devs:
			d = os.path.basename(d)
			for m in parent.monitors:
				if d == m.device.Address:
					iter = self.liststore.append([d, self.get_caption(m.device.Alias, m.device.Address), _("Connected:") + " " + m.interface, m])
					if self.cb_device.get_active() == -1:
						self.cb_device.set_active_iter(iter)
					added = True
					break
			if not added:
				name = d
				if self.parent.Applet.Manager:
					for a in self.parent.Applet.Manager.ListAdapters():
						try:
							device = a.FindDevice(d)
							device = Device(device)
							name = self.get_caption(device.Alias, device.Address)
						except:
							pass

				self.liststore.append([d, name, _("Not Connected"), None])
			added = False
		if len(self.liststore) > 0:
			if self.cb_device.get_active() == -1:
				self.cb_device.set_active(0)
		else:
			d = gtk.MessageDialog(parent=self.dialog, flags=gtk.DIALOG_MODAL, type=gtk.MESSAGE_INFO, buttons=gtk.BUTTONS_CLOSE, message_format=_("No usage statistics are available yet. Try establishing a connection first and then check this page."))
			d.props.icon_name = "blueman"
			d.run()
			d.destroy()
			self.on_response(None, None)
			return
		
		self.dialog.show()
Beispiel #19
0
    def __init__(self, parent):
        if not Dialog.running:
            Dialog.running = True
        else:
            return
        self.config = None
        self.parent = parent
        builder = Gtk.Builder()
        builder.add_from_file(UI_PATH + "/net-usage.ui")
        builder.set_translation_domain("blueman")

        self.dialog = builder.get_object("dialog")
        self.dialog.connect("response", self.on_response)
        cr1 = Gtk.CellRendererText()
        cr1.props.ellipsize = Pango.EllipsizeMode.END

        self.devices = {}
        self.signals = SignalTracker()

        self.signals.Handle(parent, "monitor-added", self.monitor_added)
        self.signals.Handle(parent, "monitor-removed", self.monitor_removed)
        self.signals.Handle(parent, "stats", self.on_stats)

        cr2 = Gtk.CellRendererText()
        cr2.props.sensitive = False
        cr2.props.style = Pango.Style.ITALIC

        self.liststore = Gtk.ListStore(str, str, str, object)

        self.e_ul = builder.get_object("e_ul")
        self.e_dl = builder.get_object("e_dl")
        self.e_total = builder.get_object("e_total")

        self.l_started = builder.get_object("l_started")
        self.l_duration = builder.get_object("l_duration")

        self.b_reset = builder.get_object("b_reset")
        self.b_reset.connect("clicked", self.on_reset)

        self.cb_device = builder.get_object("cb_device")
        self.cb_device.props.model = self.liststore
        self.cb_device.connect("changed", self.on_selection_changed)

        self.cb_device.pack_start(cr1, True)
        self.cb_device.add_attribute(cr1, 'markup', 1)

        self.cb_device.pack_start(cr2, False)
        self.cb_device.add_attribute(cr2, 'markup', 2)

        c = Config("plugins/NetUsage")
        devs = c.list_dirs()

        added = False
        for d in devs:
            d = os.path.basename(d)
            for m in parent.monitors:
                if d == m.device.Address:
                    iter = self.liststore.append(
                        [d, self.get_caption(m.device.Alias, m.device.Address), _("Connected:") + " " + m.interface, m])
                    if self.cb_device.get_active() == -1:
                        self.cb_device.set_active_iter(iter)
                    added = True
                    break
            if not added:
                name = d
                if self.parent.Applet.Manager:
                    for a in self.parent.Applet.Manager.list_adapters():
                        try:
                            device = a.find_device(d)
                            device = Device(device)
                            name = self.get_caption(device.Alias, device.Address)
                        except:
                            pass

                self.liststore.append([d, name, _("Not Connected"), None])
            added = False
        if len(self.liststore) > 0:
            if self.cb_device.get_active() == -1:
                self.cb_device.set_active(0)
        else:
            d = Gtk.MessageDialog(parent=self.dialog, flags=Gtk.DialogFlags.MODAL, type=Gtk.MessageType.INFO,
                                  buttons=Gtk.ButtonsType.CLOSE, message_format=_(
                    "No usage statistics are available yet. Try establishing a connection first and then check this page."))
            d.props.icon_name = "blueman"
            d.run()
            d.destroy()
            self.on_response(None, None)
            return

        self.dialog.show()
Beispiel #20
0
class Blueman(Gtk.Window):
    def __init__(self):
        super(Blueman, self).__init__(title=_("Bluetooth Devices"))

        self._applet_sig = None

        self.Config = Config("org.blueman.general")

        self.Builder = Gtk.Builder()
        self.Builder.set_translation_domain("blueman")
        bind_textdomain_codeset("blueman", "UTF-8")
        self.Builder.add_from_file(UI_PATH + "/manager-main.ui")

        grid = self.Builder.get_object("grid")
        self.add(grid)
        self.set_name("BluemanManager")

        self.Plugins = PluginManager(ManagerPlugin, blueman.plugins.manager, self)
        self.Plugins.load_plugin()

        area = MessageArea()
        grid.attach(area, 0, 3, 1, 1)

        # Add margin for resize grip or it will overlap
        if self.get_has_resize_grip():
            statusbar = self.Builder.get_object("statusbar")
            margin_right = statusbar.get_margin_right()
            statusbar.set_margin_right(margin_right + 10)

        def do_present(time):
            if self.props.visible:
                self.present_with_time(time)

        check_single_instance("blueman-manager", do_present)

        def on_window_delete(window, event):
            w, h = self.get_size()
            x, y = self.get_position()
            self.Config["window-properties"] = [w, h, x, y]
            Gtk.main_quit()

        def bt_status_changed(status):
            if not status:
                self.hide()
                check_bluetooth_status(_("Bluetooth needs to be turned on for the device manager to function"),
                                       lambda: Gtk.main_quit())
            else:
                self.show()

        def on_applet_signal(_proxy, _sender, signal_name, params):
            if signal_name == 'BluetoothStatusChanged':
                status = params.unpack()
                bt_status_changed(status)

        def on_dbus_name_vanished(_connection, name):
            logging.info(name)
            if self._applet_sig is not None:
                self.Applet.disconnect(self._applet_sig)
                self._applet_sig = None

            self.hide()

            d = ErrorDialog(
                _("Connection to BlueZ failed"),
                _("Bluez daemon is not running, blueman-manager cannot continue.\n"
                  "This probably means that there were no Bluetooth adapters detected "
                  "or Bluetooth daemon was not started."),
                icon_name="blueman")
            d.run()
            d.destroy()

            # FIXME ui can handle BlueZ start/stop but we should inform user
            Gtk.main_quit()

        def on_dbus_name_appeared(_connection, name, owner):
            logging.info("%s %s" % (name, owner))
            setup_icon_path()

            try:
                self.Applet = AppletService()
            except DBusProxyFailed:
                print("Blueman applet needs to be running")
                exit()

            if 'PowerManager' in self.Applet.QueryPlugins():
                if not self.Applet.get_bluetooth_status():
                    bt_status_changed(False)

            self._applet_sig = self.Applet.connect('g-signal', on_applet_signal)

            self.connect("delete-event", on_window_delete)
            self.props.icon_name = "blueman"

            w, h, x, y = self.Config["window-properties"]
            if w and h:
                self.resize(w, h)
            if x and y:
                self.move(x, y)

            sw = self.Builder.get_object("scrollview")
            # Disable overlay scrolling
            if Gtk.get_minor_version() >= 16:
                sw.props.overlay_scrolling = False

            self.List = ManagerDeviceList(adapter=self.Config["last-adapter"], inst=self)

            self.List.show()
            sw.add(self.List)

            self.Toolbar = ManagerToolbar(self)
            self.Menu = ManagerMenu(self)
            self.Stats = ManagerStats(self)

            if self.List.is_valid_adapter():
                self.List.display_known_devices(autoselect=True)

            self.List.connect("adapter-changed", self.on_adapter_changed)

            toolbar = self.Builder.get_object("toolbar")
            statusbar = self.Builder.get_object("statusbar")

            self.Config.bind_to_widget("show-toolbar", toolbar, "visible")
            self.Config.bind_to_widget("show-statusbar", statusbar, "visible")

            self.show()

        bluez.Manager.watch_name_owner(on_dbus_name_appeared, on_dbus_name_vanished)

    def on_adapter_changed(self, lst, adapter):
        if adapter is not None:
            self.List.display_known_devices(autoselect=True)

    def inquiry(self):
        def prop_changed(lst, adapter, key_value):
            key, value = key_value
            if key == "Discovering" and not value:
                prog.finalize()
                self.List.disconnect(s1)
                self.List.disconnect(s2)

        def on_progress(lst, frac):
            if abs(1.0 - frac) <= 0.00001:
                if not prog.started():
                    prog.start()
            else:
                prog.fraction(frac)

        prog = ManagerProgressbar(self, text=_("Searching"))
        prog.connect("cancelled", lambda x: self.List.stop_discovery())
        try:
            self.List.discover_devices()
        except Exception as e:
            prog.finalize()
            MessageArea.show_message(*e_(e))

        s1 = self.List.connect("discovery-progress", on_progress)
        s2 = self.List.connect("adapter-property-changed", prop_changed)

    def setup(self, device):
        command = "blueman-assistant --device=%s" % device['Address']
        launch(command, None, False, "blueman", _("Bluetooth Assistant"))

    def bond(self, device):
        def error_handler(e):
            logging.exception(e)
            message = 'Pairing failed for:\n%s (%s)' % (device['Alias'], device['Address'])
            Notification('Bluetooth', message, icon_name="blueman").show()

        device.pair(error_handler=error_handler)

    def adapter_properties(self):
        launch("blueman-adapters", None, False, "blueman", _("Adapter Preferences"))

    def toggle_trust(self, device):
        device['Trusted'] = not device['Trusted']

    def send(self, device, f=None):
        adapter = self.List.Adapter

        command = "blueman-sendto --source=%s --device=%s" % (adapter["Address"], device['Address'])
        launch(command, None, False, "blueman", _("File Sender"))

    def remove(self, device):
        self.List.Adapter.remove_device(device)
Beispiel #21
0
    def __init__(self, blueman):
        self.blueman = blueman
        self.Config = Config("org.blueman.general")

        self.adapter_items: Dict[str, Tuple[Gtk.RadioMenuItem, Adapter]] = {}
        self._adapters_group: List[Gtk.RadioMenuItem] = []
        self._insert_adapter_item_pos = 2
        self.Search = None

        self.item_adapter = self.blueman.Builder.get_object("item_adapter")
        self.item_device = self.blueman.Builder.get_object("item_device")

        self.item_view = self.blueman.Builder.get_object("item_view")
        self.item_help = self.blueman.Builder.get_object("item_help")

        help_menu = Gtk.Menu()

        self.item_help.set_submenu(help_menu)
        help_menu.show()

        report_item = create_menuitem(_("_Report a Problem"), "dialog-warning")
        report_item.show()
        help_menu.append(report_item)
        report_item.connect("activate",
                            lambda x: launch("xdg-open %s/issues" % WEBSITE))

        sep = Gtk.SeparatorMenuItem()
        sep.show()
        help_menu.append(sep)

        help_item = create_menuitem("_Help", "help-about")
        help_item.show()
        help_menu.append(help_item)
        help_item.connect(
            "activate",
            lambda x: show_about_dialog('Blueman ' + _('Device Manager'),
                                        parent=self.blueman.get_toplevel()))

        view_menu = Gtk.Menu()
        self.item_view.set_submenu(view_menu)
        view_menu.show()

        item_toolbar = Gtk.CheckMenuItem.new_with_mnemonic(_("Show _Toolbar"))
        item_toolbar.show()
        view_menu.append(item_toolbar)
        self.blueman.Config.bind_to_widget("show-toolbar", item_toolbar,
                                           "active")

        item_statusbar = Gtk.CheckMenuItem.new_with_mnemonic(
            _("Show _Statusbar"))
        item_statusbar.show()
        view_menu.append(item_statusbar)
        self.blueman.Config.bind_to_widget("show-statusbar", item_statusbar,
                                           "active")

        item_services = Gtk.SeparatorMenuItem()
        view_menu.append(item_services)
        item_services.show()

        sorting_group: List[Gtk.RadioMenuItem] = []
        item_sort = Gtk.MenuItem.new_with_mnemonic(_("S_ort By"))
        view_menu.append(item_sort)
        item_sort.show()

        sorting_menu = Gtk.Menu()
        item_sort.set_submenu(sorting_menu)

        self._sort_alias_item = Gtk.RadioMenuItem.new_with_mnemonic(
            sorting_group, _("_Name"))
        self._sort_alias_item.show()
        sorting_group = self._sort_alias_item.get_group()
        sorting_menu.append(self._sort_alias_item)

        self._sort_timestamp_item = Gtk.RadioMenuItem.new_with_mnemonic(
            sorting_group, _("_Added"))
        self._sort_timestamp_item.show()
        sorting_menu.append(self._sort_timestamp_item)

        sort_config = self.Config['sort-by']
        if sort_config == "alias":
            self._sort_alias_item.props.active = True
        else:
            self._sort_timestamp_item.props.active = True

        sort_sep = Gtk.SeparatorMenuItem()
        sort_sep.show()
        sorting_menu.append(sort_sep)

        self._sort_type_item = Gtk.CheckMenuItem.new_with_mnemonic(
            _("_Descending"))
        self._sort_type_item.show()
        sorting_menu.append(self._sort_type_item)

        if self.Config['sort-order'] == "ascending":
            self._sort_type_item.props.active = False
        else:
            self._sort_type_item.props.active = True

        sep = Gtk.SeparatorMenuItem()
        sep.show()
        view_menu.append(sep)

        item_plugins = create_menuitem(_("_Plugins"), 'blueman-plugin')
        item_plugins.show()
        view_menu.append(item_plugins)
        item_plugins.connect('activate', self._on_plugin_dialog_activate)

        item_services = create_menuitem(
            _("_Local Services") + "...", "preferences-desktop")
        item_services.connect(
            'activate', lambda *args: launch("blueman-services",
                                             name=_("Service Preferences")))
        view_menu.append(item_services)
        item_services.show()

        adapter_menu = Gtk.Menu()
        self.item_adapter.set_submenu(adapter_menu)
        self.item_adapter.props.sensitive = False

        search_item = create_menuitem(_("_Search"), "edit-find")
        search_item.connect("activate", lambda x: self.blueman.inquiry())
        search_item.show()
        adapter_menu.prepend(search_item)
        self.Search = search_item

        sep = Gtk.SeparatorMenuItem()
        sep.show()
        adapter_menu.append(sep)

        sep = Gtk.SeparatorMenuItem()
        sep.show()
        adapter_menu.append(sep)

        adapter_settings = create_menuitem("_Preferences",
                                           "preferences-system")
        adapter_settings.connect("activate",
                                 lambda x: self.blueman.adapter_properties())
        adapter_settings.show()
        adapter_menu.append(adapter_settings)

        sep = Gtk.SeparatorMenuItem()
        sep.show()
        adapter_menu.append(sep)

        exit_item = create_menuitem("_Exit", "application-exit")
        exit_item.connect("activate", lambda x: Gtk.main_quit())
        exit_item.show()
        adapter_menu.append(exit_item)

        self.item_adapter.show()
        self.item_view.show()
        self.item_help.show()
        self.item_device.show()
        self.item_device.props.sensitive = False

        self._manager = Manager()
        self._manager.connect_signal("adapter-added", self.on_adapter_added)
        self._manager.connect_signal("adapter-removed",
                                     self.on_adapter_removed)

        blueman.List.connect("device-selected", self.on_device_selected)

        for adapter in self._manager.get_adapters():
            self.on_adapter_added(None, adapter.get_object_path())

        self.device_menu = None

        self.Config.connect("changed", self._on_settings_changed)
        self._sort_alias_item.connect("activate", self._on_sorting_changed,
                                      "alias")
        self._sort_timestamp_item.connect("activate", self._on_sorting_changed,
                                          "timestamp")
        self._sort_type_item.connect("activate", self._on_sorting_changed,
                                     "sort-type")
Beispiel #22
0
    def setup_network(self):
        self.NetConf = Config("network")
        self.NetConf.connect("property-changed", self.on_property_changed)

        gn_enable = self.Builder.get_object("gn_enable")
        # latest bluez does not support GN, apparently
        gn_enable.props.visible = False

        nap_enable = self.Builder.get_object("nap_enable")
        r_dnsmasq = self.Builder.get_object("r_dnsmasq")
        r_dhcpd = self.Builder.get_object("r_dhcpd")
        net_ip = self.Builder.get_object("net_ip")
        net_nat = self.Builder.get_object("net_nat")
        rb_nm = self.Builder.get_object("rb_nm")
        rb_blueman = self.Builder.get_object("rb_blueman")
        rb_dun_nm = self.Builder.get_object("rb_dun_nm")
        rb_dun_blueman = self.Builder.get_object("rb_dun_blueman")

        nap_frame = self.Builder.get_object("nap_frame")
        warning = self.Builder.get_object("warning")

        rb_blueman.props.active = self.NetConf.props.dhcp_client
        nap_enable.props.active = self.NetConf.props.nap_enable
        gn_enable.props.active = self.NetConf.props.gn_enable

        net_ip.props.text = "10.%d.%d.1" % (randint(0, 255), randint(0, 255))

        if not self.NetConf.props.nap_enable:
            nap_frame.props.sensitive = False

        nc = NetConf.get_default()
        if nc.ip4_address != None:
            net_ip.props.text = inet_ntoa(nc.ip4_address)
            #if not self.NetConf.props.nap_enable:
            #	self.ignored_keys.append("nap_enable")
            self.NetConf.props.nap_enable = True


        #if ns["masq"] != 0:
        #	net_nat.props.active = ns["masq"]

        if nc.get_dhcp_handler() == None:
            nap_frame.props.sensitive = False
            nap_enable.props.active = False
            if self.NetConf.props.nap_enable or self.NetConf.props.nap_enable == None:
                self.ignored_keys.append("nap_enable")
            self.NetConf.props.nap_enable = False


        else:
            if nc.get_dhcp_handler() == DnsMasqHandler:
                r_dnsmasq.props.active = True
            else:
                r_dhcpd.props.active = True

        if not have("dnsmasq") and not have("dhcpd3") and not have("dhcpd"):
            nap_frame.props.sensitive = False
            warning.props.visible = True
            warning.props.sensitive = True
            nap_enable.props.sensitive = False
            if self.NetConf.props.nap_enable or self.NetConf.props.nap_enable == None:
                self.ignored_keys.append("nap_enable")
            self.NetConf.props.nap_enable = False

        if not have("dnsmasq"):
            r_dnsmasq.props.sensitive = False
            r_dnsmasq.props.active = False
            r_dhcpd.props.active = True

        if not have("dhcpd3") and not have("dhcpd"):
            r_dhcpd.props.sensitive = False
            r_dhcpd.props.active = False
            r_dnsmasq.props.active = True

        r_dnsmasq.connect("toggled", lambda x: self.option_changed_notify("dnsmasq"))

        net_nat.connect("toggled", lambda x: self.on_property_changed(self.NetConf, "nat", x.props.active))
        net_ip.connect("changed", lambda x: self.on_property_changed(self.NetConf, "ip", x.props.text))
        gn_enable.connect("toggled", lambda x: setattr(self.NetConf.props, "gn_enable", x.props.active))
        nap_enable.connect("toggled", lambda x: self.on_property_changed(self.NetConf, "nap_enable", x.props.active))

        applet = AppletService()

        avail_plugins = applet.QueryAvailablePlugins()
        active_plugins = applet.QueryPlugins()

        def dun_support_toggled(rb, x):
            if rb.props.active and x == "nm":
                applet.SetPluginConfig("PPPSupport", False)
                applet.SetPluginConfig("NMDUNSupport", True)
            elif rb.props.active and x == "blueman":
                applet.SetPluginConfig("NMDUNSupport", False)
                applet.SetPluginConfig("PPPSupport", True)

        def pan_support_toggled(rb, x):
            if rb.props.active and x == "nm":
                applet.SetPluginConfig("DhcpClient", False)
                applet.SetPluginConfig("NMPANSupport", True)

            elif rb.props.active and x == "blueman":
                applet.SetPluginConfig("NMPANSupport", False)
                applet.SetPluginConfig("DhcpClient", True)


        if "PPPSupport" in active_plugins:
            rb_dun_blueman.props.active = True

        if "NMDUNSupport" in avail_plugins:
            rb_dun_nm.props.sensitive = True
        else:
            rb_dun_nm.props.sensitive = False
            rb_dun_nm.props.tooltip_text = _("Not currently supported with this setup")

        if "NMPANSupport" in avail_plugins:
            rb_nm.props.sensitive = True
        else:
            rb_nm.props.sensitive = False
            rb_nm.props.tooltip_text = _("Not currently supported with this setup")

        if "NMPANSupport" in active_plugins:
            rb_nm.props.active = True

        if "NMDUNSupport" in active_plugins:
            rb_dun_nm.props.active = True

        rb_nm.connect("toggled", pan_support_toggled, "nm")
        rb_blueman.connect("toggled", pan_support_toggled, "blueman")

        rb_dun_nm.connect("toggled", dun_support_toggled, "nm")
        rb_dun_blueman.connect("toggled", dun_support_toggled, "blueman")
Beispiel #23
0
class Network(ServicePlugin):
    __plugin_info__ = (_("Network"), "network-workgroup")

    def on_load(self, container):

        self.Builder = Gtk.Builder()
        self.Builder.set_translation_domain("blueman")
        self.Builder.add_from_file(UI_PATH + "/services-network.ui")
        self.widget = self.Builder.get_object("network")

        self.ignored_keys = []

        container.pack_start(self.widget, True, True, 0)

        self.interfaces = []
        for iface in get_net_interfaces():
            if iface != "lo" and iface != "pan1":
                print(iface)
                ip = inet_aton(get_net_address(iface))
                mask = inet_aton(get_net_netmask(iface))
                self.interfaces.append((iface, ip, mask, mask_ip4_address(ip, mask)))

        self.setup_network()
        try:
            self.ip_check()
        except:
            pass
        return (_("Network"), "network-workgroup")

    def on_enter(self):
        self.widget.props.visible = True

    def on_leave(self):
        self.widget.props.visible = False

    def on_property_changed(self, netconf, key, value):
        dprint(self.ignored_keys)
        if key in self.ignored_keys:
            self.ignored_keys.remove(key)
            return
        if key == "rb_blueman" or key == "dhcp_client":
            if value:
                self.Builder.get_object("rb_blueman").props.active = True
            else:
                self.Builder.get_object("rb_nm").props.active = True
            return
        if key == "rb_nm":
            return

        if key == "gn_enable":
            self.Builder.get_object(key).props.active = value
            return

        if key == "nap_enable":
            dprint("nap_enable", value)
            self.Builder.get_object(key).props.active = value
            nap_frame = self.Builder.get_object("nap_frame")
            if value:
                nap_frame.props.sensitive = True
            else:
                nap_frame.props.sensitive = False

        if key == "ip":
            self.option_changed_notify(key, False)
        else:
            self.option_changed_notify(key)

    def on_apply(self):

        if self.on_query_apply_state() == True:
            dprint("network apply")

            m = Mechanism()
            nap_enable = self.Builder.get_object("nap_enable")
            if nap_enable.props.active:

                r_dnsmasq = self.Builder.get_object("r_dnsmasq")
                if r_dnsmasq.props.active:
                    stype = "DnsMasqHandler"
                else:
                    stype = "DhcpdHandler"

                net_ip = self.Builder.get_object("net_ip")
                net_nat = self.Builder.get_object("net_nat")

                try:
                    m.EnableNetwork(inet_aton(net_ip.props.text), inet_aton("255.255.255.0"), stype)

                    if not self.NetConf.props.nap_enable:  # race condition workaround
                        self.ignored_keys.append("nap_enable")
                    self.NetConf.props.nap_enable = True
                except Exception as e:
                    lines = str(e).splitlines()

                    d = Gtk.MessageDialog(None, buttons=Gtk.ButtonsType.OK, type=Gtk.MessageType.ERROR)
                    d.props.icon_name = "dialog-error"
                    d.props.text = _("Failed to apply network settings")
                    d.props.secondary_text = lines[-1]
                    d.run()
                    d.destroy()
                    return
            else:
                if self.NetConf.props.nap_enable:  # race condition workaround
                    self.ignored_keys.append("nap_enable")
                self.NetConf.props.nap_enable = False
                m.DisableNetwork()

            self.clear_options()


    def ip_check(self):
        e = self.Builder.get_object("net_ip")
        address = e.props.text
        try:
            if address.count(".") != 3:
                raise Exception
            a = inet_aton(address)
        except:
            e.props.secondary_icon_name = "dialog-error"
            e.props.secondary_icon_tooltip_text = _("Invalid IP address")
            raise

        a_netmask = "\xff\xff\xff\0"

        a_masked = mask_ip4_address(a, a_netmask)

        for iface, ip, netmask, masked in self.interfaces:
            # print mask_ip4_address(a, netmask).encode("hex_codec"), masked.encode("hex_codec")

            if a == ip:
                e.props.secondary_icon_name = "dialog-error"
                e.props.secondary_icon_tooltip_text = _("IP address conflicts with interface %s which has the same address" % iface)
                raise Exception

            elif mask_ip4_address(a, netmask) == masked:
                e.props.secondary_icon_name = "dialog-warning"
                e.props.secondary_icon_tooltip_text = _("IP address overlaps with subnet of interface"
                                                        " %s, which has the following configuration %s/%s\nThis may cause incorrect network behavior" % (iface, inet_ntoa(ip), inet_ntoa(netmask)))
                return

        e.props.secondary_icon_name = None

    def on_query_apply_state(self):
        changed = False
        opts = self.get_options()
        if opts == []:
            return False
        else:
            if "ip" in opts:
                try:
                    self.ip_check()
                except Exception as e:
                    print(e)
                    return -1

            return True


    def setup_network(self):
        self.NetConf = Config("network")
        self.NetConf.connect("property-changed", self.on_property_changed)

        gn_enable = self.Builder.get_object("gn_enable")
        # latest bluez does not support GN, apparently
        gn_enable.props.visible = False

        nap_enable = self.Builder.get_object("nap_enable")
        r_dnsmasq = self.Builder.get_object("r_dnsmasq")
        r_dhcpd = self.Builder.get_object("r_dhcpd")
        net_ip = self.Builder.get_object("net_ip")
        net_nat = self.Builder.get_object("net_nat")
        rb_nm = self.Builder.get_object("rb_nm")
        rb_blueman = self.Builder.get_object("rb_blueman")
        rb_dun_nm = self.Builder.get_object("rb_dun_nm")
        rb_dun_blueman = self.Builder.get_object("rb_dun_blueman")

        nap_frame = self.Builder.get_object("nap_frame")
        warning = self.Builder.get_object("warning")

        rb_blueman.props.active = self.NetConf.props.dhcp_client
        nap_enable.props.active = self.NetConf.props.nap_enable
        gn_enable.props.active = self.NetConf.props.gn_enable

        net_ip.props.text = "10.%d.%d.1" % (randint(0, 255), randint(0, 255))

        if not self.NetConf.props.nap_enable:
            nap_frame.props.sensitive = False

        nc = NetConf.get_default()
        if nc.ip4_address != None:
            net_ip.props.text = inet_ntoa(nc.ip4_address)
            #if not self.NetConf.props.nap_enable:
            #	self.ignored_keys.append("nap_enable")
            self.NetConf.props.nap_enable = True


        #if ns["masq"] != 0:
        #	net_nat.props.active = ns["masq"]

        if nc.get_dhcp_handler() == None:
            nap_frame.props.sensitive = False
            nap_enable.props.active = False
            if self.NetConf.props.nap_enable or self.NetConf.props.nap_enable == None:
                self.ignored_keys.append("nap_enable")
            self.NetConf.props.nap_enable = False


        else:
            if nc.get_dhcp_handler() == DnsMasqHandler:
                r_dnsmasq.props.active = True
            else:
                r_dhcpd.props.active = True

        if not have("dnsmasq") and not have("dhcpd3") and not have("dhcpd"):
            nap_frame.props.sensitive = False
            warning.props.visible = True
            warning.props.sensitive = True
            nap_enable.props.sensitive = False
            if self.NetConf.props.nap_enable or self.NetConf.props.nap_enable == None:
                self.ignored_keys.append("nap_enable")
            self.NetConf.props.nap_enable = False

        if not have("dnsmasq"):
            r_dnsmasq.props.sensitive = False
            r_dnsmasq.props.active = False
            r_dhcpd.props.active = True

        if not have("dhcpd3") and not have("dhcpd"):
            r_dhcpd.props.sensitive = False
            r_dhcpd.props.active = False
            r_dnsmasq.props.active = True

        r_dnsmasq.connect("toggled", lambda x: self.option_changed_notify("dnsmasq"))

        net_nat.connect("toggled", lambda x: self.on_property_changed(self.NetConf, "nat", x.props.active))
        net_ip.connect("changed", lambda x: self.on_property_changed(self.NetConf, "ip", x.props.text))
        gn_enable.connect("toggled", lambda x: setattr(self.NetConf.props, "gn_enable", x.props.active))
        nap_enable.connect("toggled", lambda x: self.on_property_changed(self.NetConf, "nap_enable", x.props.active))

        applet = AppletService()

        avail_plugins = applet.QueryAvailablePlugins()
        active_plugins = applet.QueryPlugins()

        def dun_support_toggled(rb, x):
            if rb.props.active and x == "nm":
                applet.SetPluginConfig("PPPSupport", False)
                applet.SetPluginConfig("NMDUNSupport", True)
            elif rb.props.active and x == "blueman":
                applet.SetPluginConfig("NMDUNSupport", False)
                applet.SetPluginConfig("PPPSupport", True)

        def pan_support_toggled(rb, x):
            if rb.props.active and x == "nm":
                applet.SetPluginConfig("DhcpClient", False)
                applet.SetPluginConfig("NMPANSupport", True)

            elif rb.props.active and x == "blueman":
                applet.SetPluginConfig("NMPANSupport", False)
                applet.SetPluginConfig("DhcpClient", True)


        if "PPPSupport" in active_plugins:
            rb_dun_blueman.props.active = True

        if "NMDUNSupport" in avail_plugins:
            rb_dun_nm.props.sensitive = True
        else:
            rb_dun_nm.props.sensitive = False
            rb_dun_nm.props.tooltip_text = _("Not currently supported with this setup")

        if "NMPANSupport" in avail_plugins:
            rb_nm.props.sensitive = True
        else:
            rb_nm.props.sensitive = False
            rb_nm.props.tooltip_text = _("Not currently supported with this setup")

        if "NMPANSupport" in active_plugins:
            rb_nm.props.active = True

        if "NMDUNSupport" in active_plugins:
            rb_dun_nm.props.active = True

        rb_nm.connect("toggled", pan_support_toggled, "nm")
        rb_blueman.connect("toggled", pan_support_toggled, "blueman")

        rb_dun_nm.connect("toggled", dun_support_toggled, "nm")
        rb_dun_blueman.connect("toggled", dun_support_toggled, "blueman")
Beispiel #24
0
class Networking(AppletPlugin):
    __icon__ = "network-workgroup"
    __description__ = _("Manages local network services, like NAP bridges")
    __author__ = "Walmis"

    _signal = None

    def on_load(self) -> None:
        self._registered: Dict[str, bool] = {}

        self.Config = Config("org.blueman.network")
        self.Config.connect("changed", self.on_config_changed)

        self.load_nap_settings()

    def on_manager_state_changed(self, state: bool) -> None:
        if state:
            self.update_status()

    def load_nap_settings(self) -> None:
        logging.info("Loading NAP settings")

        def reply(_obj: Mechanism, _result: None, _user_data: None) -> None:
            pass

        def err(_obj: Mechanism, result: GLib.Error, _user_data: None) -> None:
            d = ErrorDialog(
                "<b>Failed to apply network settings</b>",
                "You might not be able to connect to the Bluetooth network via this machine",
                result,
                margin_left=9)

            d.run()
            d.destroy()

        m = Mechanism()
        m.ReloadNetwork(result_handler=reply, error_handler=err)

    def on_unload(self) -> None:
        for adapter_path in self._registered:
            s = NetworkServer(obj_path=adapter_path)
            s.unregister("nap")

        self._registered = {}
        del self.Config

    def on_adapter_added(self, path: str) -> None:
        self.update_status()

    def update_status(self) -> None:
        self.set_nap(self.Config["nap-enable"])

    def on_config_changed(self, config: Config, key: str) -> None:
        if key == "nap-enable":
            self.set_nap(config[key])

    def set_nap(self, on: bool) -> None:
        logging.info("set nap %s" % on)
        if self.parent.manager_state:
            adapters = self.parent.Manager.get_adapters()
            for adapter in adapters:
                object_path = adapter.get_object_path()

                registered = self._registered.setdefault(object_path, False)

                s = NetworkServer(obj_path=object_path)
                if on and not registered:
                    s.register("nap", "pan1")
                    self._registered[object_path] = True
                elif not on and registered:
                    s.unregister("nap")
                    self._registered[object_path] = False
Beispiel #25
0
 def on_selection_changed(self, cb):
     titer = cb.get_active_iter()
     (addr,) = self.liststore.get(titer, 0)
     self.config = Config("org.blueman.plugins.netusage", "/org/blueman/plugins/netusages/%s/" % addr)
     self.update_counts(self.config["tx"], self.config["rx"])
     self.update_time()
Beispiel #26
0
    def __init__(self, plugin):
        if not Dialog.running:
            Dialog.running = True
        else:
            return
        self.config = None
        self.plugin = plugin
        builder = Gtk.Builder()
        builder.add_from_file(UI_PATH + "/net-usage.ui")
        builder.set_translation_domain("blueman")
        bind_textdomain_codeset("blueman", "UTF-8")

        self.dialog = builder.get_object("dialog")
        self.dialog.connect("response", self.on_response)
        cr1 = Gtk.CellRendererText()
        cr1.props.ellipsize = Pango.EllipsizeMode.END

        self._signals = [
            plugin.connect("monitor-added", self.monitor_added),
            plugin.connect("monitor-removed", self.monitor_removed),
            plugin.connect("stats", self.on_stats)
        ]

        cr2 = Gtk.CellRendererText()
        cr2.props.sensitive = False
        cr2.props.style = Pango.Style.ITALIC

        self.liststore = Gtk.ListStore(str, str, str, object)

        self.e_ul = builder.get_object("e_ul")
        self.e_dl = builder.get_object("e_dl")
        self.e_total = builder.get_object("e_total")

        self.l_started = builder.get_object("l_started")
        self.l_duration = builder.get_object("l_duration")

        self.b_reset = builder.get_object("b_reset")
        self.b_reset.connect("clicked", self.on_reset)

        self.cb_device = builder.get_object("cb_device")
        self.cb_device.props.model = self.liststore
        self.cb_device.connect("changed", self.on_selection_changed)

        self.cb_device.pack_start(cr1, True)
        self.cb_device.add_attribute(cr1, 'markup', 1)

        self.cb_device.pack_start(cr2, False)
        self.cb_device.add_attribute(cr2, 'markup', 2)

        general_config = Config("org.blueman.general")

        added = False
        for d in general_config["netusage-dev-list"]:
            for m in plugin.monitors:
                if d == m.device["Address"]:
                    titer = self.liststore.append([
                        d,
                        self.get_caption(m.device["Alias"],
                                         m.device["Address"]),
                        _("Connected:") + " " + m.interface, m
                    ])
                    if self.cb_device.get_active() == -1:
                        self.cb_device.set_active_iter(titer)
                    added = True
                    break
            if not added:
                name = d
                if self.plugin.parent.Manager:
                    device = self.plugin.parent.Manager.find_device(d)
                    if device is None:
                        pass
                    else:
                        name = self.get_caption(device["Alias"],
                                                device["Address"])

                self.liststore.append([d, name, _("Not Connected"), None])
            added = False
        if len(self.liststore) > 0:
            if self.cb_device.get_active() == -1:
                self.cb_device.set_active(0)
        else:
            msg = _(
                "No usage statistics are available yet. Try establishing a connection first and "
                "then check this page.")
            d = Gtk.MessageDialog(parent=self.dialog,
                                  flags=Gtk.DialogFlags.MODAL,
                                  type=Gtk.MessageType.INFO,
                                  buttons=Gtk.ButtonsType.CLOSE,
                                  message_format=msg)
            d.props.icon_name = "blueman"
            d.run()
            d.destroy()
            self.on_response(None, None)
            return

        self.dialog.show()
Beispiel #27
0
 def on_selection_changed(self, cb):
     iter = cb.get_active_iter()
     (addr,) = self.liststore.get(iter, 0)
     self.config = Config("plugins/NetUsage/" + addr)
     self.update_counts(self.config.props.tx, self.config.props.rx)
     self.update_time()
Beispiel #28
0
class Transfer(ServicePlugin):
    __plugin_info__ = (_("Transfer"), "gtk-open")

    def on_load(self, container):

        self.Builder = gtk.Builder()
        self.Builder.set_translation_domain("blueman")
        self.Builder.add_from_file(UI_PATH + "/services-transfer.ui")
        self.widget = self.Builder.get_object("transfer")

        self.ignored_keys = []

        container.pack_start(self.widget)
        a = AppletService()
        if "TransferService" in a.QueryPlugins():
            self.setup_transfer()
        else:
            self.widget.props.sensitive = False
            self.widget.props.tooltip_text = _("Applet's transfer service plugin is disabled")

        return True

    def on_enter(self):
        self.widget.props.visible = True

    def on_leave(self):
        self.widget.props.visible = False

    def on_property_changed(self, config, key, value):

        if key == "opp_enabled":
            self.Builder.get_object(key).props.active = value
        if key == "ftp_enabled":
            self.Builder.get_object(key).props.active = value
        if key == "ftp_allow_write":
            self.Builder.get_object(key).props.active = value
        if key == "shared_path":
            self.Builder.get_object(key).set_current_folder(value)
        if key == "browse_command":
            return
        if key == "shared_path":
            self.option_changed_notify(key, False)
        else:
            self.option_changed_notify(key)

    def on_apply(self):
        if self.on_query_apply_state() == True:

            try:
                a = AppletService()
            except:
                dprint("failed to connect to applet")
            else:
                c = self.get_options()
                if "opp_enabled" in c:
                    if not self.TransConf.props.opp_enabled:
                        a.TransferControl("opp", "destroy")

                if "ftp_enabled" in c:
                    if not self.TransConf.props.ftp_enabled:
                        a.TransferControl("ftp", "destroy")

                if "opp_accept" in c or "shared_path" in c or "opp_enabled" in c:
                    if self.TransConf.props.opp_enabled:
                        state = a.TransferStatus("opp")
                        if state == 0:  # destroyed
                            a.TransferControl("opp", "create")
                        elif state == 2:  # running
                            a.TransferControl("opp", "stop")
                            a.TransferControl("opp", "start")
                        elif state == 1:
                            a.TransferControl("opp", "start")

                if "ftp_allow_write" in c or "shared_path" in c or "ftp_enabled" in c:
                    if self.TransConf.props.ftp_enabled:
                        state = a.TransferStatus("ftp")
                        if state == 0:  # destroyed
                            a.TransferControl("ftp", "create")
                        elif state == 2:  # running
                            a.TransferControl("ftp", "stop")
                            a.TransferControl("ftp", "start")
                        elif state == 1:
                            a.TransferControl("ftp", "start")

                self.clear_options()

            dprint("transfer apply")

    def on_query_apply_state(self):
        opts = self.get_options()
        if opts == []:
            return False
        else:
            return True

    def setup_transfer(self):
        a = AppletService()
        status = a.TransferStatus("opp")
        if status == -1:
            self.widget.props.sensitive = False
            self.widget.props.tooltip_text = _("obex-data-server not available")

        self.TransConf = Config("transfer")
        self.TransConf.connect("property-changed", self.on_property_changed)
        opp_enabled = self.Builder.get_object("opp_enabled")
        ftp_enabled = self.Builder.get_object("ftp_enabled")
        ftp_allow_write = self.Builder.get_object("ftp_allow_write")
        opp_accept = self.Builder.get_object("opp_accept")
        shared_path = self.Builder.get_object("shared_path")
        obex_cmd = self.Builder.get_object("e_obex_cmd")

        opp_enabled.props.active = self.TransConf.props.opp_enabled
        ftp_enabled.props.active = self.TransConf.props.ftp_enabled
        ftp_allow_write.props.active = self.TransConf.props.ftp_allow_write
        opp_accept.props.active = self.TransConf.props.opp_accept
        if self.TransConf.props.browse_command == None:
            self.TransConf.props.browse_command = DEF_BROWSE_COMMAND

        obex_cmd.props.text = self.TransConf.props.browse_command

        if self.TransConf.props.shared_path != None:
            shared_path.set_current_folder(self.TransConf.props.shared_path)

        obex_cmd.connect("changed", lambda x: setattr(self.TransConf.props, "browse_command", x.props.text))
        opp_enabled.connect("toggled", lambda x: setattr(self.TransConf.props, "opp_enabled", x.props.active))
        ftp_enabled.connect("toggled", lambda x: setattr(self.TransConf.props, "ftp_enabled", x.props.active))
        ftp_allow_write.connect("toggled", lambda x: setattr(self.TransConf.props, "ftp_allow_write", x.props.active))
        opp_accept.connect("toggled", lambda x: setattr(self.TransConf.props, "opp_accept", x.props.active))
        shared_path.connect(
            "current-folder-changed", lambda x: setattr(self.TransConf.props, "shared_path", x.get_filename())
        )
Beispiel #29
0
class ManagerMenu:
    def __init__(self, blueman):
        self.blueman = blueman
        self.Config = Config("org.blueman.general")

        self.adapter_items = {}
        self._adapters_group = []
        self._insert_adapter_item_pos = 2
        self.Search = None

        self.item_adapter = self.blueman.Builder.get_object("item_adapter")
        self.item_device = self.blueman.Builder.get_object("item_device")

        self.item_view = self.blueman.Builder.get_object("item_view")
        self.item_help = self.blueman.Builder.get_object("item_help")

        help_menu = Gtk.Menu()

        self.item_help.set_submenu(help_menu)
        help_menu.show()

        report_item = create_menuitem(_("_Report a Problem"), get_icon("dialog-warning", 16))
        report_item.show()
        help_menu.append(report_item)
        report_item.connect("activate", lambda x: launch("xdg-open %s/issues" % WEBSITE, None, True))

        sep = Gtk.SeparatorMenuItem()
        sep.show()
        help_menu.append(sep)

        help_item = create_menuitem("_Help", get_icon("help-about"))
        help_item.show()
        help_menu.append(help_item)
        help_item.connect("activate", lambda x: show_about_dialog('Blueman ' + _('Device Manager')))

        view_menu = Gtk.Menu()
        self.item_view.set_submenu(view_menu)
        view_menu.show()

        item_toolbar = Gtk.CheckMenuItem.new_with_mnemonic(_("Show _Toolbar"))
        item_toolbar.show()
        view_menu.append(item_toolbar)
        self.blueman.Config.bind_to_widget("show-toolbar", item_toolbar, "active")

        item_statusbar = Gtk.CheckMenuItem.new_with_mnemonic(_("Show _Statusbar"))
        item_statusbar.show()
        view_menu.append(item_statusbar)
        self.blueman.Config.bind_to_widget("show-statusbar", item_statusbar, "active")

        item_services = Gtk.SeparatorMenuItem()
        view_menu.append(item_services)
        item_services.show()

        sorting_group = []
        item_sort = Gtk.MenuItem.new_with_mnemonic(_("S_ort By"))
        view_menu.append(item_sort)
        item_sort.show()

        sorting_menu = Gtk.Menu()
        item_sort.set_submenu(sorting_menu)

        self._sort_alias_item = Gtk.RadioMenuItem.new_with_mnemonic(sorting_group, _("_Name"))
        self._sort_alias_item.show()
        sorting_group = self._sort_alias_item.get_group()
        sorting_menu.append(self._sort_alias_item)

        self._sort_timestamp_item = Gtk.RadioMenuItem.new_with_mnemonic(sorting_group, _("_Added"))
        self._sort_timestamp_item.show()
        sorting_group = self._sort_timestamp_item.get_group()
        sorting_menu.append(self._sort_timestamp_item)

        sort_config = self.Config['sort-by']
        if sort_config == "alias":
            self._sort_alias_item.props.active = True
        else:
            self._sort_timestamp_item.props.active = True

        sort_sep = Gtk.SeparatorMenuItem()
        sort_sep.show()
        sorting_menu.append(sort_sep)

        self._sort_type_item = Gtk.CheckMenuItem.new_with_mnemonic(_("_Descending"))
        self._sort_type_item.show()
        sorting_menu.append(self._sort_type_item)

        if self.Config['sort-order'] == "ascending":
            self._sort_type_item.props.active = False
        else:
            self._sort_type_item.props.active = True

        sep = Gtk.SeparatorMenuItem()
        sep.show()
        view_menu.append(sep)

        item_plugins = create_menuitem(_("Plugins"), get_icon('blueman-plugin', 16))
        item_plugins.show()
        view_menu.append(item_plugins)
        item_plugins.connect('activate', lambda *args: self.blueman.Applet.open_plugin_dialog(ignore_reply=True))

        item_services = create_menuitem(_("_Local Services") + "...", get_icon("preferences-desktop", 16))
        item_services.connect('activate',
                              lambda *args: launch("blueman-services", None, False, "blueman", _("Service Preferences")))
        view_menu.append(item_services)
        item_services.show()

        adapter_menu = Gtk.Menu()
        self.item_adapter.set_submenu(adapter_menu)
        self.item_adapter.props.sensitive = False

        search_item = create_menuitem(_("_Search"), get_icon("edit-find", 16))
        search_item.connect("activate", lambda x: self.blueman.inquiry())
        search_item.show()
        adapter_menu.prepend(search_item)
        self.Search = search_item

        sep = Gtk.SeparatorMenuItem()
        sep.show()
        adapter_menu.append(sep)

        sep = Gtk.SeparatorMenuItem()
        sep.show()
        adapter_menu.append(sep)

        adapter_settings = create_menuitem("_Preferences", get_icon("preferences-system", 16))
        adapter_settings.connect("activate", lambda x: self.blueman.adapter_properties())
        adapter_settings.show()
        adapter_menu.append(adapter_settings)

        sep = Gtk.SeparatorMenuItem()
        sep.show()
        adapter_menu.append(sep)

        exit_item = create_menuitem("_Exit", get_icon("application-exit", 16))
        exit_item.connect("activate", lambda x: Gtk.main_quit())
        exit_item.show()
        adapter_menu.append(exit_item)

        self.item_adapter.show()
        self.item_view.show()
        self.item_help.show()
        self.item_device.show()
        self.item_device.props.sensitive = False

        self._manager = bluez.Manager()
        self._manager.connect_signal("adapter-added", self.on_adapter_added)
        self._manager.connect_signal("adapter-removed", self.on_adapter_removed)

        blueman.List.connect("device-selected", self.on_device_selected)

        for adapter in self._manager.list_adapters():
            self.on_adapter_added(None, adapter.get_object_path())

        self.device_menu = None

        self.Config.connect("changed", self._on_settings_changed)
        self._sort_alias_item.connect("activate", self._on_sorting_changed, "alias")
        self._sort_timestamp_item.connect("activate", self._on_sorting_changed, "timestamp")
        self._sort_type_item.connect("activate", self._on_sorting_changed, "sort-type")

    def _on_sorting_changed(self, btn, sort_opt):
        if sort_opt == 'alias' and btn.props.active:
            self.Config['sort-by'] = "alias"
        elif sort_opt == "timestamp" and btn.props.active:
            self.Config['sort-by'] = "timestamp"
        elif sort_opt == 'sort-type':
            # FIXME bind widget to gsetting
            if btn.props.active:
                self.Config["sort-order"] = "descending"
            else:
                self.Config["sort-order"] = "ascending"

    def _on_settings_changed(self, settings, key):
        value = settings[key]
        if key == 'sort-by':
            if value == "alias":
                if not self._sort_alias_item.props.active:
                    self._sort_alias_item.props.active = True
            elif value == "timestamp":
                if not self._sort_timestamp_item.props.active:
                    self._sort_timestamp_item.props.active = True
        elif key == "sort-type":
            if value == "ascending":
                if not self._sort_type_item.props.active:
                    self._sort_type_item.props.active = True
            else:
                if not self._sort_type_item.props.active:
                    self._sort_type_item.props.active = False

    def on_device_selected(self, List, device, tree_iter):
        if tree_iter and device:
            self.item_device.props.sensitive = True

            if self.device_menu is None:
                self.device_menu = ManagerDeviceMenu(self.blueman)
                self.item_device.set_submenu(self.device_menu)
            else:
                GLib.idle_add(self.device_menu.Generate, priority=GLib.PRIORITY_LOW)

        else:
            self.item_device.props.sensitive = False

    def on_adapter_property_changed(self, _adapter, name, value, path):
        if name == "Name" or name == "Alias":
            item = self.adapter_items[path][0]
            item.set_label(value)
        elif name == "Discovering":
            if self.Search:
                if value:
                    self.Search.props.sensitive = False
                else:
                    self.Search.props.sensitive = True

    def on_adapter_selected(self, menuitem, adapter_path):
        if menuitem.props.active:
            if adapter_path != self.blueman.List.Adapter.get_object_path():
                dprint("selected", adapter_path)
                self.blueman.Config["last-adapter"] = adapter_path_to_name(adapter_path)
                self.blueman.List.SetAdapter(adapter_path)

    def on_adapter_added(self, _manager, adapter_path):
        adapter = bluez.Adapter(adapter_path)
        menu = self.item_adapter.get_submenu()
        object_path = adapter.get_object_path()

        item = Gtk.RadioMenuItem.new_with_label(self._adapters_group, adapter.get_name())
        item.show()
        self._adapters_group = item.get_group()

        item_sig = item.connect("activate", self.on_adapter_selected, object_path)
        adapter_sig = adapter.connect_signal("property-changed", self.on_adapter_property_changed)

        menu.insert(item, self._insert_adapter_item_pos)
        self._insert_adapter_item_pos += 1

        self.adapter_items[object_path] = (item, item_sig, adapter, adapter_sig)

        if adapter_path == self.blueman.List.Adapter.get_object_path():
            item.props.active = True

        if len(self.adapter_items) > 0:
            self.item_adapter.props.sensitive = True

    def on_adapter_removed(self, _manager, adapter_path):
        item, item_sig, adapter, adapter_sig = self.adapter_items.pop(adapter_path)
        menu = self.item_adapter.get_submenu()

        item.disconnect(item_sig)
        adapter.disconnect_signal(adapter_sig)

        menu.remove(item)
        self._insert_adapter_item_pos -= 1

        if len(self.adapter_items) == 0:
            self.item_adapter.props.sensitive = False
Beispiel #30
0
    def __init__(self):
        super(Blueman, self).__init__(title=_("Bluetooth Devices"))

        self._applet_sig = None

        self.Config = Config("org.blueman.general")

        self.Builder = Gtk.Builder()
        self.Builder.set_translation_domain("blueman")
        bind_textdomain_codeset("blueman", "UTF-8")
        self.Builder.add_from_file(UI_PATH + "/manager-main.ui")

        grid = self.Builder.get_object("grid")
        self.add(grid)
        self.set_name("BluemanManager")

        self.Plugins = PluginManager(ManagerPlugin, blueman.plugins.manager, self)
        self.Plugins.load_plugin()

        area = MessageArea()
        grid.attach(area, 0, 3, 1, 1)

        # Add margin for resize grip or it will overlap
        if self.get_has_resize_grip():
            statusbar = self.Builder.get_object("statusbar")
            margin_right = statusbar.get_margin_right()
            statusbar.set_margin_right(margin_right + 10)

        def do_present(time):
            if self.props.visible:
                self.present_with_time(time)

        check_single_instance("blueman-manager", do_present)

        def on_window_delete(window, event):
            w, h = self.get_size()
            x, y = self.get_position()
            self.Config["window-properties"] = [w, h, x, y]
            Gtk.main_quit()

        def bt_status_changed(status):
            if not status:
                self.hide()
                check_bluetooth_status(_("Bluetooth needs to be turned on for the device manager to function"),
                                       lambda: Gtk.main_quit())
            else:
                self.show()

        def on_applet_signal(_proxy, _sender, signal_name, params):
            if signal_name == 'BluetoothStatusChanged':
                status = params.unpack()
                bt_status_changed(status)

        def on_dbus_name_vanished(_connection, name):
            logging.info(name)
            if self._applet_sig is not None:
                self.Applet.disconnect(self._applet_sig)
                self._applet_sig = None

            self.hide()

            d = ErrorDialog(
                _("Connection to BlueZ failed"),
                _("Bluez daemon is not running, blueman-manager cannot continue.\n"
                  "This probably means that there were no Bluetooth adapters detected "
                  "or Bluetooth daemon was not started."),
                icon_name="blueman")
            d.run()
            d.destroy()

            # FIXME ui can handle BlueZ start/stop but we should inform user
            Gtk.main_quit()

        def on_dbus_name_appeared(_connection, name, owner):
            logging.info("%s %s" % (name, owner))
            setup_icon_path()

            try:
                self.Applet = AppletService()
            except DBusProxyFailed:
                print("Blueman applet needs to be running")
                exit()

            if 'PowerManager' in self.Applet.QueryPlugins():
                if not self.Applet.get_bluetooth_status():
                    bt_status_changed(False)

            self._applet_sig = self.Applet.connect('g-signal', on_applet_signal)

            self.connect("delete-event", on_window_delete)
            self.props.icon_name = "blueman"

            w, h, x, y = self.Config["window-properties"]
            if w and h:
                self.resize(w, h)
            if x and y:
                self.move(x, y)

            sw = self.Builder.get_object("scrollview")
            # Disable overlay scrolling
            if Gtk.get_minor_version() >= 16:
                sw.props.overlay_scrolling = False

            self.List = ManagerDeviceList(adapter=self.Config["last-adapter"], inst=self)

            self.List.show()
            sw.add(self.List)

            self.Toolbar = ManagerToolbar(self)
            self.Menu = ManagerMenu(self)
            self.Stats = ManagerStats(self)

            if self.List.is_valid_adapter():
                self.List.display_known_devices(autoselect=True)

            self.List.connect("adapter-changed", self.on_adapter_changed)

            toolbar = self.Builder.get_object("toolbar")
            statusbar = self.Builder.get_object("statusbar")

            self.Config.bind_to_widget("show-toolbar", toolbar, "visible")
            self.Config.bind_to_widget("show-statusbar", statusbar, "visible")

            self.show()

        bluez.Manager.watch_name_owner(on_dbus_name_appeared, on_dbus_name_vanished)
Beispiel #31
0
    def __init__(self, blueman):
        self.blueman = blueman
        self.Config = Config("org.blueman.general")

        self.adapter_items = {}
        self._adapters_group = []
        self._insert_adapter_item_pos = 2
        self.Search = None

        self.item_adapter = self.blueman.Builder.get_object("item_adapter")
        self.item_device = self.blueman.Builder.get_object("item_device")

        self.item_view = self.blueman.Builder.get_object("item_view")
        self.item_help = self.blueman.Builder.get_object("item_help")

        help_menu = Gtk.Menu()

        self.item_help.set_submenu(help_menu)
        help_menu.show()

        report_item = create_menuitem(_("_Report a Problem"), get_icon("dialog-warning", 16))
        report_item.show()
        help_menu.append(report_item)
        report_item.connect("activate", lambda x: launch("xdg-open %s/issues" % WEBSITE, None, True))

        sep = Gtk.SeparatorMenuItem()
        sep.show()
        help_menu.append(sep)

        help_item = create_menuitem("_Help", get_icon("help-about"))
        help_item.show()
        help_menu.append(help_item)
        help_item.connect("activate", lambda x: show_about_dialog('Blueman ' + _('Device Manager')))

        view_menu = Gtk.Menu()
        self.item_view.set_submenu(view_menu)
        view_menu.show()

        item_toolbar = Gtk.CheckMenuItem.new_with_mnemonic(_("Show _Toolbar"))
        item_toolbar.show()
        view_menu.append(item_toolbar)
        self.blueman.Config.bind_to_widget("show-toolbar", item_toolbar, "active")

        item_statusbar = Gtk.CheckMenuItem.new_with_mnemonic(_("Show _Statusbar"))
        item_statusbar.show()
        view_menu.append(item_statusbar)
        self.blueman.Config.bind_to_widget("show-statusbar", item_statusbar, "active")

        item_services = Gtk.SeparatorMenuItem()
        view_menu.append(item_services)
        item_services.show()

        sorting_group = []
        item_sort = Gtk.MenuItem.new_with_mnemonic(_("S_ort By"))
        view_menu.append(item_sort)
        item_sort.show()

        sorting_menu = Gtk.Menu()
        item_sort.set_submenu(sorting_menu)

        self._sort_alias_item = Gtk.RadioMenuItem.new_with_mnemonic(sorting_group, _("_Name"))
        self._sort_alias_item.show()
        sorting_group = self._sort_alias_item.get_group()
        sorting_menu.append(self._sort_alias_item)

        self._sort_timestamp_item = Gtk.RadioMenuItem.new_with_mnemonic(sorting_group, _("_Added"))
        self._sort_timestamp_item.show()
        sorting_group = self._sort_timestamp_item.get_group()
        sorting_menu.append(self._sort_timestamp_item)

        sort_config = self.Config['sort-by']
        if sort_config == "alias":
            self._sort_alias_item.props.active = True
        else:
            self._sort_timestamp_item.props.active = True

        sort_sep = Gtk.SeparatorMenuItem()
        sort_sep.show()
        sorting_menu.append(sort_sep)

        self._sort_type_item = Gtk.CheckMenuItem.new_with_mnemonic(_("_Descending"))
        self._sort_type_item.show()
        sorting_menu.append(self._sort_type_item)

        if self.Config['sort-order'] == "ascending":
            self._sort_type_item.props.active = False
        else:
            self._sort_type_item.props.active = True

        sep = Gtk.SeparatorMenuItem()
        sep.show()
        view_menu.append(sep)

        item_plugins = create_menuitem(_("Plugins"), get_icon('blueman-plugin', 16))
        item_plugins.show()
        view_menu.append(item_plugins)
        item_plugins.connect('activate', lambda *args: self.blueman.Applet.open_plugin_dialog(ignore_reply=True))

        item_services = create_menuitem(_("_Local Services") + "...", get_icon("preferences-desktop", 16))
        item_services.connect('activate',
                              lambda *args: launch("blueman-services", None, False, "blueman", _("Service Preferences")))
        view_menu.append(item_services)
        item_services.show()

        adapter_menu = Gtk.Menu()
        self.item_adapter.set_submenu(adapter_menu)
        self.item_adapter.props.sensitive = False

        search_item = create_menuitem(_("_Search"), get_icon("edit-find", 16))
        search_item.connect("activate", lambda x: self.blueman.inquiry())
        search_item.show()
        adapter_menu.prepend(search_item)
        self.Search = search_item

        sep = Gtk.SeparatorMenuItem()
        sep.show()
        adapter_menu.append(sep)

        sep = Gtk.SeparatorMenuItem()
        sep.show()
        adapter_menu.append(sep)

        adapter_settings = create_menuitem("_Preferences", get_icon("preferences-system", 16))
        adapter_settings.connect("activate", lambda x: self.blueman.adapter_properties())
        adapter_settings.show()
        adapter_menu.append(adapter_settings)

        sep = Gtk.SeparatorMenuItem()
        sep.show()
        adapter_menu.append(sep)

        exit_item = create_menuitem("_Exit", get_icon("application-exit", 16))
        exit_item.connect("activate", lambda x: Gtk.main_quit())
        exit_item.show()
        adapter_menu.append(exit_item)

        self.item_adapter.show()
        self.item_view.show()
        self.item_help.show()
        self.item_device.show()
        self.item_device.props.sensitive = False

        self._manager = bluez.Manager()
        self._manager.connect_signal("adapter-added", self.on_adapter_added)
        self._manager.connect_signal("adapter-removed", self.on_adapter_removed)

        blueman.List.connect("device-selected", self.on_device_selected)

        for adapter in self._manager.list_adapters():
            self.on_adapter_added(None, adapter.get_object_path())

        self.device_menu = None

        self.Config.connect("changed", self._on_settings_changed)
        self._sort_alias_item.connect("activate", self._on_sorting_changed, "alias")
        self._sort_timestamp_item.connect("activate", self._on_sorting_changed, "timestamp")
        self._sort_type_item.connect("activate", self._on_sorting_changed, "sort-type")
    def __init__(self, *args):
        super(PersistentPluginManager, self).__init__(*args)

        self.__config = Config("org.blueman.general")

        self.__config.connect("changed::plugin-list", self.on_property_changed)
Beispiel #33
0
class Networking(AppletPlugin):
    __icon__ = "network-workgroup"
    __description__ = _("Manages local network services, like NAP bridges")
    __author__ = "Walmis"

    _signal = None

    def on_load(self):
        self._registered = {}

        self.Config = Config("org.blueman.network")
        self.Config.connect("changed", self.on_config_changed)

        self.load_nap_settings()

    def on_manager_state_changed(self, state):
        if state:
            self.update_status()

    def load_nap_settings(self):
        logging.info("Loading NAP settings")

        def reply(*_):
            pass

        def err(_obj, result, _user_data):
            d = ErrorDialog("<b>Failed to apply network settings</b>",
                            "You might not be able to connect to the Bluetooth network via this machine",
                            result,
                            margin_left=9)

            d.run()
            d.destroy()

        m = Mechanism()
        m.ReloadNetwork(result_handler=reply, error_handler=err)

    def on_unload(self):
        for adapter_path in self._registered:
            s = NetworkServer(adapter_path)
            s.unregister("nap")

        self._registered = {}
        del self.Config

    def on_adapter_added(self, path):
        self.update_status()

    def update_status(self):
        self.set_nap(self.Config["nap-enable"])

    def on_config_changed(self, config, key):
        if key == "nap-enable":
            self.set_nap(config[key])

    def set_nap(self, on):
        logging.info("set nap %s" % on)
        if self.parent.manager_state:
            adapters = self.parent.Manager.get_adapters()
            for adapter in adapters:
                object_path = adapter.get_object_path()

                registered = self._registered.setdefault(object_path, False)

                s = NetworkServer(object_path)
                if on and not registered:
                    s.register("nap", "pan1")
                    self._registered[object_path] = True
                elif not on and registered:
                    s.unregister("nap")
                    self._registered[object_path] = False
Beispiel #34
0
    def setup_network(self):
        self.Config = Config("org.blueman.network")

        nap_enable = self.Builder.get_object("nap-enable")
        r_dnsmasq = self.Builder.get_object("r_dnsmasq")
        r_dhcpd = self.Builder.get_object("r_dhcpd")
        r_udhcpd = self.Builder.get_object("r_udhcpd")
        net_ip = self.Builder.get_object("net_ip")
        rb_nm = self.Builder.get_object("rb_nm")
        rb_blueman = self.Builder.get_object("rb_blueman")
        rb_dun_nm = self.Builder.get_object("rb_dun_nm")
        rb_dun_blueman = self.Builder.get_object("rb_dun_blueman")

        nap_frame = self.Builder.get_object("nap_frame")
        warning = self.Builder.get_object("warning")

        rb_blueman.props.active = self.Config["dhcp-client"]

        if not self.Config["nap-enable"]:
            nap_frame.props.sensitive = False

        nc = NetConf.get_default()
        if nc.ip4_address is not None:
            net_ip.props.text = inet_ntoa(nc.ip4_address)
            nap_enable.props.active = True
        else:
            net_ip.props.text = "10.%d.%d.1" % (randint(0, 255), randint(0, 255))

        if nc.get_dhcp_handler() is None:
            nap_frame.props.sensitive = False
            nap_enable.props.active = False
            r_dnsmasq.props.active = True
            self.Config["nap-enable"] = False

        if nc.get_dhcp_handler() == DnsMasqHandler:
            r_dnsmasq.props.active = True
        elif nc.get_dhcp_handler() == DhcpdHandler:
            r_dhcpd.props.active = True
        elif nc.get_dhcp_handler() == UdhcpdHandler:
            r_udhcpd.props.active = True

        if not have("dnsmasq") and not have("dhcpd3") and not have("dhcpd") and not have("udhcpd"):
            nap_frame.props.sensitive = False
            warning.props.visible = True
            warning.props.sensitive = True
            nap_enable.props.sensitive = False
            self.Config["nap-enable"] = False

        if not have("dnsmasq"):
            r_dnsmasq.props.sensitive = False
            r_dnsmasq.props.active = False

        if not have("dhcpd3") and not have("dhcpd"):
            r_dhcpd.props.sensitive = False
            r_dhcpd.props.active = False

        if not have("udhcpd"):
            r_udhcpd.props.sensitive = False
            r_udhcpd.props.active = False

        r_dnsmasq.connect("toggled", lambda x: self.option_changed_notify("dnsmasq"))
        r_udhcpd.connect("toggled", lambda x: self.option_changed_notify("udhcpd"))

        net_ip.connect("changed", lambda x: self.option_changed_notify("ip", False))
        nap_enable.connect("toggled", lambda x: self.option_changed_notify("nap_enable"))

        self.Config.bind_to_widget("nap-enable", nap_enable, "active", Gio.SettingsBindFlags.GET)

        nap_enable.bind_property("active", nap_frame, "sensitive", 0)

        applet = AppletService()

        avail_plugins = applet.QueryAvailablePlugins()
        active_plugins = applet.QueryPlugins()

        def dun_support_toggled(rb, x):
            if rb.props.active and x == "nm":
                applet.SetPluginConfig('(sb)', "PPPSupport", False)
                applet.SetPluginConfig('(sb)', "NMDUNSupport", True)
            elif rb.props.active and x == "blueman":
                applet.SetPluginConfig('(sb)', "NMDUNSupport", False)
                applet.SetPluginConfig('(sb)', "PPPSupport", True)

        def pan_support_toggled(rb, x):
            if rb.props.active and x == "nm":
                applet.SetPluginConfig('(sb)', "DhcpClient", False)
                applet.SetPluginConfig('(sb)', "NMPANSupport", True)

            elif rb.props.active and x == "blueman":
                applet.SetPluginConfig('(sb)', "NMPANSupport", False)
                applet.SetPluginConfig('(sb)', "DhcpClient", True)

        if "PPPSupport" in active_plugins:
            rb_dun_blueman.props.active = True

        if "NMDUNSupport" in avail_plugins:
            rb_dun_nm.props.sensitive = True
        else:
            rb_dun_nm.props.sensitive = False
            rb_dun_nm.props.tooltip_text = _("Not currently supported with this setup")

        if "NMPANSupport" in avail_plugins:
            rb_nm.props.sensitive = True
        else:
            rb_nm.props.sensitive = False
            rb_nm.props.tooltip_text = _("Not currently supported with this setup")

        if "NMPANSupport" in active_plugins:
            rb_nm.props.active = True

        if "NMDUNSupport" in active_plugins:
            rb_dun_nm.props.active = True

        rb_nm.connect("toggled", pan_support_toggled, "nm")
        rb_blueman.connect("toggled", pan_support_toggled, "blueman")

        rb_dun_nm.connect("toggled", dun_support_toggled, "nm")
        rb_dun_blueman.connect("toggled", dun_support_toggled, "blueman")
Beispiel #35
0
class Networking(AppletPlugin):
    __icon__ = "network"
    __description__ = _("Manages local network services, like NAP bridges")
    __author__ = "Walmis"

    _signal = None

    def on_load(self, applet):
        self._registered = {}

        self.Applet = applet

        self.Config = Config("org.blueman.network")
        self.Config.connect("changed", self.on_config_changed)

        self.load_nap_settings()

    def on_manager_state_changed(self, state):
        if state:
            self.update_status()

    def load_nap_settings(self):
        dprint("Loading NAP settings")

        def reply():
            pass

        def err(excp):
            d = NetworkErrorDialog(
                excp,
                "You might not be able to connect to the Bluetooth network via this machine"
            )
            d.expander.props.margin_left = 9

            d.run()
            d.destroy()

        m = Mechanism()
        m.ReloadNetwork(reply_handler=reply, error_handler=err)

    def on_unload(self):
        del self.Config

    def on_adapter_added(self, path):
        self.update_status()

    def update_status(self):
        self.set_nap(self.Config["nap-enable"])

    def on_config_changed(self, config, key):
        if key == "nap-enable":
            self.set_nap(config[key])

    def set_nap(self, on):
        dprint("set nap", on)
        if self.Applet.Manager is not None:
            adapters = self.Applet.Manager.list_adapters()
            for adapter in adapters:
                object_path = adapter.get_object_path()

                registered = self._registered.setdefault(object_path, False)

                s = NetworkServer(object_path)
                if on and not registered:
                    s.register("nap", "pan1")
                    self._registered[object_path] = True
                elif not on and registered:
                    s.unregister("nap")
                    self._registered[object_path] = False
Beispiel #36
0
def bluez_to_friendly_name(svc):
    if svc == "audiosink":
        return uuid_names[0x110b]
    elif svc == "audiosource":
        return uuid_names[0x110a]
    else:
        raise Exception


from blueman.main.Config import Config
import pickle
import base64
import zlib

sdp_cache = {}
sdp_conf = Config("sdp")


def on_sdp_changed(c, key, value):
    if value and key in sdp_cache:
        s = pickle.loads(zlib.decompress(base64.b64decode(value)))
        sdp_cache[key] = s


sdp_conf.connect("property-changed", on_sdp_changed)


def sdp_get_cached(address):
    if not address in sdp_cache:

        d = sdp_conf.get(address)
Beispiel #37
0
    def __init__(self, *args):
        super(PersistentPluginManager, self).__init__(*args)

        self.__config = Config("org.blueman.general")

        self.__config.connect("changed::plugin-list", self.on_property_changed)
Beispiel #38
0
class ManagerMenu:
    def __init__(self, blueman):
        self.blueman = blueman
        self.Config = Config("org.blueman.general")

        self.adapter_items: Dict[str, Tuple[Gtk.RadioMenuItem, Adapter]] = {}
        self._adapters_group: List[Gtk.RadioMenuItem] = []
        self._insert_adapter_item_pos = 2
        self.Search = None

        self.item_adapter = self.blueman.Builder.get_object("item_adapter")
        self.item_device = self.blueman.Builder.get_object("item_device")

        self.item_view = self.blueman.Builder.get_object("item_view")
        self.item_help = self.blueman.Builder.get_object("item_help")

        help_menu = Gtk.Menu()

        self.item_help.set_submenu(help_menu)
        help_menu.show()

        report_item = create_menuitem(_("_Report a Problem"), "dialog-warning")
        report_item.show()
        help_menu.append(report_item)
        report_item.connect("activate",
                            lambda x: launch("xdg-open %s/issues" % WEBSITE))

        sep = Gtk.SeparatorMenuItem()
        sep.show()
        help_menu.append(sep)

        help_item = create_menuitem("_Help", "help-about")
        help_item.show()
        help_menu.append(help_item)
        help_item.connect(
            "activate",
            lambda x: show_about_dialog('Blueman ' + _('Device Manager'),
                                        parent=self.blueman.get_toplevel()))

        view_menu = Gtk.Menu()
        self.item_view.set_submenu(view_menu)
        view_menu.show()

        item_toolbar = Gtk.CheckMenuItem.new_with_mnemonic(_("Show _Toolbar"))
        item_toolbar.show()
        view_menu.append(item_toolbar)
        self.blueman.Config.bind_to_widget("show-toolbar", item_toolbar,
                                           "active")

        item_statusbar = Gtk.CheckMenuItem.new_with_mnemonic(
            _("Show _Statusbar"))
        item_statusbar.show()
        view_menu.append(item_statusbar)
        self.blueman.Config.bind_to_widget("show-statusbar", item_statusbar,
                                           "active")

        item_services = Gtk.SeparatorMenuItem()
        view_menu.append(item_services)
        item_services.show()

        sorting_group: List[Gtk.RadioMenuItem] = []
        item_sort = Gtk.MenuItem.new_with_mnemonic(_("S_ort By"))
        view_menu.append(item_sort)
        item_sort.show()

        sorting_menu = Gtk.Menu()
        item_sort.set_submenu(sorting_menu)

        self._sort_alias_item = Gtk.RadioMenuItem.new_with_mnemonic(
            sorting_group, _("_Name"))
        self._sort_alias_item.show()
        sorting_group = self._sort_alias_item.get_group()
        sorting_menu.append(self._sort_alias_item)

        self._sort_timestamp_item = Gtk.RadioMenuItem.new_with_mnemonic(
            sorting_group, _("_Added"))
        self._sort_timestamp_item.show()
        sorting_menu.append(self._sort_timestamp_item)

        sort_config = self.Config['sort-by']
        if sort_config == "alias":
            self._sort_alias_item.props.active = True
        else:
            self._sort_timestamp_item.props.active = True

        sort_sep = Gtk.SeparatorMenuItem()
        sort_sep.show()
        sorting_menu.append(sort_sep)

        self._sort_type_item = Gtk.CheckMenuItem.new_with_mnemonic(
            _("_Descending"))
        self._sort_type_item.show()
        sorting_menu.append(self._sort_type_item)

        if self.Config['sort-order'] == "ascending":
            self._sort_type_item.props.active = False
        else:
            self._sort_type_item.props.active = True

        sep = Gtk.SeparatorMenuItem()
        sep.show()
        view_menu.append(sep)

        item_plugins = create_menuitem(_("_Plugins"), 'blueman-plugin')
        item_plugins.show()
        view_menu.append(item_plugins)
        item_plugins.connect('activate', self._on_plugin_dialog_activate)

        item_services = create_menuitem(
            _("_Local Services") + "...", "preferences-desktop")
        item_services.connect(
            'activate', lambda *args: launch("blueman-services",
                                             name=_("Service Preferences")))
        view_menu.append(item_services)
        item_services.show()

        adapter_menu = Gtk.Menu()
        self.item_adapter.set_submenu(adapter_menu)
        self.item_adapter.props.sensitive = False

        search_item = create_menuitem(_("_Search"), "edit-find")
        search_item.connect("activate", lambda x: self.blueman.inquiry())
        search_item.show()
        adapter_menu.prepend(search_item)
        self.Search = search_item

        sep = Gtk.SeparatorMenuItem()
        sep.show()
        adapter_menu.append(sep)

        sep = Gtk.SeparatorMenuItem()
        sep.show()
        adapter_menu.append(sep)

        adapter_settings = create_menuitem("_Preferences",
                                           "preferences-system")
        adapter_settings.connect("activate",
                                 lambda x: self.blueman.adapter_properties())
        adapter_settings.show()
        adapter_menu.append(adapter_settings)

        sep = Gtk.SeparatorMenuItem()
        sep.show()
        adapter_menu.append(sep)

        exit_item = create_menuitem("_Exit", "application-exit")
        exit_item.connect("activate", lambda x: Gtk.main_quit())
        exit_item.show()
        adapter_menu.append(exit_item)

        self.item_adapter.show()
        self.item_view.show()
        self.item_help.show()
        self.item_device.show()
        self.item_device.props.sensitive = False

        self._manager = Manager()
        self._manager.connect_signal("adapter-added", self.on_adapter_added)
        self._manager.connect_signal("adapter-removed",
                                     self.on_adapter_removed)

        blueman.List.connect("device-selected", self.on_device_selected)

        for adapter in self._manager.get_adapters():
            self.on_adapter_added(None, adapter.get_object_path())

        self.device_menu = None

        self.Config.connect("changed", self._on_settings_changed)
        self._sort_alias_item.connect("activate", self._on_sorting_changed,
                                      "alias")
        self._sort_timestamp_item.connect("activate", self._on_sorting_changed,
                                          "timestamp")
        self._sort_type_item.connect("activate", self._on_sorting_changed,
                                     "sort-type")

    def _on_sorting_changed(self, btn, sort_opt):
        if sort_opt == 'alias' and btn.props.active:
            self.Config['sort-by'] = "alias"
        elif sort_opt == "timestamp" and btn.props.active:
            self.Config['sort-by'] = "timestamp"
        elif sort_opt == 'sort-type':
            # FIXME bind widget to gsetting
            if btn.props.active:
                self.Config["sort-order"] = "descending"
            else:
                self.Config["sort-order"] = "ascending"

    def _on_settings_changed(self, settings, key):
        value = settings[key]
        if key == 'sort-by':
            if value == "alias":
                if not self._sort_alias_item.props.active:
                    self._sort_alias_item.props.active = True
            elif value == "timestamp":
                if not self._sort_timestamp_item.props.active:
                    self._sort_timestamp_item.props.active = True
        elif key == "sort-type":
            if value == "ascending":
                if not self._sort_type_item.props.active:
                    self._sort_type_item.props.active = True
            else:
                if not self._sort_type_item.props.active:
                    self._sort_type_item.props.active = False

    def on_device_selected(self, lst, device, tree_iter):
        if tree_iter and device:
            self.item_device.props.sensitive = True

            if self.device_menu is None:
                self.device_menu = ManagerDeviceMenu(self.blueman)
                self.item_device.set_submenu(self.device_menu)
            else:
                GLib.idle_add(self.device_menu.generate,
                              priority=GLib.PRIORITY_LOW)

        else:
            self.item_device.props.sensitive = False

    def on_adapter_property_changed(self, _adapter, name, value, path):
        if name == "Name" or name == "Alias":
            item = self.adapter_items[path][0]
            item.set_label(value)
        elif name == "Discovering":
            if self.Search:
                if value:
                    self.Search.props.sensitive = False
                else:
                    self.Search.props.sensitive = True

    def on_adapter_selected(self, menuitem, adapter_path):
        if menuitem.props.active:
            if adapter_path != self.blueman.List.Adapter.get_object_path():
                logging.info("selected %s", adapter_path)
                self.blueman.Config["last-adapter"] = adapter_path_to_name(
                    adapter_path)
                self.blueman.List.set_adapter(adapter_path)

    def on_adapter_added(self, _manager, adapter_path):
        adapter = Adapter(obj_path=adapter_path)
        menu = self.item_adapter.get_submenu()
        object_path = adapter.get_object_path()

        item = Gtk.RadioMenuItem.new_with_label(self._adapters_group,
                                                adapter.get_name())
        item.show()
        self._adapters_group = item.get_group()

        self._itemhandler = item.connect("activate", self.on_adapter_selected,
                                         object_path)
        self._adapterhandler = adapter.connect_signal(
            "property-changed", self.on_adapter_property_changed)

        menu.insert(item, self._insert_adapter_item_pos)
        self._insert_adapter_item_pos += 1

        self.adapter_items[object_path] = (item, adapter)

        if adapter_path == self.blueman.List.Adapter.get_object_path():
            item.props.active = True

        if len(self.adapter_items) > 0:
            self.item_adapter.props.sensitive = True

    def on_adapter_removed(self, _manager, adapter_path):
        item, adapter = self.adapter_items.pop(adapter_path)
        menu = self.item_adapter.get_submenu()

        item.disconnect(self._itemhandler)
        adapter.disconnect(self._adapterhandler)

        menu.remove(item)
        self._insert_adapter_item_pos -= 1

        if len(self.adapter_items) == 0:
            self.item_adapter.props.sensitive = False

    def _on_plugin_dialog_activate(self, *args):
        def cb(*args):
            pass

        self.blueman.Applet.OpenPluginDialog(result_handler=cb)
Beispiel #39
0
class Network(ServicePlugin):
    __plugin_info__ = (_("Network"), "network-workgroup")

    def on_load(self, container):

        self.Builder = Gtk.Builder()
        self.Builder.set_translation_domain("blueman")
        bind_textdomain_codeset("blueman", "UTF-8")
        self.Builder.add_from_file(UI_PATH + "/services-network.ui")
        self.widget = self.Builder.get_object("network_frame")

        container.pack_start(self.widget, True, True, 0)

        self.interfaces = []
        for iface in get_net_interfaces():
            if iface != "lo" and iface != "pan1":
                logging.info(iface)
                ipiface = ipaddress.ip_interface('/'.join((get_net_address(iface), get_net_netmask(iface))))
                self.interfaces.append((iface, ipiface))

        self.setup_network()
        try:
            self.ip_check()
        except (ValueError, ipaddress.AddressValueError) as e:
            logging.exception(e)
        return _("Network"), "network-workgroup"

    def on_enter(self):
        self.widget.props.visible = True

    def on_leave(self):
        self.widget.props.visible = False

    def on_apply(self):

        if self.on_query_apply_state():
            logging.info("network apply")

            m = Mechanism()
            nap_enable = self.Builder.get_object("nap-enable")
            if nap_enable.props.active:

                if self.Builder.get_object("r_dhcpd").props.active:
                    stype = "DhcpdHandler"
                elif self.Builder.get_object("r_dnsmasq").props.active:
                    stype = "DnsMasqHandler"
                elif self.Builder.get_object("r_udhcpd").props.active:
                    stype = "UdhcpdHandler"

                net_ip = self.Builder.get_object("net_ip")

                try:
                    m.EnableNetwork('(sss)', net_ip.props.text, "255.255.255.0", stype)

                    if not self.Config["nap-enable"]:
                        self.Config["nap-enable"] = True
                except Exception as e:
                    d = ErrorDialog("<b>Failed to apply network settings</b>",
                                    excp=e, parent=self.widget.get_toplevel())

                    d.run()
                    d.destroy()
                    return
            else:
                self.Config["nap-enable"] = False
                m.DisableNetwork()

            self.clear_options()

    def ip_check(self):
        entry = self.Builder.get_object("net_ip")
        try:
            nap_ipiface = ipaddress.ip_interface('/'.join((entry.props.text, '255.255.255.0')))
        except (ValueError, ipaddress.AddressValueError):
            entry.props.secondary_icon_name = "dialog-error"
            entry.props.secondary_icon_tooltip_text = _("Invalid IP address")
            raise

        for iface, ipiface in self.interfaces:
            if nap_ipiface.ip == ipiface.ip:
                error_message = _("IP address conflicts with interface %s which has the same address" % iface)
                tooltip_text = error_message
                entry.props.secondary_icon_name = "dialog-error"
                entry.props.secondary_icon_tooltip_text = tooltip_text
                raise ValueError(error_message)

            elif nap_ipiface.network == ipiface.network:
                tooltip_text = _(
                    "IP address overlaps with subnet of interface %s, which has the following configuration  %s/%s\n"
                    "This may cause incorrect network behavior" % (iface, ipiface.ip, ipiface.netmask))
                entry.props.secondary_icon_name = "dialog-warning"
                entry.props.secondary_icon_tooltip_text = tooltip_text
                return

        entry.props.secondary_icon_name = None

    def on_query_apply_state(self):
        opts = self.get_options()
        if not opts:
            return False

        if "ip" in opts:
            try:
                self.ip_check()
            except (ValueError, ipaddress.AddressValueError) as e:
                logging.exception(e)
                return -1

        return True

    def setup_network(self):
        self.Config = Config("org.blueman.network")

        nap_enable = self.Builder.get_object("nap-enable")
        r_dnsmasq = self.Builder.get_object("r_dnsmasq")
        r_dhcpd = self.Builder.get_object("r_dhcpd")
        r_udhcpd = self.Builder.get_object("r_udhcpd")
        net_ip = self.Builder.get_object("net_ip")
        rb_nm = self.Builder.get_object("rb_nm")
        rb_blueman = self.Builder.get_object("rb_blueman")
        rb_dun_nm = self.Builder.get_object("rb_dun_nm")
        rb_dun_blueman = self.Builder.get_object("rb_dun_blueman")

        nap_frame = self.Builder.get_object("nap_frame")
        warning = self.Builder.get_object("warning")

        if not self.Config["nap-enable"]:
            nap_frame.props.sensitive = False

        nc = NetConf.get_default()
        if nc.ip4_address is not None:
            # previously we stored a bytearray, ipaddress module reads both
            net_ip.props.text = str(ipaddress.ip_address(nc.ip4_address))
            nap_enable.props.active = True
        else:
            net_ip.props.text = "10.%d.%d.1" % (randint(0, 255), randint(0, 255))

        if nc.get_dhcp_handler() is None:
            nap_frame.props.sensitive = False
            nap_enable.props.active = False
            r_dnsmasq.props.active = True
            self.Config["nap-enable"] = False

        have_dhcpd = have("dhcpd3") or have("dhcpd")
        have_dnsmasq = have("dnsmasq")
        have_udhcpd = have("udhcpd")

        if nc.get_dhcp_handler() == DnsMasqHandler and have_dnsmasq:
            r_dnsmasq.props.active = True
        elif nc.get_dhcp_handler() == DhcpdHandler and have_dhcpd:
            r_dhcpd.props.active = True
        elif nc.get_dhcp_handler() == UdhcpdHandler and have_udhcpd:
            r_udhcpd.props.active = True
        else:
            r_dnsmasq.props.active = True

        if not have_dnsmasq and not have_dhcpd and not have_udhcpd:
            nap_frame.props.sensitive = False
            warning.props.visible = True
            warning.props.sensitive = True
            nap_enable.props.sensitive = False
            self.Config["nap-enable"] = False

        if not have_dnsmasq:
            r_dnsmasq.props.sensitive = False
            r_dnsmasq.props.active = False

        if not have_dhcpd:
            r_dhcpd.props.sensitive = False
            r_dhcpd.props.active = False

        if not have_udhcpd:
            r_udhcpd.props.sensitive = False
            r_udhcpd.props.active = False

        r_dnsmasq.connect("toggled", lambda x: self.option_changed_notify("dnsmasq"))
        r_dhcpd.connect("toggled", lambda x: self.option_changed_notify("dhcpd"))
        r_udhcpd.connect("toggled", lambda x: self.option_changed_notify("udhcpd"))

        net_ip.connect("changed", lambda x: self.option_changed_notify("ip", False))
        nap_enable.connect("toggled", lambda x: self.option_changed_notify("nap_enable"))

        self.Config.bind_to_widget("nap-enable", nap_enable, "active", Gio.SettingsBindFlags.GET)

        nap_enable.bind_property("active", nap_frame, "sensitive", 0)

        applet = AppletService()

        avail_plugins = applet.QueryAvailablePlugins()
        active_plugins = applet.QueryPlugins()

        def dun_support_toggled(rb, x):
            if rb.props.active and x == "nm":
                applet.SetPluginConfig('(sb)', "PPPSupport", False)
                applet.SetPluginConfig('(sb)', "NMDUNSupport", True)
            elif rb.props.active and x == "blueman":
                applet.SetPluginConfig('(sb)', "NMDUNSupport", False)
                applet.SetPluginConfig('(sb)', "PPPSupport", True)

        def pan_support_toggled(rb, x):
            if rb.props.active and x == "nm":
                applet.SetPluginConfig('(sb)', "DhcpClient", False)
                applet.SetPluginConfig('(sb)', "NMPANSupport", True)

            elif rb.props.active and x == "blueman":
                applet.SetPluginConfig('(sb)', "NMPANSupport", False)
                applet.SetPluginConfig('(sb)', "DhcpClient", True)

        if "PPPSupport" in active_plugins:
            rb_dun_blueman.props.active = True

        if "NMDUNSupport" in avail_plugins:
            rb_dun_nm.props.sensitive = True
        else:
            rb_dun_nm.props.sensitive = False
            rb_dun_nm.props.tooltip_text = _("Not currently supported with this setup")

        if "DhcpClient" in active_plugins:
            rb_blueman.props.active = True

        if "NMPANSupport" in avail_plugins:
            rb_nm.props.sensitive = True
        else:
            rb_nm.props.sensitive = False
            rb_nm.props.tooltip_text = _("Not currently supported with this setup")

        if "NMPANSupport" in active_plugins:
            rb_nm.props.active = True

        if "NMDUNSupport" in active_plugins:
            rb_dun_nm.props.active = True

        rb_nm.connect("toggled", pan_support_toggled, "nm")
        rb_blueman.connect("toggled", pan_support_toggled, "blueman")

        rb_dun_nm.connect("toggled", dun_support_toggled, "nm")
        rb_dun_blueman.connect("toggled", dun_support_toggled, "blueman")