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"))