示例#1
0
文件: chat.py 项目: leonardcj/speak
    def __init__(self):
        Gtk.VBox.__init__(self)

        self.messenger = None
        self.me = None
        self.quiet = False

        self._buddies = {}

        # chat entry

        owner = presenceservice.get_instance().get_owner()
        self._chat = ChatBox(owner, _is_tablet_mode())
        self._chat.connect('open-on-journal', self.__open_on_journal)
        self.me = self._new_face(owner, ENTRY_COLOR)

        # add owner to buddy list
        self._buddies[owner] = self.me

        # buddies box

        self._buddies_box = Gtk.HBox()
        self._buddies_box.pack_end(self.me, True, True, 0)

        self._buddies_sw = Gtk.ScrolledWindow()
        self._buddies_sw.set_policy(Gtk.PolicyType.AUTOMATIC,
                                    Gtk.PolicyType.NEVER)
        self._buddies_sw.add_with_viewport(self._buddies_box)

        self.chat_post = Gtk.Entry()
        self.chat_post.modify_font(Pango.FontDescription('sans bold 24'))
        self.chat_post.connect('activate', self._activate_cb)
        self.chat_post.connect('key-press-event', self._key_press_cb)

        self._entry = Gtk.HBox()
        self._entry.pack_start(self._buddies_sw, False, False, 0)
        self._entry.pack_start(self.chat_post, True, True, 0)

        if _is_tablet_mode():
            self.pack_start(self._entry, False, False, 0)
            self.pack_end(self._chat, True, True, 0)
        else:
            self.pack_start(self._chat, True, True, 0)
            self.pack_end(self._entry, False, False, 0)

        self.resize_chat_box(expanded=False)
        self.show_all()
示例#2
0
文件: chat.py 项目: sugarlabs/speak
    def __init__(self):
        Gtk.VBox.__init__(self)

        self.messenger = None
        self.me = None
        self.quiet = False

        self._buddies = {}

        # chat entry

        owner = presenceservice.get_instance().get_owner()
        self._chat = ChatBox(owner, _is_tablet_mode())
        self._chat.connect('open-on-journal', self.__open_on_journal)
        self.me = self._new_face(owner, ENTRY_COLOR)

        # add owner to buddy list
        self._buddies[owner] = self.me

        # buddies box

        self._buddies_box = Gtk.HBox()
        self._buddies_box.pack_end(self.me, True, True, 0)

        self._buddies_sw = Gtk.ScrolledWindow()
        self._buddies_sw.set_policy(Gtk.PolicyType.AUTOMATIC,
                                    Gtk.PolicyType.NEVER)
        self._buddies_sw.add_with_viewport(self._buddies_box)

        self.chat_post = Gtk.Entry()
        self.chat_post.modify_font(Pango.FontDescription('sans bold 24'))
        self.chat_post.connect('activate', self._activate_cb)
        self.chat_post.connect('key-press-event', self._key_press_cb)

        self._entry = Gtk.HBox()
        self._entry.pack_start(self._buddies_sw, False, False, 0)
        self._entry.pack_start(self.chat_post, True, True, 0)

        if _is_tablet_mode():
            self.pack_start(self._entry, False, False, 0)
            self.pack_end(self._chat, True, True, 0)
        else:
            self.pack_start(self._chat, True, True, 0)
            self.pack_end(self._entry, False, False, 0)

        self.resize_chat_box(expanded=False)
        self.show_all()
示例#3
0
    def __init__(self, *args, **kwargs):
        super(RootBox, self).__init__(*args, **kwargs)
        self.chat_client = None
        self.receive_queue = Queue()

        # create the confirm box for quitting
        self.quit_confirm = ConfirmPopup(title='Quit?', confirm_text='Quit')
        self.quit_confirm.bind(on_confirm=self.quit_pushed)
        self.quit_confirm.bind(on_cancel=self.cancel_pushed)

        # there is some sort of instantiation order problem where you can't
        # directly refer to custom classes as children in the kv language, so
        # everywhere were we want custom classes there is a BoxLayout which we
        # will now put the custom classes inside
        self.menu = Menu()
        self.menu.hide_item('Chats')
        self.menu.bind(text=self.menu_action)
        self.ids.menu_container.add_widget(self.menu)

        self.chat_box = ChatBox()
        self.ids.chat_box_container.add_widget(self.chat_box)
        
        # don't add server_list just yet, it has the connection status label in
        # it
        # self.server_list = ServerBox(self)

        # store = JsonStore('storage.json')
        # try:
        #     userid = store.get('account')['userid']
        #     password = store.get('account')['password']
        #     host = store.get('server')['host']
        #     port = store.get('server')['port']
        # except KeyError as msg:
        #     print("test {}".format(msg))
        #     self.ids.connection_label.text = 'No Username Set'
        # else:
        #     # create the chat client and start processing on separate thread
        #     self.chat_client = ChatClient(self, userid, password)
        #     self.chat_client.connect((host, port))
        #     self.chat_client.process(block=False)

        self.chat_client = TMPClient(self, tmp, username)
示例#4
0
文件: chat.py 项目: Akirato/speak
    def __init__(self):
        gtk.EventBox.__init__(self)

        self.messenger = None
        self.me = None
        self.quiet = False

        self._buddies = {}

        # buddies box

        self._buddies_sw = gtk.ScrolledWindow()
        self._buddies_sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_NEVER)
        self._buddies_sw.set_size_request(BUDDY_SIZE, BUDDY_SIZE)

        self._buddies_box = gtk.HBox()
        self._buddies_box.set_size_request(BUDDY_SIZE, BUDDY_SIZE)
        self._buddies_sw.add_with_viewport(self._buddies_box)
        self._buddies_box.show()

        # chat entry

        self._owner = presenceservice.get_instance().get_owner()
        self._chat = ChatBox(self._owner, _is_tablet_mode())
        self._chat.set_size_request(
            -1, gtk.gdk.screen_height() - style.GRID_CELL_SIZE - BUDDY_SIZE)
        self.me, my_face_widget = self._new_face(self._owner,
                ENTRY_COLOR)
        my_face_widget.set_size_request(BUDDY_SIZE, BUDDY_SIZE)

        # add owner to buddy list
        self._buddies[self._owner] = {
                'box': my_face_widget,
                'face': self.me,
                'lang': ''
                }

        self.chat_post = gtk.Entry()
        entry_height = int(BUDDY_SIZE)
        entry_width = gtk.gdk.screen_width() - \
                      max(1, min(5, len(self._buddies))) * BUDDY_SIZE
        self.chat_post.set_size_request(entry_width, entry_height)
        self.chat_post.modify_bg(gtk.STATE_NORMAL,
                                 style.COLOR_WHITE.get_gdk_color())
        self.chat_post.modify_base(gtk.STATE_NORMAL,
                                   style.COLOR_WHITE.get_gdk_color())
        self.chat_post.modify_font(pango.FontDescription(str='sans bold 24'))
        self.chat_post.connect('activate', self._activate_cb)
        self.chat_post.connect('key-press-event', self._key_press_cb)

        chat_post_box = gtk.VBox()
        chat_post_box.pack_start(self.chat_post, padding=ENTRY_XPAD)
        self.chat_post.show()

        chat_entry = gtk.HBox()
        self._buddies_box.pack_start(my_face_widget)
        chat_entry.pack_start(self._buddies_sw)
        my_face_widget.show()
        chat_entry.pack_start(chat_post_box)
        chat_post_box.show()

        if _is_tablet_mode():
            chat_box = gtk.VBox()
            chat_box.pack_start(chat_entry)
            chat_entry.show()
            chat_box.pack_start(self._chat, expand=True)
            self._chat.show()
        else:
            chat_box = gtk.VBox()
            chat_box.pack_start(self._chat, expand=True)
            self._chat.show()
            chat_box.pack_start(chat_entry)
            chat_entry.show()

        # desk
        self._desk = gtk.HBox()
        self._desk.pack_start(chat_box)
        self.add(self._desk)
        self._desk.show()
示例#5
0
文件: chat.py 项目: Akirato/speak
class View(gtk.EventBox):
    def __init__(self):
        gtk.EventBox.__init__(self)

        self.messenger = None
        self.me = None
        self.quiet = False

        self._buddies = {}

        # buddies box

        self._buddies_sw = gtk.ScrolledWindow()
        self._buddies_sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_NEVER)
        self._buddies_sw.set_size_request(BUDDY_SIZE, BUDDY_SIZE)

        self._buddies_box = gtk.HBox()
        self._buddies_box.set_size_request(BUDDY_SIZE, BUDDY_SIZE)
        self._buddies_sw.add_with_viewport(self._buddies_box)
        self._buddies_box.show()

        # chat entry

        self._owner = presenceservice.get_instance().get_owner()
        self._chat = ChatBox(self._owner, _is_tablet_mode())
        self._chat.set_size_request(
            -1, gtk.gdk.screen_height() - style.GRID_CELL_SIZE - BUDDY_SIZE)
        self.me, my_face_widget = self._new_face(self._owner,
                ENTRY_COLOR)
        my_face_widget.set_size_request(BUDDY_SIZE, BUDDY_SIZE)

        # add owner to buddy list
        self._buddies[self._owner] = {
                'box': my_face_widget,
                'face': self.me,
                'lang': ''
                }

        self.chat_post = gtk.Entry()
        entry_height = int(BUDDY_SIZE)
        entry_width = gtk.gdk.screen_width() - \
                      max(1, min(5, len(self._buddies))) * BUDDY_SIZE
        self.chat_post.set_size_request(entry_width, entry_height)
        self.chat_post.modify_bg(gtk.STATE_NORMAL,
                                 style.COLOR_WHITE.get_gdk_color())
        self.chat_post.modify_base(gtk.STATE_NORMAL,
                                   style.COLOR_WHITE.get_gdk_color())
        self.chat_post.modify_font(pango.FontDescription(str='sans bold 24'))
        self.chat_post.connect('activate', self._activate_cb)
        self.chat_post.connect('key-press-event', self._key_press_cb)

        chat_post_box = gtk.VBox()
        chat_post_box.pack_start(self.chat_post, padding=ENTRY_XPAD)
        self.chat_post.show()

        chat_entry = gtk.HBox()
        self._buddies_box.pack_start(my_face_widget)
        chat_entry.pack_start(self._buddies_sw)
        my_face_widget.show()
        chat_entry.pack_start(chat_post_box)
        chat_post_box.show()

        if _is_tablet_mode():
            chat_box = gtk.VBox()
            chat_box.pack_start(chat_entry)
            chat_entry.show()
            chat_box.pack_start(self._chat, expand=True)
            self._chat.show()
        else:
            chat_box = gtk.VBox()
            chat_box.pack_start(self._chat, expand=True)
            self._chat.show()
            chat_box.pack_start(chat_entry)
            chat_entry.show()

        # desk
        self._desk = gtk.HBox()
        self._desk.pack_start(chat_box)
        self.add(self._desk)
        self._desk.show()

    def resize_chat_box(self, expanded=False):
        if expanded:
            self._chat.set_size_request(
                -1,
                gtk.gdk.screen_height() - 2 * style.GRID_CELL_SIZE
                - BUDDY_SIZE)
        else:
            self._chat.set_size_request(
                -1,
                gtk.gdk.screen_height() - style.GRID_CELL_SIZE - BUDDY_SIZE)

    def update(self, status):
        self.me.update(status)
        if self.messenger:
            self.messenger.post('%s:%s' %
                                (STATUS_MSG, status.serialize()))

    def post(self, buddy, text, status_message=False):
        i = self._find_buddy(buddy)

        buddy_face = i['face']
        lang_box = i['lang']

        if not text:
            return

        ascii_text = text.encode('ascii', 'ignore')
        if STATUS_MSG in ascii_text:
            try:
                status = face.Status().deserialize(
                    ascii_text[len(STATUS_MSG) + 1:])
                buddy_face.update(status)
                if lang_box:
                    lang_box.props.text = status.voice.friendlyname
            except:
                logging.error('Could not parse status message %s' %
                              text)
        else:
            self._chat.add_text(buddy, text, status_message)
            if not self.quiet:
                # and self.props.window \
                #    and self.props.window.is_visible():
                buddy_face.say(text)

    def _find_buddy(self, buddy):
        i = self._buddies.get(buddy)
        if not i:
            # Sometimes the same buddy has a different dbus instance,
            # so walk through the list
            nick = buddy.props.nick
            color = buddy.props.color
            for old_buddy in self._buddies.keys():
                if old_buddy.props.nick == nick and \
                   old_buddy.props.color == color:
                    i = self._buddies.get(old_buddy)
            if not i:  # No match, so add a new buddy
                self._add_buddy(buddy)
                i = self._buddies[buddy]
        return i

    def resize_buddy_list(self):
        self._buddies_box.set_size_request(
            len(self._buddies) * BUDDY_SIZE, -1)
        size = min(5, len(self._buddies)) * BUDDY_SIZE
        self._buddies_sw.set_size_request(size, -1)
        self.chat_post.set_size_request(gtk.gdk.screen_width() - size, -1)

    def farewell(self, buddy):
        i = self._find_buddy(buddy)
        if not i:
            logger.debug('farewell: cannot find buddy %s' % buddy.props.nick)
            return

        self._buddies_box.remove(i['box'])
        del self._buddies[buddy]
        self.resize_buddy_list()

    def shut_up(self):
        for i in self._buddies.values():
            i['face'].shut_up();
        self.me.shut_up();

    def _add_buddy(self, buddy):
        box = gtk.VBox()
        buddy_face, buddy_widget = self._new_face(buddy, BUDDIES_COLOR)
        box.pack_start(buddy_widget)
        buddy_widget.show()
        self._buddies[buddy] = {
                'box': box,
                'face': buddy_face,
                'lang': ''
                }
        self._buddies_box.pack_start(box)
        box.show()
        self.resize_buddy_list()

    def _activate_cb(self, widget, event):
        text = widget.get_buffer().props.text
        if text:
            self._chat.add_text(None, text)
            widget.get_buffer().props.text = ''
            if not self.quiet:
                self.me.say(text)
            if self.messenger:
                self.messenger.post(text)
        return True

    def _key_press_cb(self, widget, event):
        if event.keyval == gtk.keysyms.Return:
            if not (event.state & gtk.gdk.CONTROL_MASK):
                return self._activate_cb(widget, event)
        return False

    def _new_face(self, buddy, color):
        colors = buddy.props.color.split(',')
        lighter = style.Color(colors[_lighter_color(colors)])

        buddy_face = face.View(lighter)
        buddy_face.set_border_state(False)
        buddy_face.set_size_request(BUDDY_SIZE - style.DEFAULT_PADDING,
                                    BUDDY_SIZE - style.DEFAULT_PADDING)

        outer = gtk.VBox()
        outer.set_size_request(BUDDY_SIZE, BUDDY_SIZE)
        outer.pack_start(buddy_face)
        buddy_face.show_all()

        return (buddy_face, outer)

    def look_at(self):
        self.me.look_at()
        for i in self._buddies.values():
            i['face'].look_at()
示例#6
0
文件: chat.py 项目: leonardcj/speak
class View(Gtk.VBox):
    def __init__(self):
        Gtk.VBox.__init__(self)

        self.messenger = None
        self.me = None
        self.quiet = False

        self._buddies = {}

        # chat entry

        owner = presenceservice.get_instance().get_owner()
        self._chat = ChatBox(owner, _is_tablet_mode())
        self._chat.connect('open-on-journal', self.__open_on_journal)
        self.me = self._new_face(owner, ENTRY_COLOR)

        # add owner to buddy list
        self._buddies[owner] = self.me

        # buddies box

        self._buddies_box = Gtk.HBox()
        self._buddies_box.pack_end(self.me, True, True, 0)

        self._buddies_sw = Gtk.ScrolledWindow()
        self._buddies_sw.set_policy(Gtk.PolicyType.AUTOMATIC,
                                    Gtk.PolicyType.NEVER)
        self._buddies_sw.add_with_viewport(self._buddies_box)

        self.chat_post = Gtk.Entry()
        self.chat_post.modify_font(Pango.FontDescription('sans bold 24'))
        self.chat_post.connect('activate', self._activate_cb)
        self.chat_post.connect('key-press-event', self._key_press_cb)

        self._entry = Gtk.HBox()
        self._entry.pack_start(self._buddies_sw, False, False, 0)
        self._entry.pack_start(self.chat_post, True, True, 0)

        if _is_tablet_mode():
            self.pack_start(self._entry, False, False, 0)
            self.pack_end(self._chat, True, True, 0)
        else:
            self.pack_start(self._chat, True, True, 0)
            self.pack_end(self._entry, False, False, 0)

        self.resize_chat_box(expanded=False)
        self.show_all()

    def resize_chat_box(self, expanded=False):
        pass

    def update(self, status):
        self.me.update(status)
        if self.messenger:
            self.messenger.post('%s:%s' %
                                (STATUS_MSG, status.serialize()))

    def post(self, buddy, text, status_message=False):
        buddy_face = self._find_buddy(buddy)

        if not text:
            return

        ascii_text = text.encode('ascii', 'ignore')
        if STATUS_MSG in ascii_text:
            try:
                status = face.Status().deserialize(
                    ascii_text[len(STATUS_MSG) + 1:])
                buddy_face.update(status)
                self.resize_buddy_list()
            except:
                logging.error('Could not parse status message %s' %
                              text)
        else:
            self._chat.add_text(buddy, text, status_message)
            if not self.quiet:
                # and self.props.window \
                #    and self.props.window.is_visible():
                buddy_face.say(text)

    def _find_buddy(self, buddy):
        i = self._buddies.get(buddy)
        if not i:
            # Sometimes the same buddy has a different dbus instance,
            # so walk through the list
            nick = buddy.props.nick
            color = buddy.props.color
            for old_buddy in self._buddies.keys():
                if old_buddy.props.nick == nick and \
                   old_buddy.props.color == color:
                    i = self._buddies.get(old_buddy)
            if not i:  # No match, so add a new buddy
                self._add_buddy(buddy)
                i = self._buddies[buddy]
        return i

    def resize_buddy_list(self):
        """ maintain the buddy list width """
        size = min(BUDDIES_WIDTH, len(self._buddies) * BUDDY_SIZE)
        self._buddies_sw.set_size_request(size, BUDDY_SIZE)
        for buddy in self._buddies.values():
            buddy.set_size_request(BUDDY_SIZE, BUDDY_SIZE)

    def farewell(self, buddy):
        i = self._find_buddy(buddy)
        if not i:
            logger.debug('farewell: cannot find buddy %s' % buddy.props.nick)
            return

        self._buddies_box.remove(i)
        del self._buddies[buddy]
        self.resize_buddy_list()

    def shut_up(self):
        for i in self._buddies.values():
            i.shut_up();
        self.me.shut_up();

    def _add_buddy(self, buddy):
        self._buddies[buddy] = self._new_face(buddy, BUDDIES_COLOR)
        self._buddies_box.pack_start(self._buddies[buddy], True, True, 0)
        self.resize_buddy_list()

    def _activate_cb(self, widget, event):
        text = widget.get_buffer().props.text
        if text:
            self._chat.add_text(None, text)
            widget.get_buffer().props.text = ''
            if not self.quiet:
                self.me.say(text)
            if self.messenger:
                self.messenger.post(text)
        return True

    def _key_press_cb(self, widget, event):
        if event.keyval == Gdk.KEY_Return:
            if not (event.state & Gdk.ModifierType.CONTROL_MASK):
                return self._activate_cb(widget, event)
        return False

    def _new_face(self, buddy, color):
        colors = buddy.props.color.split(',')
        lighter = style.Color(colors[_lighter_color(colors)])

        buddy_face = face.View(lighter)
        # FIXME: omit set_border_state causes main face alignment problems
        buddy_face.set_border_state(False)
        # FIXME: non-me faces have no mouth

        buddy_face.show_all()

        return buddy_face

    def look_at(self):
        self.me.look_at()
        for i in self._buddies.values():
            i.look_at()

    def __open_on_journal(self, widget, url):
        '''Ask the journal to display a URL'''
        jobject = datastore.create()
        metadata = {
            'title': '%s: %s' % (_('URL from Speak'), url),
            'title_set_by_user': '******',
            'icon-color': profile.get_color().to_string(),
            'mime_type': 'text/uri-list',
            }
        for k, v in metadata.items():
            jobject.metadata[k] = v
        file_path = os.path.join(get_activity_root(), 'instance',
                                 '%i_' % time.time())
        open(file_path, 'w').write(url + '\r\n')
        os.chmod(file_path, 0755)
        jobject.set_file_path(file_path)
        datastore.write(jobject)
        show_object_in_journal(jobject.object_id)
        jobject.destroy()
        os.unlink(file_path)
示例#7
0
    def __init__(self):
        hippo.Canvas.__init__(self)

        self.messenger = None
        self.me = None
        self.quiet = False

        self._buddies = {}

        # buddies box

        self._buddies_list = hippo.CanvasBox(
                background_color = BUDDIES_COLOR.get_int(),
                box_width = BUDDIES_WIDTH,
                padding = ENTRY_YPAD,
                spacing = ENTRY_YPAD
                )

        self._buddies_box = hippo.CanvasScrollbars()
        self._buddies_box.set_policy(hippo.ORIENTATION_HORIZONTAL,
                hippo.SCROLLBAR_NEVER)
        self._buddies_box.set_root(self._buddies_list)

        # chat entry

        self._chat = ChatBox()
        self.me, my_face_widget = self._new_face(self._chat.owner,
                ENTRY_COLOR)

        chat_post = gtk.TextView()
        chat_post.modify_bg(gtk.STATE_INSENSITIVE,
                style.COLOR_WHITE.get_gdk_color())
        chat_post.modify_base(gtk.STATE_INSENSITIVE,
                style.COLOR_WHITE.get_gdk_color())
        chat_post.connect('key-press-event', self._key_press_cb)
        chat_post.props.wrap_mode = gtk.WRAP_WORD_CHAR
        chat_post.set_size_request(-1, BUDDY_SIZE - ENTRY_YPAD * 2)
        chat_post_box = CanvasRoundBox(
                background_color = style.COLOR_WHITE.get_int(),
                padding_left = ENTRY_XPAD,
                padding_right = ENTRY_XPAD,
                padding_top = ENTRY_YPAD,
                padding_bottom = ENTRY_YPAD
                )
        chat_post_box.props.border_color = ENTRY_COLOR.get_int()
        chat_post_box.append(hippo.CanvasWidget(widget=chat_post),
                hippo.PACK_EXPAND)

        chat_entry = CanvasRoundBox(
                background_color = ENTRY_COLOR.get_int(),
                padding_left = ENTRY_XPAD,
                padding_right = ENTRY_XPAD,
                padding_top = ENTRY_YPAD,
                padding_bottom = ENTRY_YPAD,
                spacing = ENTRY_YPAD
                )
        chat_entry.props.orientation = hippo.ORIENTATION_HORIZONTAL
        chat_entry.props.border_color = style.COLOR_WHITE.get_int()
        chat_entry.append(my_face_widget)
        chat_entry.append(chat_post_box, hippo.PACK_EXPAND)

        chat_box = hippo.CanvasBox(
                orientation = hippo.ORIENTATION_VERTICAL,
                background_color = style.COLOR_WHITE.get_int(),
                )
        chat_box.append(self._chat, hippo.PACK_EXPAND)
        chat_box.append(chat_entry)

        # desk

        self._desk = hippo.CanvasBox()
        self._desk.props.orientation = hippo.ORIENTATION_HORIZONTAL
        self._desk.append(chat_box, hippo.PACK_EXPAND)

        self.set_root(self._desk)
示例#8
0
class View(hippo.Canvas):
    def __init__(self):
        hippo.Canvas.__init__(self)

        self.messenger = None
        self.me = None
        self.quiet = False

        self._buddies = {}

        # buddies box

        self._buddies_list = hippo.CanvasBox(
                background_color = BUDDIES_COLOR.get_int(),
                box_width = BUDDIES_WIDTH,
                padding = ENTRY_YPAD,
                spacing = ENTRY_YPAD
                )

        self._buddies_box = hippo.CanvasScrollbars()
        self._buddies_box.set_policy(hippo.ORIENTATION_HORIZONTAL,
                hippo.SCROLLBAR_NEVER)
        self._buddies_box.set_root(self._buddies_list)

        # chat entry

        self._chat = ChatBox()
        self.me, my_face_widget = self._new_face(self._chat.owner,
                ENTRY_COLOR)

        chat_post = gtk.TextView()
        chat_post.modify_bg(gtk.STATE_INSENSITIVE,
                style.COLOR_WHITE.get_gdk_color())
        chat_post.modify_base(gtk.STATE_INSENSITIVE,
                style.COLOR_WHITE.get_gdk_color())
        chat_post.connect('key-press-event', self._key_press_cb)
        chat_post.props.wrap_mode = gtk.WRAP_WORD_CHAR
        chat_post.set_size_request(-1, BUDDY_SIZE - ENTRY_YPAD * 2)
        chat_post_box = CanvasRoundBox(
                background_color = style.COLOR_WHITE.get_int(),
                padding_left = ENTRY_XPAD,
                padding_right = ENTRY_XPAD,
                padding_top = ENTRY_YPAD,
                padding_bottom = ENTRY_YPAD
                )
        chat_post_box.props.border_color = ENTRY_COLOR.get_int()
        chat_post_box.append(hippo.CanvasWidget(widget=chat_post),
                hippo.PACK_EXPAND)

        chat_entry = CanvasRoundBox(
                background_color = ENTRY_COLOR.get_int(),
                padding_left = ENTRY_XPAD,
                padding_right = ENTRY_XPAD,
                padding_top = ENTRY_YPAD,
                padding_bottom = ENTRY_YPAD,
                spacing = ENTRY_YPAD
                )
        chat_entry.props.orientation = hippo.ORIENTATION_HORIZONTAL
        chat_entry.props.border_color = style.COLOR_WHITE.get_int()
        chat_entry.append(my_face_widget)
        chat_entry.append(chat_post_box, hippo.PACK_EXPAND)

        chat_box = hippo.CanvasBox(
                orientation = hippo.ORIENTATION_VERTICAL,
                background_color = style.COLOR_WHITE.get_int(),
                )
        chat_box.append(self._chat, hippo.PACK_EXPAND)
        chat_box.append(chat_entry)

        # desk

        self._desk = hippo.CanvasBox()
        self._desk.props.orientation = hippo.ORIENTATION_HORIZONTAL
        self._desk.append(chat_box, hippo.PACK_EXPAND)

        self.set_root(self._desk)

    def update(self, status):
        self.me.update(status)
        if self.messenger:
            self.messenger.post(None)

    def post(self, buddy, status, text):
        i = self._buddies.get(buddy)
        if not i:
            self._add_buddy(buddy)
            i = self._buddies[buddy]

        face = i['face']
        lang_box = i['lang']

        if status:
            face.update(status)
            if lang_box:
                lang_box.props.text = status.voice.friendlyname
        if text:
            self._chat.add_text(buddy, text)
            if not self.quiet:
                # and self.props.window \
                #    and self.props.window.is_visible():
                face.say(text)

    def farewell(self, buddy):
        i = self._buddies.get(buddy)
        if not i:
            logger.debug('farewell: cannot find buddy %s' % buddy.props.nick)
            return

        self._buddies_list.remove(i['box'])
        del self._buddies[buddy]

        if len(self._buddies) == 0:
            self._desk.remove(self._buddies_box)

    def shut_up(self):
        for i in self._buddies.values():
            i['face'].shut_up();
        self.me.shut_up();

    def _add_buddy(self, buddy):
        box = hippo.CanvasBox(
                orientation = hippo.ORIENTATION_HORIZONTAL,
                background_color = BUDDIES_COLOR.get_int(),
                spacing = ENTRY_YPAD
                )

        buddy_face, buddy_widget = self._new_face(buddy, BUDDIES_COLOR)

        char_box = hippo.CanvasBox(
                orientation = hippo.ORIENTATION_VERTICAL,
                )
        nick = hippo.CanvasText(
                text = buddy.props.nick,
                xalign = hippo.ALIGNMENT_START,
                yalign = hippo.ALIGNMENT_START
                )
        lang = hippo.CanvasText(
                text = '',
                xalign = hippo.ALIGNMENT_START,
                yalign = hippo.ALIGNMENT_START
                )
        char_box.append(nick)
        char_box.append(lang)

        box.append(buddy_widget)
        box.append(char_box, hippo.PACK_EXPAND)

        self._buddies[buddy] = {
                'box': box,
                'face': buddy_face,
                'lang': lang
                }
        self._buddies_list.append(box)

        if len(self._buddies) == 1:
            self._desk.append(self._buddies_box)

    def _key_press_cb(self, widget, event):
        if event.keyval == gtk.keysyms.Return:
            if not (event.state & gtk.gdk.CONTROL_MASK):
                text = widget.get_buffer().props.text

                if text:
                    self._chat.add_text(None, text)
                    widget.get_buffer().props.text = ''
                    if not self.quiet:
                        self.me.say(text)
                    if self.messenger:
                        self.messenger.post(text)

                return True
        return False

    def _new_face(self, buddy, color):
        stroke_color, fill_color = buddy.props.color.split(',')
        stroke_color = style.Color(stroke_color)
        fill_color = style.Color(fill_color)

        buddy_face = face.View(fill_color)
        buddy_face.show_all()

        inner = CanvasRoundBox(
                background_color = fill_color.get_int(),
                )
        inner.props.border_color = fill_color.get_int()
        inner.append(hippo.CanvasWidget(widget=buddy_face), hippo.PACK_EXPAND)
        inner.props.border = BUDDY_PAD

        outer = CanvasRoundBox(
                background_color = stroke_color.get_int(),
                box_width = BUDDY_SIZE,
                box_height = BUDDY_SIZE,
                )
        outer.props.border_color = stroke_color.get_int()
        outer.append(inner, hippo.PACK_EXPAND)
        outer.props.border = BUDDY_PAD

        return (buddy_face, outer)

    def look_at(self):
        self.me.look_at()
        for i in self._buddies.values():
            i['face'].look_at()
示例#9
0
文件: chat.py 项目: sugarlabs/speak
class View(Gtk.VBox):
    def __init__(self):
        Gtk.VBox.__init__(self)

        self.messenger = None
        self.me = None
        self.quiet = False

        self._buddies = {}

        # chat entry

        owner = presenceservice.get_instance().get_owner()
        self._chat = ChatBox(owner, _is_tablet_mode())
        self._chat.connect('open-on-journal', self.__open_on_journal)
        self.me = self._new_face(owner, ENTRY_COLOR)

        # add owner to buddy list
        self._buddies[owner] = self.me

        # buddies box

        self._buddies_box = Gtk.HBox()
        self._buddies_box.pack_end(self.me, True, True, 0)

        self._buddies_sw = Gtk.ScrolledWindow()
        self._buddies_sw.set_policy(Gtk.PolicyType.AUTOMATIC,
                                    Gtk.PolicyType.NEVER)
        self._buddies_sw.add_with_viewport(self._buddies_box)

        self.chat_post = Gtk.Entry()
        self.chat_post.modify_font(Pango.FontDescription('sans bold 24'))
        self.chat_post.connect('activate', self._activate_cb)
        self.chat_post.connect('key-press-event', self._key_press_cb)

        self._entry = Gtk.HBox()
        self._entry.pack_start(self._buddies_sw, False, False, 0)
        self._entry.pack_start(self.chat_post, True, True, 0)

        if _is_tablet_mode():
            self.pack_start(self._entry, False, False, 0)
            self.pack_end(self._chat, True, True, 0)
        else:
            self.pack_start(self._chat, True, True, 0)
            self.pack_end(self._entry, False, False, 0)

        self.resize_chat_box(expanded=False)
        self.show_all()

    def resize_chat_box(self, expanded=False):
        pass

    def update(self, status):
        self.me.update(status)
        if self.messenger:
            self.messenger.post('%s:%s' %
                                (STATUS_MSG, status.serialize()))

    def post(self, buddy, text, status_message=False):
        buddy_face = self._find_buddy(buddy)

        if not text:
            return

        ascii_text = text.encode('ascii', 'ignore')
        if STATUS_MSG in ascii_text:
            try:
                status = face.Status().deserialize(
                    ascii_text[len(STATUS_MSG) + 1:])
                buddy_face.update(status)
                self.resize_buddy_list()
            except:
                logging.error('Could not parse status message %s' %
                              text)
        else:
            self._chat.add_text(buddy, text, status_message)
            if not self.quiet:
                # and self.props.window \
                #    and self.props.window.is_visible():
                buddy_face.say(text)

    def _find_buddy(self, buddy):
        i = self._buddies.get(buddy)
        if not i:
            # Sometimes the same buddy has a different dbus instance,
            # so walk through the list
            nick = buddy.props.nick
            color = buddy.props.color
            for old_buddy in self._buddies.keys():
                if old_buddy.props.nick == nick and \
                   old_buddy.props.color == color:
                    i = self._buddies.get(old_buddy)
            if not i:  # No match, so add a new buddy
                self._add_buddy(buddy)
                i = self._buddies[buddy]
        return i

    def resize_buddy_list(self):
        """ maintain the buddy list width """
        size = min(BUDDIES_WIDTH, len(self._buddies) * BUDDY_SIZE)
        self._buddies_sw.set_size_request(size, BUDDY_SIZE)
        for buddy in self._buddies.values():
            buddy.set_size_request(BUDDY_SIZE, BUDDY_SIZE)

    def farewell(self, buddy):
        i = self._find_buddy(buddy)
        if not i:
            logger.debug('farewell: cannot find buddy %s' % buddy.props.nick)
            return

        self._buddies_box.remove(i)
        del self._buddies[buddy]
        self.resize_buddy_list()

    def shut_up(self):
        for i in self._buddies.values():
            i.shut_up()
        self.me.shut_up()

    def _add_buddy(self, buddy):
        self._buddies[buddy] = self._new_face(buddy, BUDDIES_COLOR)
        self._buddies_box.pack_start(self._buddies[buddy], True, True, 0)
        self.resize_buddy_list()

    def _activate_cb(self, widget, event):
        text = widget.get_buffer().props.text
        if text:
            self._chat.add_text(None, text)
            widget.get_buffer().props.text = ''
            if not self.quiet:
                self.me.say(text)
            if self.messenger:
                self.messenger.post(text)
        return True

    def _key_press_cb(self, widget, event):
        if event.keyval == Gdk.KEY_Return:
            if not (event.state & Gdk.ModifierType.CONTROL_MASK):
                return self._activate_cb(widget, event)
        return False

    def _new_face(self, buddy, color):
        colors = buddy.props.color.split(',')
        lighter = style.Color(colors[_lighter_color(colors)])

        buddy_face = face.View(lighter)
        # FIXME: omit set_border_state causes main face alignment problems
        buddy_face.set_border_state(False)
        # FIXME: non-me faces have no mouth

        buddy_face.show_all()

        return buddy_face

    def look_at(self):
        self.me.look_at()
        for i in self._buddies.values():
            i.look_at()

    def __open_on_journal(self, widget, url):
        '''Ask the journal to display a URL'''
        jobject = datastore.create()
        metadata = {
            'title': '%s: %s' % (_('URL from Speak'), url),
            'title_set_by_user': '******',
            'icon-color': profile.get_color().to_string(),
            'mime_type': 'text/uri-list',
        }
        for k, v in metadata.items():
            jobject.metadata[k] = v
        file_path = os.path.join(get_activity_root(), 'instance',
                                 '%i_' % time.time())
        open(file_path, 'w').write(url + '\r\n')
        os.chmod(file_path, 0755)
        jobject.set_file_path(file_path)
        datastore.write(jobject)
        show_object_in_journal(jobject.object_id)
        jobject.destroy()
        os.unlink(file_path)