Mercurial > libervia-backend
diff frontends/wix/main_window.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 | 8f2ed279784b |
children | 7322a41f8a8e |
line wrap: on
line diff
--- a/frontends/wix/main_window.py Sat Mar 06 14:57:23 2010 +1100 +++ b/frontends/wix/main_window.py Sun Mar 21 10:28:55 2010 +1100 @@ -22,9 +22,9 @@ from quick_frontend.quick_chat_list import QuickChatList from quick_frontend.quick_app import QuickApp -from quick_frontend.quick_contact_list import QuickContactList from quick_frontend.quick_contact_management import QuickContactManagement import wx +from contact_list import ContactList from chat import Chat from param import Param from form import Form @@ -35,14 +35,9 @@ import os.path import pdb from tools.jid import JID -from logging import debug, info, error -from cgi import escape -import sys +from logging import debug, info, warning, error +import constants -IMAGE_DIR = sys.path[0]+'/images' - -msgOFFLINE = "offline" -msgONLINE = "online" idCONNECT,\ idDISCONNECT,\ idEXIT,\ @@ -50,13 +45,8 @@ idADD_CONTACT,\ idREMOVE_CONTACT,\ idSHOW_PROFILE,\ -idFIND_GATEWAYS = range(8) -const_DEFAULT_GROUP = "Unclassed" -const_STATUS = [("", _("Online"), None), - ("chat", _("Free for chat"), "green"), - ("away", _("AFK"), "brown"), - ("dnd", _("DND"), "red"), - ("xa", _("Away"), "red")] +idJOIN_ROOM,\ +idFIND_GATEWAYS = range(9) class ChatList(QuickChatList): """This class manage the list of chat windows""" @@ -67,155 +57,6 @@ def createChat(self, target): return Chat(target, self.host) - -class ContactList(wx.SimpleHtmlListBox, QuickContactList): - """Customized control to manage contacts.""" - - def __init__(self, parent, CM): - wx.SimpleHtmlListBox.__init__(self, parent, -1) - QuickContactList.__init__(self, CM) - self.host = parent - 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 __find_idx(self, entity, reverse=False): - """Find indexes of given jid (or groups) in contact list - @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, jid): - debug(_("update %s") % jid) - if not self.__find_idx(jid): - self.add(jid) - else: - for i in self.__find_idx(jid): - self.SetString(i, self.__presentItem(jid)) - - def disconnect(self, jid): - self.remove(jid) #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)) == JID: - 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 __presentItem(self, jid): - """Make a nice presentation of the contact in the list.""" - 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, jid): - """add a contact to the list""" - debug (_("adding %s"),jid) - groups = self.CM.getAttr(jid, 'groups') - if not groups: - idx = self.Append(self.__presentItem(jid), jid) - 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) - else: - gp_idx = indexes[0] - - self.Insert(self.__presentItem(jid), gp_idx+1, jid) - - - - def remove(self, jid): - """remove a contact from the list""" - debug (_("removing %s"),jid) - list_idx = self.__find_idx(jid) - 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 type(data) == JID: - event.Skip() - else: - 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) - - 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) != JID: - return None - return data - - def registerActivatedCB(self, cb): - """Register a callback with manage contact activation.""" - self.onActivatedCB=cb - class MainWindow(wx.Frame, QuickApp): """main app window""" @@ -228,7 +69,7 @@ self.SetSizer(self.sizer) #Frame elements - self.contactList = ContactList(self, self.CM) + self.contactList = ContactList(self, self) self.contactList.registerActivatedCB(self.onContactActivated) self.contactList.Hide() self.sizer.Add(self.contactList, 1, flag=wx.EXPAND) @@ -296,6 +137,7 @@ contactMenu.AppendSeparator() contactMenu.Append(idSHOW_PROFILE, _("&Show profile"), _(" Show contact's profile")) communicationMenu = wx.Menu() + communicationMenu.Append(idJOIN_ROOM, _("&Join Room"),_(" Join a Multi-User Chat room")) communicationMenu.Append(idFIND_GATEWAYS, _("&Find Gateways"),_(" Find gateways to legacy IM")) self.menuBar = wx.MenuBar() self.menuBar.Append(connectMenu,_("&General")) @@ -311,12 +153,18 @@ wx.EVT_MENU(self, idADD_CONTACT, self.onAddContact) wx.EVT_MENU(self, idREMOVE_CONTACT, self.onRemoveContact) wx.EVT_MENU(self, idSHOW_PROFILE, self.onShowProfile) + wx.EVT_MENU(self, idJOIN_ROOM, self.onJoinRoom) wx.EVT_MENU(self, idFIND_GATEWAYS, self.onFindGateways) def newMessage(self, from_jid, msg, type, to_jid, profile): QuickApp.newMessage(self, from_jid, msg, type, to_jid, profile) + def roomJoined(self, room_id, room_service, room_nicks, user_nick, profile): + super(MainWindow, self).roomJoined(room_id, room_service, room_nicks, user_nick, profile) + self.chat_wins[room_id+'@'+room_service].setType("group") + self.chat_wins[room_id+'@'+room_service].setPresents([user_nick]+room_nicks) + def showAlert(self, message): # TODO: place this in a separate class popup=wx.PopupWindow(self) @@ -552,6 +400,9 @@ debug (_('Profile received: [%s]') % data) profile=Profile(self, data) + def onJoinRoom(self, e): + warning('FIXME: temporary menu, must be improved') + self.bridge.joinMUC("conference.necton2.int", "test", "Goffi \o/", self.profile) def onFindGateways(self, e): debug(_("Find Gateways request"))