Exemplo n.º 1
0
    def ConnectWiimote(self, config_file, daemon):
        """Request a wiimote connection using the config_file as mapping.

        In order to allow connections a bluetooth adaptor must be available, 
        the uinput module must be loaded and no other connection could be in 
        use (3 - WC_AVAILABLE status, check the StatusChanged signal for more info).

        The bluetooth adaptor connection changes are auto-discovered.
        By now, the uinput module load/unload it's only discovered at service 
        start and at bluetooth adaptor connection changes too. So the best
        it's to ensure that module it's loaded before launching the service.

        The daemon mode sets the connection for waiting indefinitely for 
        pressing 1+2 (not daemon mode only wait for 3 seconds) and trying to 
        reconnect if wiimote it's disconnected.

        Parameters:
        config_file - a string with the absolute path to mapping config file
        daemon - a boolean to set the daemon mode

        Potential Errors:
        Not uinput module present
        Not bluetooth adapter present
        A wiimote connection still in use (disconnect first)
        Mapping validation error
        """

        self.__check_uinput_present()
        if not self.status & WC_UINPUT_PRESENT:
            raise dbus.exceptions.DBusException('Not uinput module present')
        elif not self.status & WC_BLUEZ_PRESENT:
            raise dbus.exceptions.DBusException('Not bluetooth adapter present')
        elif self.status & WC_WIIMOTE_DISCOVERING:
            raise dbus.exceptions.DBusException('Disconnect wiimote first')
        else:
            if config_file:
                validator = MappingValidator()
                validator.validate_file(config_file, False)
                if validator.validation_errors:
                    raise dbus.exceptions.DBusException('Mapping validation error')
                    return

            self.__wminput = WMInputLauncher(config_file, daemon)
            self.__wminput.start()
Exemplo n.º 2
0
    def __init__(self, mapping, system_mapping=False):
        self.mapping = mapping

        self.builder = gtk.Builder()
        if not self.builder.add_objects_from_file(MAPPING_UI, ["mapping_editor_dlg"]):  # , 'mapping_buffer']):
            raise "Cant load %s" % MAPPING_UI
        self.builder.connect_signals(self)

        self.mapping_editor_dlg = self.builder.get_object("mapping_editor_dlg")
        self.name_entry = self.builder.get_object("name_entry")
        self.comment_entry = self.builder.get_object("comment_entry")
        self.version_entry = self.builder.get_object("version_entry")
        self.authors_entry = self.builder.get_object("authors_entry")
        self.scrolledwindow2 = self.builder.get_object("scrolledwindow2")
        self.icon_image = self.builder.get_object("icon_image")
        self.execute_btn = self.builder.get_object("execute_btn")

        lm = gtksourceview2.LanguageManager()
        self.mapping_buffer = gtksourceview2.Buffer()
        self.mapping_buffer.set_data("languages-manager", lm)
        view = gtksourceview2.View(self.mapping_buffer)
        view.set_show_line_numbers(True)
        view.set_auto_indent(True)

        self.scrolledwindow2.add(view)
        self.scrolledwindow2.show_all()

        if system_mapping:
            self.warning_box = self.builder.get_object("warning_box")
            self.warning_frame = self.builder.get_object("warning_frame")
            self.warning_box.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#F6FA9C"))
            self.warning_frame.show_all()

        # FIXME: iconfilechooser with default dialog from glade 3.6.7 crashes
        self.icon_dlg = IconChooserDialog(self.mapping_editor_dlg)
        self.iconfilechooser_btn = gtk.FileChooserButton(self.icon_dlg)
        self.iconfilechooser_btn.show()
        self.iconfilechooser_btn.connect("file-set", self.iconfilechooser_btn_file_set_cb)
        self.builder.get_object("hbox2").add(self.iconfilechooser_btn)

        # Populate dialog with mapping values
        pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(self.mapping.get_icon(), 48, 48)
        self.icon_image.set_from_pixbuf(pixbuf)
        self.name_entry.set_text(self.mapping.get_name() or "")
        self.comment_entry.set_text(self.mapping.get_comment() or "")
        self.version_entry.set_text(self.mapping.get_version() or "")
        self.authors_entry.set_text(self.mapping.get_authors() or "")
        self.mapping_buffer.set_text(self.mapping.get_mapping() or "")
        self.mapping_buffer.place_cursor(self.mapping_buffer.get_start_iter())
        self.mapping_editor_dlg.set_title(_("Editing ") + self.mapping.get_name())

        # Initial error underlining and colorize comments
        self.mapping_buffer.create_tag("underline_error", underline=pango.UNDERLINE_ERROR)
        self.mapping_buffer.create_tag("comment", foreground="darkblue")
        self.validator = MappingValidator()
        self.changed_cb(None)
        self.mapping_buffer.connect("changed", self.changed_cb)

        # Connect and manage wiican service status
        bus = dbus.SessionBus()
        self.wiican_iface = dbus.Interface(bus.get_object(WIICAN_URI, WIICAN_PATH), WIICAN_URI)

        # FIXME: I think that handler_block/unblock its a bad design for this
        self.sig_id = self.execute_btn.connect("clicked", self.execute_btn_clicked_cb)

        def wiican_status_changed(new_status):
            if new_status & WC_WIIMOTE_DISCOVERING:
                if not self.execute_btn.get_active():
                    self.execute_btn.handler_block(self.sig_id)
                    self.execute_btn.set_active(True)
                    self.execute_btn.handler_unblock(self.sig_id)
                    self.execute_btn.set_tooltip_text(_("A mapping is running"))
                    self.execute_btn.set_image(gtk.image_new_from_pixbuf(wiican_disc3_icon))

            elif new_status == (WC_UINPUT_PRESENT | WC_BLUEZ_PRESENT):
                self.execute_btn.set_sensitive(True)
                self.execute_btn.set_tooltip_text(_("Execute this mapping"))
                self.execute_btn.set_image(gtk.image_new_from_pixbuf(wiican_on_icon))
                if self.execute_btn.get_active():
                    self.execute_btn.handler_block(self.sig_id)
                    self.execute_btn.set_active(False)
                    self.execute_btn.handler_unblock(self.sig_id)
            else:
                self.execute_btn.set_sensitive(False)
                self.execute_btn.set_image(gtk.image_new_from_pixbuf(wiican_off_icon))
                self.execute_btn.set_tooltip_text(
                    _("Ensure a bluetooth " + "adapter its available and uinput module its loaded")
                )

        self.wiican_iface.connect_to_signal("StatusChanged", wiican_status_changed, dbus_interface="org.gnome.Wiican")

        status = self.wiican_iface.GetStatus()
        wiican_status_changed(status)

        self.notificator = Notificator("wiican")
Exemplo n.º 3
0
class MappingEditorDialog(object):
    def __init__(self, mapping, system_mapping=False):
        self.mapping = mapping

        self.builder = gtk.Builder()
        if not self.builder.add_objects_from_file(MAPPING_UI, ["mapping_editor_dlg"]):  # , 'mapping_buffer']):
            raise "Cant load %s" % MAPPING_UI
        self.builder.connect_signals(self)

        self.mapping_editor_dlg = self.builder.get_object("mapping_editor_dlg")
        self.name_entry = self.builder.get_object("name_entry")
        self.comment_entry = self.builder.get_object("comment_entry")
        self.version_entry = self.builder.get_object("version_entry")
        self.authors_entry = self.builder.get_object("authors_entry")
        self.scrolledwindow2 = self.builder.get_object("scrolledwindow2")
        self.icon_image = self.builder.get_object("icon_image")
        self.execute_btn = self.builder.get_object("execute_btn")

        lm = gtksourceview2.LanguageManager()
        self.mapping_buffer = gtksourceview2.Buffer()
        self.mapping_buffer.set_data("languages-manager", lm)
        view = gtksourceview2.View(self.mapping_buffer)
        view.set_show_line_numbers(True)
        view.set_auto_indent(True)

        self.scrolledwindow2.add(view)
        self.scrolledwindow2.show_all()

        if system_mapping:
            self.warning_box = self.builder.get_object("warning_box")
            self.warning_frame = self.builder.get_object("warning_frame")
            self.warning_box.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#F6FA9C"))
            self.warning_frame.show_all()

        # FIXME: iconfilechooser with default dialog from glade 3.6.7 crashes
        self.icon_dlg = IconChooserDialog(self.mapping_editor_dlg)
        self.iconfilechooser_btn = gtk.FileChooserButton(self.icon_dlg)
        self.iconfilechooser_btn.show()
        self.iconfilechooser_btn.connect("file-set", self.iconfilechooser_btn_file_set_cb)
        self.builder.get_object("hbox2").add(self.iconfilechooser_btn)

        # Populate dialog with mapping values
        pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(self.mapping.get_icon(), 48, 48)
        self.icon_image.set_from_pixbuf(pixbuf)
        self.name_entry.set_text(self.mapping.get_name() or "")
        self.comment_entry.set_text(self.mapping.get_comment() or "")
        self.version_entry.set_text(self.mapping.get_version() or "")
        self.authors_entry.set_text(self.mapping.get_authors() or "")
        self.mapping_buffer.set_text(self.mapping.get_mapping() or "")
        self.mapping_buffer.place_cursor(self.mapping_buffer.get_start_iter())
        self.mapping_editor_dlg.set_title(_("Editing ") + self.mapping.get_name())

        # Initial error underlining and colorize comments
        self.mapping_buffer.create_tag("underline_error", underline=pango.UNDERLINE_ERROR)
        self.mapping_buffer.create_tag("comment", foreground="darkblue")
        self.validator = MappingValidator()
        self.changed_cb(None)
        self.mapping_buffer.connect("changed", self.changed_cb)

        # Connect and manage wiican service status
        bus = dbus.SessionBus()
        self.wiican_iface = dbus.Interface(bus.get_object(WIICAN_URI, WIICAN_PATH), WIICAN_URI)

        # FIXME: I think that handler_block/unblock its a bad design for this
        self.sig_id = self.execute_btn.connect("clicked", self.execute_btn_clicked_cb)

        def wiican_status_changed(new_status):
            if new_status & WC_WIIMOTE_DISCOVERING:
                if not self.execute_btn.get_active():
                    self.execute_btn.handler_block(self.sig_id)
                    self.execute_btn.set_active(True)
                    self.execute_btn.handler_unblock(self.sig_id)
                    self.execute_btn.set_tooltip_text(_("A mapping is running"))
                    self.execute_btn.set_image(gtk.image_new_from_pixbuf(wiican_disc3_icon))

            elif new_status == (WC_UINPUT_PRESENT | WC_BLUEZ_PRESENT):
                self.execute_btn.set_sensitive(True)
                self.execute_btn.set_tooltip_text(_("Execute this mapping"))
                self.execute_btn.set_image(gtk.image_new_from_pixbuf(wiican_on_icon))
                if self.execute_btn.get_active():
                    self.execute_btn.handler_block(self.sig_id)
                    self.execute_btn.set_active(False)
                    self.execute_btn.handler_unblock(self.sig_id)
            else:
                self.execute_btn.set_sensitive(False)
                self.execute_btn.set_image(gtk.image_new_from_pixbuf(wiican_off_icon))
                self.execute_btn.set_tooltip_text(
                    _("Ensure a bluetooth " + "adapter its available and uinput module its loaded")
                )

        self.wiican_iface.connect_to_signal("StatusChanged", wiican_status_changed, dbus_interface="org.gnome.Wiican")

        status = self.wiican_iface.GetStatus()
        wiican_status_changed(status)

        self.notificator = Notificator("wiican")

    def changed_cb(self, widget, data=None):
        start, end = self.mapping_buffer.get_bounds()
        self.mapping_buffer.remove_all_tags(start, end)

        start, end = self.mapping_buffer.get_bounds()
        self.validator.validate(self.mapping_buffer.get_text(start, end), halt_on_errors=False)

        for error in self.validator.validation_errors:
            if not error:
                continue
            start = self.mapping_buffer.get_iter_at_offset(error.lexpos)
            # FIXME: Finding '\n' for underlining error it's not the best way
            end = self.mapping_buffer.get_iter_at_offset(error.lexpos + error.value.find("\n"))
            self.mapping_buffer.apply_tag_by_name("underline_error", start, end)

        for comment in self.validator.comments:
            start = self.mapping_buffer.get_iter_at_offset(comment.lexpos)
            end = self.mapping_buffer.get_iter_at_offset(comment.lexpos + len(comment.value))
            self.mapping_buffer.apply_tag_by_name("comment", start, end)

    def set_title(self, title=""):
        self.mapping_editor_dlg.set_title(title)

    def run(self):
        return self.mapping_editor_dlg.run()

    def destroy(self):
        self.mapping_editor_dlg.destroy()

    def get_mapping(self):
        start, end = self.mapping_buffer.get_bounds()
        mapping_code = self.mapping_buffer.get_text(start, end)
        # FIXME: If mapping doesn't ends with \n wminput prompts segfault
        if not mapping_code.endswith("\n"):
            mapping_code += "\n"

        self.mapping.set_mapping(mapping_code)
        self.mapping.set_name(self.name_entry.get_text())
        self.mapping.set_comment(self.comment_entry.get_text())
        self.mapping.set_version(self.version_entry.get_text())
        self.mapping.set_authors(self.authors_entry.get_text())

        return self.mapping

    def help_btn_clicked_cb(self, widget):
        webbrowser.open(widget.get_uri())

    def execute_btn_clicked_cb(self, widget):
        if self.execute_btn.get_active():
            start, end = self.mapping_buffer.get_bounds()
            mapping_code = self.mapping_buffer.get_text(start, end)
            # FIXME: If mapping doesn't ends with \n wminput prompts segfault
            if not mapping_code.endswith("\n"):
                mapping_code += "\n"

            # TODO: This file must be unlinked after being used
            filename = tempfile.mktemp()
            fp = open(filename, "w")
            fp.write(mapping_code)
            fp.close()

            try:
                self.wiican_iface.ConnectWiimote(filename, True)
            except dbus.exceptions.DBusException, error:
                if error.message == ("Mapping validation error"):
                    valerr_dlg = ValidationErrorDialog(self.mapping.get_icon(), parent=self.mapping_editor_dlg)
                    valerr_dlg.run()
                    valerr_dlg.destroy()
                    return

            self.notificator.display_notification(
                title=_("Press 1+2"), text=_("To put you Wiimote in discoverable mode now"), icon="wiican"
            )
        else: