Mercurial > libervia-backend
diff frontends/wix/contact_list.py @ 72:f271fff3a713
MUC implementation: first draft
/!\ the experimental muc branche of wokkel must be used
- bridge: new roomJoined signal
- wix: contact list widget is now in a separate file, and manage different kinds of presentation
- wix: chat window now manage group chat (first draft, not working yet)
- wix: constants are now in a separate class, so then can be accessible from everywhere
- wix: new menu to join room (do nothing yet, except entering in a test room)
- new plugin for xep 0045 (MUC), use wokkel experimental MUC branch
- plugins: the profile is now given for get_handler, cause it can be used internally by a plugin (e.g.: xep-0045 plugin)
author | Goffi <goffi@goffi.org> |
---|---|
date | Sun, 21 Mar 2010 10:28:55 +1100 |
parents | |
children | 7322a41f8a8e |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/frontends/wix/contact_list.py Sun Mar 21 10:28:55 2010 +1100 @@ -0,0 +1,179 @@ +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 __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' + + #XXX: yes table I know :) but wxHTML* doesn't support CSS + 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() #we me 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 +