Mercurial > libervia-backend
diff frontends/wix/main_window.py @ 51:8c67ea98ab91
frontend improved to take into account new SàT features
- quick_frontend: better use of contact management, it now manages nicks, avatars, and connected status
- quick_frontend: disconnect and remove are now 2 separate methods for contact list
- wix: new contact list using HTML items, and showing avatars. Groups are not showed for now
- wix: contact status now use tuples, to keep order, human readable status and color of contact
- wix: contact list is updated when avatar or nick is found
- wix: fixed 'question' dialog, which is renamed in 'yes/no'
- wix: action result are now ignored for unkwnown id
- sortilege refactored to work again
author | Goffi <goffi@goffi.org> |
---|---|
date | Thu, 07 Jan 2010 00:17:27 +1100 |
parents | 874de3020e1c |
children | 6455fb62ff83 |
line wrap: on
line diff
--- a/frontends/wix/main_window.py Thu Jan 07 00:05:15 2010 +1100 +++ b/frontends/wix/main_window.py Thu Jan 07 00:17:27 2010 +1100 @@ -34,24 +34,28 @@ from quick_frontend.quick_chat_list import QuickChatList from quick_frontend.quick_contact_list import QuickContactList from quick_frontend.quick_app import QuickApp +from quick_frontend.quick_contact_management import QuickContactManagement +from cgi import escape +import sys +IMAGE_DIR = sys.path[0]+'/images' msgOFFLINE = "offline" msgONLINE = "online" -idCONNECT = 1 -idDISCONNECT = 2 -idEXIT = 3 -idPARAM = 4 -idADD_CONTACT = 5 -idREMOVE_CONTACT = 6 -idSHOW_PROFILE = 7 -idFIND_GATEWAYS = 8 +idCONNECT,\ +idDISCONNECT,\ +idEXIT,\ +idPARAM,\ +idADD_CONTACT,\ +idREMOVE_CONTACT,\ +idSHOW_PROFILE,\ +idFIND_GATEWAYS = range(8) const_DEFAULT_GROUP = "Unclassed" -const_STATUS = {"Online":"", - "Want to discuss":"chat", - "AFK":"away", - "Do Not Disturb":"dnd", - "Away":"xa"} +const_STATUS = [("", "Online", None), + ("chat", "Free for chat", "green"), + ("away", "AFK", "brown"), + ("dnd", "DND", "red"), + ("xa", "Away", "red")] class ChatList(QuickChatList): """This class manage the list of chat windows""" @@ -59,100 +63,96 @@ def __init__(self, host): QuickChatList.__init__(self, host) - def createChat(self, name): - return Chat(name, self.host) + def createChat(self, target): + return Chat(target, self.host) - -class ContactList(wx.TreeCtrl, QuickContactList): +class ContactList(wx.SimpleHtmlListBox, QuickContactList): """Customized control to manage contacts.""" - def __init__(self, parent): - wx.TreeCtrl.__init__(self, parent, style = wx.TR_HIDE_ROOT | wx.TR_HAS_BUTTONS) - QuickContactList.__init__(self) - self.jid_ids={} - self.groups={} - self.root=self.AddRoot("") - self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.onActivated, self) + def __init__(self, parent, CM): + wx.SimpleHtmlListBox.__init__(self, parent, -1) + QuickContactList.__init__(self, CM) + self.host = parent + self.Bind(wx.EVT_LISTBOX_DCLICK, self.onActivated) - #icons - isz = (16,16) - il = wx.ImageList(isz[0], isz[1]) - self.icon_online = il.Add(wx.ArtProvider_GetBitmap(wx.ART_TICK_MARK, wx.ART_OTHER, isz)) - self.icon_unavailable = il.Add(wx.ArtProvider_GetBitmap(wx.ART_CROSS_MARK, wx.ART_OTHER, isz)) - self.AssignImageList(il) + def __find_idx(self, jid, reverse=False): + """Find indexes of given jid in contact list + @return: list of indexes""" + result=[] + for i in range(self.GetCount()): + if self.GetClientData(i).short == jid.short: + result.append(i) + return result - self.__addNode(const_DEFAULT_GROUP) + 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 __addNode(self, label): - """Add an item container""" - ret=self.AppendItem(self.root, label) - self.SetPyData(ret, "[node]") - self.SetItemBold(ret) - self.groups[label]=ret + def disconnect(self, jid): + self.remove(jid) #for now, we only show online contacts - def replace(self, jid, name="", show="", status="", group=""): - debug("status = %s show = %s",status, show) - if not self.jid_ids.has_key(jid): - self.add(jid, name, show, status, group) - else: - debug ("updating %s",jid) - self.__presentItem(jid, name, show, status, group) - - def __presentItem(self, jid, name, show, status, group): + def __presentItem(self, jid): """Make a nice presentation of the contact in the list.""" - id=self.jid_ids[jid] - label= "%s [%s] \n %s" % ((name or jid), (show or "online"), status) - self.SetItemText(id, label) + 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)) - # icon - if not show or show=="chat": - self.SetItemImage(id, self.icon_online) - else: - self.SetItemImage(id, self.icon_unavailable) + return html - #colour - if not show: - self.SetItemTextColour(id, wx.BLACK) - elif show=="chat": - self.SetItemTextColour(id, wx.GREEN) - elif show=="away": - self.SetItemTextColour(id, wx.BLUE) - else: - self.SetItemTextColour(id, wx.RED) - - def add(self, jid, name="", show="", status="", group=""): + def add(self, jid): """add a contact to the list""" debug ("adding %s",jid) - dest_group=group or const_DEFAULT_GROUP - if not self.groups.has_key(dest_group): - self.__addNode(dest_group) - self.jid_ids[jid]=self.AppendItem(self.groups[dest_group], "") - self.__presentItem(jid, name, show, status, group) - self.SetPyData(self.jid_ids[jid], "[contact]"+jid) - self.EnsureVisible(self.jid_ids[jid]) - self.Refresh() #FIXME: Best way ? + idx = self.Append(self.__presentItem(jid)) + + self.SetClientData(idx, jid) def remove(self, jid): """remove a contact from the list""" debug ("removing %s",jid) - self.Delete(self.jid_ids[jid]) - del self.jid_ids[jid] - self.Refresh() #FIXME: Best way ? + 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 onActivated(self, event): """Called when a contact is clicked or activated with keyboard.""" - if self.GetPyData(event.GetItem()).startswith("[contact]"): - self.onActivatedCB(self.GetPyData(event.GetItem())[9:]) - else: - event.Skip() + data = self.getSelection() + self.onActivatedCB(data) + event.Skip() def getSelection(self): """Return the selected contact, or an empty string if there is not""" - data = self.GetPyData(self.GetSelection()) - if not data or not data.startswith("[contact]"): - return "" - return JID(data[9:]) + if self.GetSelection() == wx.NOT_FOUND: + return "" #FIXME: gof: à améliorer + data = self.GetClientData(self.GetSelection()) + return data def registerActivatedCB(self, cb): """Register a callback with manage contact activation.""" @@ -163,10 +163,11 @@ def __init__(self): wx.Frame.__init__(self,None, title="SAT Wix", size=(400,200)) + self.CM = QuickContactManagement() #gof: #Frame elements - self.contactList = ContactList(self) + self.contactList = ContactList(self, self.CM) self.contactList.registerActivatedCB(self.onContactActivated) self.chat_wins=ChatList(self) self.CreateStatusBar() @@ -175,7 +176,7 @@ #ToolBar self.tools=self.CreateToolBar() - self.statusBox = wx.ComboBox(self.tools, -1, "Online", choices=const_STATUS.keys(), + self.statusBox = wx.ComboBox(self.tools, -1, "Online", choices=[status[1] for status in const_STATUS], style=wx.CB_DROPDOWN | wx.CB_READONLY) self.tools.AddControl(self.statusBox) self.tools.AddSeparator() @@ -186,7 +187,7 @@ self.tools.Disable() #tray icon - ticon = wx.Icon("images/tray_icon.xpm", wx.BITMAP_TYPE_XPM) + ticon = wx.Icon(IMAGE_DIR+'/crystal/tray_icon.xpm', wx.BITMAP_TYPE_XPM) self.tray_icon = wx.TaskBarIcon() self.tray_icon.SetIcon(ticon, "Wix jabber client") wx.EVT_TASKBAR_LEFT_UP(self.tray_icon, self.onTrayClick) @@ -252,10 +253,11 @@ flags = wx.OK | wx.ICON_INFORMATION elif type == 'error': flags = wx.OK | wx.ICON_ERROR - elif type == 'question': - flags = wx.OK | wx.ICON_QUESTION + elif type == 'yes/no': + flags = wx.YES_NO | wx.ICON_QUESTION else: flags = wx.OK | wx.ICON_INFORMATION + error('unmanaged dialog type: %s', type) dlg = wx.MessageDialog(self, message, title, flags) answer = dlg.ShowModal() dlg.Destroy() @@ -272,8 +274,8 @@ return - def presenceUpdate(self, jabber_id, type, show, status, priority): - QuickApp.presenceUpdate(self, jabber_id, type, show, status, priority) + def presenceUpdate(self, jabber_id, show, priority, statuses): + QuickApp.presenceUpdate(self, jabber_id, show, priority, statuses) def askConfirmation(self, type, id, data): #TODO: refactor this in QuickApp @@ -315,6 +317,9 @@ def actionResult(self, type, id, data): debug ("actionResult: type = [%s] id = [%s] data = [%s]" % (type, id, data)) + if not id in self.current_action_ids: + debug ('unknown id, ignoring') + return if type == "SUPPRESS": self.current_action_ids.remove(id) elif type == "SUCCESS": @@ -349,7 +354,6 @@ callback = self.current_action_ids_cb[id] del self.current_action_ids_cb[id] callback(data) - print ("Dict of dict found as result") else: error ("FIXME FIXME FIXME: type [%s] not implemented" % type) raise NotImplementedError @@ -384,10 +388,10 @@ def onContactActivated(self, jid): debug ("onContactActivated: %s", jid) - if self.chat_wins[jid].IsShown(): - self.chat_wins[jid].Hide() + if self.chat_wins[jid.short].IsShown(): + self.chat_wins[jid.short].Hide() else: - self.chat_wins[jid].Show() + self.chat_wins[jid.short].Show() def onConnectRequest(self, e): self.bridge.connect() @@ -396,9 +400,9 @@ self.bridge.disconnect() def __updateStatus(self): - show = const_STATUS[self.statusBox.GetValue()] + show = filter(lambda x:x[1] == self.statusBox.GetValue(), const_STATUS)[0][0] status = self.statusTxt.GetValue() - self.bridge.setPresence(show=show, status=status) + self.bridge.setPresence(show=show, statuses={'default':status}) #FIXME: manage multilingual statuses def onStatusChange(self, e): debug("Status change request") @@ -445,7 +449,7 @@ ) if dlg.ShowModal() == wx.ID_YES: - info("Unsubsribing %s presence", target.short) + info("Unsubscribing %s presence", target.short) self.bridge.delContact(target.short) dlg.Destroy() @@ -476,7 +480,6 @@ id = self.bridge.findGateways(self.whoami.domain) self.current_action_ids.add(id) self.current_action_ids_cb[id] = self.onGatewaysFound - print "Find Gateways id=", id def onGatewaysFound(self, data): """Called when SàT has found the server gateways"""