Mercurial > libervia-backend
diff frontends/primitivus/chat.py @ 124:961e0898271f
primitivus chat window
- management of one 2 one / group chat
- timestamp displayed
- added shortcuts for showing/hiding panels
- color used
- fixed vcard bug (contact displayed even if not from current profile if vcard changed/not in cache)
- added VerticalSeparator widget
- *List widgets can now use an other widget than SelectableText
- new UnselectableText widget
author | Goffi <goffi@goffi.org> |
---|---|
date | Thu, 08 Jul 2010 19:47:54 +0800 |
parents | 1ca5f254ce41 |
children | 8d611eb9ae48 |
line wrap: on
line diff
--- a/frontends/primitivus/chat.py Thu Jul 08 18:29:44 2010 +0800 +++ b/frontends/primitivus/chat.py Thu Jul 08 19:47:54 2010 +0800 @@ -22,33 +22,169 @@ import urwid from quick_frontend.quick_contact_list import QuickContactList from quick_frontend.quick_chat import QuickChat -from custom_widgets import Password,List,InputDialog,ConfirmDialog,Alert,SelectableText,LabelLine,SurroundedText +import custom_widgets +import time +from tools.jid import JID + + +class ChatText(urwid.FlowWidget): + """Manage the printing of chat message""" + + def __init__(self, parent, timestamp, my_jid, from_jid, message, align='left'): + self.parent = parent + self.timestamp = time.localtime(timestamp) + self.my_jid = my_jid + self.from_jid = from_jid + self.message = unicode(message) + self.align = align + + def selectable(self): + return True + def keypress(self, size, key): + return key + + def rows(self,size,focus=False): + return self.display_widget(size, focus).rows(size, focus) + + def render(self, size, focus=False): + return self.display_widget(size, focus).render(size, focus) + + def display_widget(self, size, focus): + my_mess = (self.from_jid.resource == self.parent.nick) if self.parent.type == "group" else (self.from_jid.short == self.my_jid.short) #mymess = True if message comes from local user + render_txt = [] + if self.parent.show_timestamp: + time_format = "%c" if self.timestamp < self.parent.day_change else "%H:%M" #if the message was sent before today, we print the full date + render_txt.append(('date',"[%s]" % time.strftime(time_format, self.timestamp))) + if self.parent.show_short_nick: + render_txt.append(('my_nick' if my_mess else 'other_nick',"**" if my_mess else "*")) + else: + render_txt.append(('my_nick' if my_mess else 'other_nick',"[%s] " % self.from_jid)) + render_txt.append(self.message) + return urwid.Text(render_txt, align=self.align) class Chat(urwid.WidgetWrap, QuickChat): def __init__(self, target, host, type='one2one'): + self.target = target QuickChat.__init__(self, target, host, type) self.content = urwid.SimpleListWalker([]) self.text_list = urwid.ListBox(self.content) - main_widget = LabelLine( - urwid.Frame(self.text_list), SurroundedText(str(target)) - ) - urwid.WidgetWrap.__init__(self, main_widget) + self.chat_widget = urwid.Frame(self.text_list) + self.columns = urwid.Columns([('weight', 8, self.chat_widget)]) + urwid.WidgetWrap.__init__(self, self.__getDecoration(self.columns)) self.setType(type) - + self.day_change = time.strptime(time.strftime("%a %b %d 00:00:00 %Y")) #struct_time of day changing time + self.show_timestamp = True + self.show_short_nick = False + self.show_title = True + self.subject = None + + def keypress(self, size, key): + if key == "meta p": #user wants to (un)hide the presents panel + if self.type == 'group': + widgets = self.columns.widget_list + if self.present_panel in widgets: + self.__removePresentPanel() + else: + self.__appendPresentPanel() + elif key == "meta t": #user wants to (un)hide timestamp + self.show_timestamp = not self.show_timestamp + for wid in self.content: + wid._invalidate() + elif key == "meta n": #user wants to (not) use short nick + self.show_short_nick = not self.show_short_nick + for wid in self.content: + wid._invalidate() + elif key == "meta l": #user wants to (un)hide widget decoration + show = not self._w.__class__ == custom_widgets.LabelLine + self.showDecoration(show) + self._invalidate() + elif key == "meta s": #user wants to (un)hide group's subject + if self.subject: + self.show_title = not self.show_title + if self.show_title: + self.setSubject(self.subject) + else: + self.chat_widget.header = None + self._invalidate() + + + return super(Chat, self).keypress(size, key) + def setType(self, type): QuickChat.setType(self, type) if type == 'one2one': self.historyPrint(profile=self.host.profile) - + elif type == 'group': + if len(self.columns.widget_list) == 1: + present_widget = self.__buildPresentList() + self.present_panel = custom_widgets.VerticalSeparator(present_widget) + self.__appendPresentPanel() + + def __getDecoration(self, widget): + return custom_widgets.LabelLine(widget, custom_widgets.SurroundedText(unicode(self.target))) + + def showDecoration(self, show=True): + if show: + main_widget = self.__getDecoration(self.columns) + else: + main_widget = self.columns + self._w = main_widget + + + def __buildPresentList(self): + self.present_wid = custom_widgets.GenericList([],option_type = custom_widgets.UnselectableText) + return self.present_wid + + def __appendPresentPanel(self): + self.columns.widget_list.append(self.present_panel) + self.columns.column_types.append(('weight', 2)) + + def __removePresentPanel(self): + self.columns.set_focus(0) #necessary as the focus change to the next object, we can go out of range if we are on the last object of self.columns + self.columns.widget_list.remove(self.present_panel) + del self.columns.column_types[-1] + def setSubject(self, subject): """Set title for a group chat""" QuickChat.setSubject(self, subject) - self._w.base_widget.header = urwid.AttrMap(urwid.Text(unicode(subject),align='center'),'title') + self.subject = subject + self.chat_widget.header = urwid.AttrMap(urwid.Text(unicode(subject),align='center'),'title') + + def setPresents(self, param_nicks): + """Set the users presents in the contact list for a group chat + @param nicks: list of nicknames + """ + nicks = [unicode(nick) for nick in param_nicks] #FIXME: should be done in DBus bridge + nicks.sort() + QuickChat.setPresents(self, nicks) + self.present_wid.changeValues(nicks) + self.host.redraw() + def replaceUser(self, param_nick): + """Add user if it is not in the group list""" + nick = unicode(param_nick) #FIXME: should be done in DBus bridge + if "facebook" in nick: + self.host.debug() + QuickChat.replaceUser(self, nick) + presents = self.present_wid.getAllValues() + if nick not in presents: + presents.append(nick) + presents.sort() + self.present_wid.changeValues(presents) + self.host.redraw() + + def removeUser(self, param_nick): + """Remove a user from the group list""" + nick = unicode(param_nick) #FIXME: should be done in DBus bridge + QuickChat.removeUser(self, nick) + self.present_wid.deleteValue(nick) + self.host.redraw() def printMessage(self, from_jid, msg, profile, timestamp=""): - self.content.append(SelectableText("[%s] " % from_jid + msg)) + assert (from_jid.__class__ == JID) + my_jid = self.host.profiles[profile]['whoami'] + self.content.append(ChatText(self, timestamp or None, my_jid, from_jid, msg)) self.text_list.set_focus(len(self.content)-1) self.host.redraw()