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 __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)
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()
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()
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)
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)
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()
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)