def menu_items(self):
        items = []

        for prop in self.device_properties:
            if prop == "HSP":
                if not hasattr(self, "headset_service"):
                    self.headset_service = Headset(self.device.device_path)
                if self.headset_service.is_connected():
                    items.append((self.service_connected_pixbufs, _("Headset"), lambda : self.do_disconnect_headset()))
                else:
                    items.append((None, _("Headset"), lambda : self.do_connect_headset()))
            if prop == "AudioSink":
                if not hasattr(self, "audio_sink_service"):
                    self.audio_sink_service = AudioSink(self.device.device_path)
                if self.audio_sink_service.get_connected():
                    items.append((self.service_connected_pixbufs, _("Audio Sink"), lambda : self.do_disconnect_audio_sink()))
                else:
                    items.append((None, _("Audio Sink"), lambda : self.do_connect_audio_sink()))
            if prop == "HumanInterfaceDeviceService":
                if not hasattr(self, "input_service"):
                    self.input_service = Input(self.device.device_path)
                print self.input_service.get_connected()
                if self.input_service.get_connected():
                    items.append((self.service_connected_pixbufs, _("Input Service"), lambda : self.do_disconnect_input_service()))
                else:
                    items.append((None, _("Input Service"), lambda : self.do_connect_input_service()))
            if prop == "OBEXObjectPush":
                items.append((None, _("Send File"), lambda : self.do_send_file()))

        return items
    def menu_items(self):
        items = []

        for prop in self.device_properties:
            if prop == "HSP":
                if not hasattr(self, "headset_service"):
                    self.headset_service = Headset(self.device.device_path)
                if self.headset_service.is_connected():
                    items.append((self.service_connected_pixbufs, _("Headset"),
                                  lambda: self.do_disconnect_headset()))
                else:
                    items.append((None, _("Headset"),
                                  lambda: self.do_connect_headset()))
            if prop == "AudioSink":
                if not hasattr(self, "audio_sink_service"):
                    self.audio_sink_service = AudioSink(
                        self.device.device_path)
                if self.audio_sink_service.get_connected():
                    items.append(
                        (self.service_connected_pixbufs, _("Audio Sink"),
                         lambda: self.do_disconnect_audio_sink()))
                else:
                    items.append((None, _("Audio Sink"),
                                  lambda: self.do_connect_audio_sink()))
            if prop == "HumanInterfaceDeviceService":
                if not hasattr(self, "input_service"):
                    self.input_service = Input(self.device.device_path)
                print self.input_service.get_connected()
                if self.input_service.get_connected():
                    items.append(
                        (self.service_connected_pixbufs, _("Input Service"),
                         lambda: self.do_disconnect_input_service()))
                else:
                    items.append((None, _("Input Service"),
                                  lambda: self.do_connect_input_service()))
            if prop == "OBEXObjectPush":
                items.append(
                    (None, _("Send File"), lambda: self.do_send_file()))

        return items
class DeviceItem(gobject.GObject):
    __gsignals__ = {
        "redraw-request" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
    }

    def __init__(self, name, pixbuf, device, adapter, is_paired=False, module_frame=None):
        gobject.GObject.__init__(self)

        self.name = name
        self.pixbuf = pixbuf
        self.device = device
        self.adapter = adapter
        self.is_paired = is_paired
        self.module_frame = module_frame

        self.device.connect("property-changed", self.__device_property_changed)
        self.pair_pixbuf = app_theme.get_pixbuf("bluetooth/pair.png")
        self.service_connected_pixbufs = (app_theme.get_pixbuf("bluetooth/check_box-2.png"),
                                          app_theme.get_pixbuf("bluetooth/check_box-3.png"),
                                          app_theme.get_pixbuf("bluetooth/check_box-4.png"))
        self.device_connected_pixbuf = app_theme.get_pixbuf("bluetooth/check_box.png")
        self.icon_size = 48
        self.is_button_press = False

        self.__const_padding_y = 10

        self.highlight_fill_color = "#7db7f2"
        self.highlight_stroke_color = "#396497"
        
    def __device_property_changed(self, device, key, value):
        if key == "Paired":
            if bool(value):
                self.is_paired = True
                self.emit_redraw_request()
            else:
                self.is_paired = False
                self.emit_redraw_request()

    def render(self, cr, rect):
        padding = 10

        # Draw select background.
        if self.is_button_press == True:
            with cairo_disable_antialias(cr):
                cr.set_source_rgb(*color_hex_to_cairo(self.highlight_fill_color))
                cr.rectangle(rect.x + padding,
                             rect.y + padding,
                             rect.width - padding,
                             rect.height - padding)
                cr.fill_preserve()
                cr.set_line_width(1)
                cr.set_source_rgb(*color_hex_to_cairo(self.highlight_stroke_color))
                cr.stroke()

        # Draw device icon.
        draw_pixbuf(cr, self.pixbuf,
                    rect.x + self.icon_size / 2 + 4,
                    rect.y + (rect.height - self.icon_size) / 2,
                    )

        if self.is_paired:
            draw_pixbuf(cr,
                        self.pair_pixbuf.get_pixbuf(),
                        rect.x + self.icon_size + self.pair_pixbuf.get_pixbuf().get_width() / 2,
                        rect.y + self.icon_size + self.pair_pixbuf.get_pixbuf().get_height() / 2)
        if self.is_connected:
            draw_pixbuf(cr,
                        self.device_connected_pixbuf.get_pixbuf(),
                        rect.x + self.icon_size + self.pair_pixbuf.get_pixbuf().get_width() / 2,
                        rect.y + self.pair_pixbuf.get_pixbuf().get_height())

        # Draw device name.
        text_color="#000000"
        if self.is_button_press == True:
            text_color="#FFFFFF"
        draw_text(cr,
                  self.name,
                  rect.x + padding,
                  rect.y + self.icon_size + self.__const_padding_y * 2,
                  rect.width - padding,
                  CONTENT_FONT_SIZE,
                  CONTENT_FONT_SIZE,
                  text_color,
                  alignment=pango.ALIGN_CENTER)

    @property
    def device_properties(self):
        return map(lambda _uuid : bluetooth_uuid_to_string(_uuid), self.device.get_uuids())

    @property
    def is_connected(self):
        return self.device.get_connected()

    def emit_redraw_request(self):
        '''
        Emit `redraw-request` signal.

        This is IconView interface, you should implement it.
        '''
        self.emit("redraw-request")

    def get_width(self):
        '''
        Get item width.

        This is IconView interface, you should implement it.
        '''
        return self.icon_size * 2

    def get_height(self):
        '''
        Get item height.

        This is IconView interface, you should implement it.
        '''
        return self.icon_size + CONTENT_FONT_SIZE + self.__const_padding_y * 3

    def icon_item_motion_notify(self, x, y):
        '''
        Handle `motion-notify-event` signal.

        This is IconView interface, you should implement it.
        '''
        self.hover_flag = True
        self.emit_redraw_request()
        event_manager.emit("text", self.name)

    def icon_item_lost_focus(self):
        '''
        Lost focus.

        This is IconView interface, you should implement it.
        '''
        self.hover_flag = False
        self.emit_redraw_request()
        event_manager.emit("hide-text", None)

    def icon_item_highlight(self):
        '''
        Highlight item.

        This is IconView interface, you should implement it.
        '''
        self.highlight_flag = True

        self.emit_redraw_request()

    def icon_item_normal(self):
        '''
        Set item with normal status.

        This is IconView interface, you should implement it.
        '''
        self.highlight_flag = False
        self.is_button_press = False
        self.emit_redraw_request()

    def icon_item_button_press(self, x, y):
        '''
        Handle button-press event.

        This is IconView interface, you should implement it.
        '''
        self.is_button_press = True

    def icon_item_button_release(self, x, y):
        '''
        Handle button-release event.

        This is IconView interface, you should implement it.
        '''
        self.is_button_press = True

    def icon_item_single_click(self, x, y):
        '''
        Handle single click event.

        This is IconView interface, you should implement it.
        '''
        pass

    @property
    def menu_items(self):
        items = []

        for prop in self.device_properties:
            if prop == "HSP":
                if not hasattr(self, "headset_service"):
                    self.headset_service = Headset(self.device.device_path)
                if self.headset_service.is_connected():
                    items.append((self.service_connected_pixbufs, _("Headset"), lambda : self.do_disconnect_headset()))
                else:
                    items.append((None, _("Headset"), lambda : self.do_connect_headset()))
            if prop == "AudioSink":
                if not hasattr(self, "audio_sink_service"):
                    self.audio_sink_service = AudioSink(self.device.device_path)
                if self.audio_sink_service.get_connected():
                    items.append((self.service_connected_pixbufs, _("Audio Sink"), lambda : self.do_disconnect_audio_sink()))
                else:
                    items.append((None, _("Audio Sink"), lambda : self.do_connect_audio_sink()))
            if prop == "HumanInterfaceDeviceService":
                if not hasattr(self, "input_service"):
                    self.input_service = Input(self.device.device_path)
                print self.input_service.get_connected()
                if self.input_service.get_connected():
                    items.append((self.service_connected_pixbufs, _("Input Service"), lambda : self.do_disconnect_input_service()))
                else:
                    items.append((None, _("Input Service"), lambda : self.do_connect_input_service()))
            if prop == "OBEXObjectPush":
                items.append((None, _("Send File"), lambda : self.do_send_file()))

        return items

    def do_send_file(self):
        sender = BluetoothSender(self.adapter, self.device)
        sender.do_send_file()

    def do_connect_audio_sink(self):
        try:
            self.audio_sink_service.as_connect()
            if self.audio_sink_service.get_state() == "connected":
                notify_message(_("Bluetooth Audio"),
                               _("Successfully connected to the Bluetooth audio device."))
            else:
                notify_message(_("Connection Failed"), _("An error occured when connecting to the device."))
            self.emit_redraw_request()
        except Exception, e:
            print "Exception:", e
class DeviceItem(gobject.GObject):
    __gsignals__ = {
        "redraw-request": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
    }

    def __init__(self,
                 name,
                 pixbuf,
                 device,
                 adapter,
                 is_paired=False,
                 module_frame=None):
        gobject.GObject.__init__(self)

        self.name = name
        self.pixbuf = pixbuf
        self.device = device
        self.adapter = adapter
        self.is_paired = is_paired
        self.module_frame = module_frame

        self.device.connect("property-changed", self.__device_property_changed)
        self.pair_pixbuf = app_theme.get_pixbuf("bluetooth/pair.png")
        self.service_connected_pixbufs = (
            app_theme.get_pixbuf("bluetooth/check_box-2.png"),
            app_theme.get_pixbuf("bluetooth/check_box-3.png"),
            app_theme.get_pixbuf("bluetooth/check_box-4.png"))
        self.device_connected_pixbuf = app_theme.get_pixbuf(
            "bluetooth/check_box.png")
        self.icon_size = 48
        self.is_button_press = False

        self.__const_padding_y = 10

        self.highlight_fill_color = "#7db7f2"
        self.highlight_stroke_color = "#396497"

    def __device_property_changed(self, device, key, value):
        if key == "Paired":
            if bool(value):
                self.is_paired = True
                self.emit_redraw_request()
            else:
                self.is_paired = False
                self.emit_redraw_request()

    def render(self, cr, rect):
        padding = 10

        # Draw select background.
        if self.is_button_press == True:
            with cairo_disable_antialias(cr):
                cr.set_source_rgb(
                    *color_hex_to_cairo(self.highlight_fill_color))
                cr.rectangle(rect.x + padding, rect.y + padding,
                             rect.width - padding, rect.height - padding)
                cr.fill_preserve()
                cr.set_line_width(1)
                cr.set_source_rgb(
                    *color_hex_to_cairo(self.highlight_stroke_color))
                cr.stroke()

        # Draw device icon.
        draw_pixbuf(
            cr,
            self.pixbuf,
            rect.x + self.icon_size / 2 + 4,
            rect.y + (rect.height - self.icon_size) / 2,
        )

        if self.is_paired:
            draw_pixbuf(
                cr, self.pair_pixbuf.get_pixbuf(), rect.x + self.icon_size +
                self.pair_pixbuf.get_pixbuf().get_width() / 2,
                rect.y + self.icon_size +
                self.pair_pixbuf.get_pixbuf().get_height() / 2)
        if self.is_connected:
            draw_pixbuf(
                cr, self.device_connected_pixbuf.get_pixbuf(), rect.x +
                self.icon_size + self.pair_pixbuf.get_pixbuf().get_width() / 2,
                rect.y + self.pair_pixbuf.get_pixbuf().get_height())

        # Draw device name.
        text_color = "#000000"
        if self.is_button_press == True:
            text_color = "#FFFFFF"
        draw_text(cr,
                  self.name,
                  rect.x + padding,
                  rect.y + self.icon_size + self.__const_padding_y * 2,
                  rect.width - padding,
                  CONTENT_FONT_SIZE,
                  CONTENT_FONT_SIZE,
                  text_color,
                  alignment=pango.ALIGN_CENTER)

    @property
    def device_properties(self):
        return map(lambda _uuid: bluetooth_uuid_to_string(_uuid),
                   self.device.get_uuids())

    @property
    def is_connected(self):
        return self.device.get_connected()

    def emit_redraw_request(self):
        '''
        Emit `redraw-request` signal.

        This is IconView interface, you should implement it.
        '''
        self.emit("redraw-request")

    def get_width(self):
        '''
        Get item width.

        This is IconView interface, you should implement it.
        '''
        return self.icon_size * 2

    def get_height(self):
        '''
        Get item height.

        This is IconView interface, you should implement it.
        '''
        return self.icon_size + CONTENT_FONT_SIZE + self.__const_padding_y * 3

    def icon_item_motion_notify(self, x, y):
        '''
        Handle `motion-notify-event` signal.

        This is IconView interface, you should implement it.
        '''
        self.hover_flag = True
        self.emit_redraw_request()
        event_manager.emit("text", self.name)

    def icon_item_lost_focus(self):
        '''
        Lost focus.

        This is IconView interface, you should implement it.
        '''
        self.hover_flag = False
        self.emit_redraw_request()
        event_manager.emit("hide-text", None)

    def icon_item_highlight(self):
        '''
        Highlight item.

        This is IconView interface, you should implement it.
        '''
        self.highlight_flag = True

        self.emit_redraw_request()

    def icon_item_normal(self):
        '''
        Set item with normal status.

        This is IconView interface, you should implement it.
        '''
        self.highlight_flag = False
        self.is_button_press = False
        self.emit_redraw_request()

    def icon_item_button_press(self, x, y):
        '''
        Handle button-press event.

        This is IconView interface, you should implement it.
        '''
        self.is_button_press = True

    def icon_item_button_release(self, x, y):
        '''
        Handle button-release event.

        This is IconView interface, you should implement it.
        '''
        self.is_button_press = True

    def icon_item_single_click(self, x, y):
        '''
        Handle single click event.

        This is IconView interface, you should implement it.
        '''
        pass

    @property
    def menu_items(self):
        items = []

        for prop in self.device_properties:
            if prop == "HSP":
                if not hasattr(self, "headset_service"):
                    self.headset_service = Headset(self.device.device_path)
                if self.headset_service.is_connected():
                    items.append((self.service_connected_pixbufs, _("Headset"),
                                  lambda: self.do_disconnect_headset()))
                else:
                    items.append((None, _("Headset"),
                                  lambda: self.do_connect_headset()))
            if prop == "AudioSink":
                if not hasattr(self, "audio_sink_service"):
                    self.audio_sink_service = AudioSink(
                        self.device.device_path)
                if self.audio_sink_service.get_connected():
                    items.append(
                        (self.service_connected_pixbufs, _("Audio Sink"),
                         lambda: self.do_disconnect_audio_sink()))
                else:
                    items.append((None, _("Audio Sink"),
                                  lambda: self.do_connect_audio_sink()))
            if prop == "HumanInterfaceDeviceService":
                if not hasattr(self, "input_service"):
                    self.input_service = Input(self.device.device_path)
                print self.input_service.get_connected()
                if self.input_service.get_connected():
                    items.append(
                        (self.service_connected_pixbufs, _("Input Service"),
                         lambda: self.do_disconnect_input_service()))
                else:
                    items.append((None, _("Input Service"),
                                  lambda: self.do_connect_input_service()))
            if prop == "OBEXObjectPush":
                items.append(
                    (None, _("Send File"), lambda: self.do_send_file()))

        return items

    def do_send_file(self):
        sender = BluetoothSender(self.adapter, self.device)
        sender.do_send_file()

    def do_connect_audio_sink(self):
        try:
            self.audio_sink_service.as_connect()
            if self.audio_sink_service.get_state() == "connected":
                notify_message(
                    _("Bluetooth Audio"),
                    _("Successfully connected to the Bluetooth audio device."))
            else:
                notify_message(
                    _("Connection Failed"),
                    _("An error occured when connecting to the device."))
            self.emit_redraw_request()
        except Exception, e:
            print "Exception:", e