Mercurial > libervia-backend
view frontends/wix/contact_list.py @ 125:8d611eb9ae48
primitivus: contact list enhancement
- primitivus: contact list now display groups and sexy name (instead of bare jid)
- primitivus: contact list now show an alert when somebody want to contact you, and its chat window is not on the screen
- primitivus: cursor is now visible when going to chat window (useful to go back in logs)
author | Goffi <goffi@goffi.org> |
---|---|
date | Mon, 12 Jul 2010 17:50:00 +0800 |
parents | 961e0898271f |
children | 2f8c86488b05 |
line wrap: on
line source
import wx from quick_frontend.quick_contact_list import QuickContactList from logging import debug, info, error from cgi import escape from tools.jid import JID class Group(str): """Class used to recognize groups""" class Contact(str): """Class used to recognize groups""" class ContactList(wx.SimpleHtmlListBox, QuickContactList): """Customized control to manage contacts.""" def __init__(self, parent, host, type="JID"): """init the contact list @param parent: WxWidgets parent of the widget @param host: wix main app class @param type: type of contact list: "JID" for the usual big jid contact list "CUSTOM" for a customized contact list (self.__presentItem must then be overrided) """ wx.SimpleHtmlListBox.__init__(self, parent, -1) QuickContactList.__init__(self, host.CM) self.host = host self.type = type self.__typeSwitch() self.groups = {} #list contacts in each groups, key = group self.Bind(wx.EVT_LISTBOX, self.onSelected) self.Bind(wx.EVT_LISTBOX_DCLICK, self.onActivated) def __contains__(self, jid): return bool(self.__find_idx(jid)) def __typeSwitch(self): if self.type == "JID": self.__presentItem = self.__presentItemJID elif type != "CUSTOM": self.__presentItem = self.__presentItemDefault def __find_idx(self, entity): """Find indexes of given contact (or groups) in contact list, manage jid @return: list of indexes""" result=[] for i in range(self.GetCount()): if (type(entity) == JID and type(self.GetClientData(i)) == JID and self.GetClientData(i).short == entity.short) or\ self.GetClientData(i) == entity: result.append(i) return result def replace(self, contact, groups=None): debug(_("update %s") % contact) if not self.__find_idx(contact): self.add(contact, groups) else: for i in self.__find_idx(contact): self.SetString(i, self.__presentItem(contact)) def disconnect(self, contact): self.remove(contact) #for now, we only show online contacts def __eraseGroup(self, group): """Erase all contacts in group @param group: group to erase @return: True if something as been erased""" erased = False indexes = self.__find_idx(group) for idx in indexes: while idx<self.GetCount()-1 and type(self.GetClientData(idx+1)) != Group: erased = True self.Delete(idx+1) return erased def __presentGroup(self, group): """Make a nice presentation for the contact groups""" html = """-- [%s] --""" % group return html def __presentItemDefault(self, contact): """Make a basic presentation of string contacts in the list.""" return contact def __presentItemJID(self, jid): """Make a nice presentation of the contact in the list for JID contacts.""" name = self.CM.getAttr(jid,'name') nick = self.CM.getAttr(jid,'nick') show = filter(lambda x:x[0]==self.CM.getAttr(jid,'show'), const_STATUS)[0] #show[0]==shortcut #show[1]==human readable #show[2]==color (or None) show_html = "<font color='%s'>[%s]</font>" % (show[2], show[1]) if show[2] else "" status = self.CM.getAttr(jid,'status') or '' avatar = self.CM.getAttr(jid,'avatar') or IMAGE_DIR+'/empty_avatar.png' html = """ <table border='0'> <td> <img height='64' width='64' src='%s' /> </td> <td> <b>%s</b> %s<br /> <i>%s</i> </td> </table> """ % (avatar, escape(nick or name or jid.node or jid.short), show_html, escape(status)) return html def clear_contacts(self): """Clear all the contact list""" self.Clear() def add(self, contact, groups = None): """add a contact to the list""" debug (_("adding %s"),contact) #gof: groups = param_groups or self.CM.getAttr(jid, 'groups') if not groups: idx = self.Insert(self.__presentItem(contact), 0, contact) else: for group in groups: indexes = self.__find_idx(group) gp_idx = 0 if not indexes: #this is a new group, we have to create it gp_idx = self.Append(self.__presentGroup(group), Group(group)) else: gp_idx = indexes[0] self.Insert(self.__presentItem(contact), gp_idx+1, contact) def remove(self, contact): """remove a contact from the list""" debug (_("removing %s"), contact) list_idx = self.__find_idx(contact) list_idx.reverse() #as we make some deletions, we have to reverse the order for i in list_idx: self.Delete(i) def onSelected(self, event): """Called when a contact is selected.""" data = self.getSelection() if data == None: #we have a group group = self.GetClientData(self.GetSelection()) erased = self.__eraseGroup(group) if not erased: #the group was already erased, we can add again the contacts contacts = self.CM.getContFromGroup(group) contacts.sort() id_insert = self.GetSelection()+1 for contact in contacts: self.Insert(self.__presentItem(contact), id_insert, contact) self.SetSelection(wx.NOT_FOUND) event.Skip(False) else: event.Skip() def onActivated(self, event): """Called when a contact is clicked or activated with keyboard.""" data = self.getSelection() self.onActivatedCB(data) event.Skip() def getSelection(self): """Return the selected contact, or an empty string if there is not""" if self.GetSelection() == wx.NOT_FOUND: return None data = self.GetClientData(self.GetSelection()) if type(data) == Group: return None return data def registerActivatedCB(self, cb): """Register a callback with manage contact activation.""" self.onActivatedCB=cb