diff --git a/frontends/quick_frontend/quick_app.py b/frontends/quick_frontend/quick_app.py
index c6d4e8d8..909457da 100644
--- a/frontends/quick_frontend/quick_app.py
+++ b/frontends/quick_frontend/quick_app.py
@@ -22,23 +22,23 @@ along with this program. If not, see .
from logging import debug, info, error
from tools.jid import JID
from sat_bridge_frontend.DBus import DBusBridgeFrontend
-from quick_frontend.quick_contact_management import QuickContactManagement
-
+import pdb
class QuickApp():
"""This class contain the main methods needed for the frontend"""
def __init__(self):
self.rosterList = {}
- self.CM = QuickContactManagement() #a short name if more handy
## bridge ##
self.bridge=DBusBridgeFrontend()
self.bridge.register("newContact", self.newContact)
self.bridge.register("newMessage", self.newMessage)
self.bridge.register("presenceUpdate", self.presenceUpdate)
+ self.bridge.register("subscribe", self.subscribe)
self.bridge.register("paramUpdate", self.paramUpdate)
self.bridge.register("contactDeleted", self.contactDeleted)
+ self.bridge.register("updatedValue", self.updatedValue, "request")
self.bridge.register("askConfirmation", self.askConfirmation, "request")
self.bridge.register("actionResult", self.actionResult, "request")
self.bridge.register("actionResultExt", self.actionResult, "request")
@@ -59,13 +59,23 @@ class QuickApp():
for contact in self.bridge.getContacts():
self.newContact(contact[0], contact[1], contact[2])
- for status in self.bridge.getPresenceStatus():
- self.presenceUpdate(status[0], status[1], status[2], status[3], status[4])
+ presences = self.bridge.getPresenceStatus()
+ for contact in presences:
+ for res in presences[contact]:
+ jabber_id = contact+('/'+res if res else '')
+ show = presences[contact][res][0]
+ priority = presences[contact][res][1]
+ statuses = presences[contact][res][2]
+ self.presenceUpdate(jabber_id, show, priority, statuses)
+
+ waitingSub = self.bridge.getWaitingSub()
+ for sub in waitingSub:
+ self.subscribe(waitingSub[sub], sub)
def newContact(self, JabberId, attributes, groups):
- jid=JID(JabberId)
- self.rosterList[jid.short]=(dict(attributes), list(groups))
+ entity=JID(JabberId)
+ self.rosterList[entity.short]=(dict(attributes), list(groups))
def newMessage(self, from_jid, msg, type, to_jid):
sender=JID(from_jid)
@@ -76,64 +86,66 @@ class QuickApp():
def setStatusOnline(self, online=True):
pass
- def presenceUpdate(self, jabber_id, type, show, status, priority):
- debug ("presence update for %s (type=%s, show=%s, status=%s)", jabber_id, type, show, status);
- jid=JID(jabber_id)
- debug ("jid.short=%s whoami.short=%s", jid.short, self.whoami.short)
+ def presenceUpdate(self, jabber_id, show, priority, statuses):
+ debug ("presence update for %s (show=%s, statuses=%s)", jabber_id, show, statuses);
+ from_jid=JID(jabber_id)
+ debug ("from_jid.short=%s whoami.short=%s", from_jid.short, self.whoami.short)
- ### subscription management ###
- if type=="subscribed":
- # this is a subscription confirmation, we just have to inform user
- self.showDialog("The contact %s has accepted your subscription" % jid.short, 'Subscription confirmation')
- return
- elif type=="unsubscribed":
- # this is a subscription refusal, we just have to inform user
- self.showDialog("The contact %s has refused your subscription" % jid.short, 'Subscription refusal', 'error')
- return
- elif type=="subscribe":
- # this is a subscrition request, we have to ask for user confirmation
- answer = self.showDialog("The contact %s wants to subscribe to your presence.\nDo you accept ?" % jid.short, 'Subscription confirmation', 'question')
- if answer:
- self.bridge.setPresence(type="subscribed", to=jid.short)
- else:
- self.bridge.setPresence(type="unsubscribed", to=jid.short)
- return
- ### subscription management end ###
-
- if jid.short==self.whoami.short:
+ if from_jid.short==self.whoami.short:
if not type:
self.setStatusOnline(True)
elif type=="unavailable":
self.setStatusOnline(False)
return
- if not type:
+ if show != 'unavailable':
name=""
group=""
- if self.rosterList.has_key(jid.short):
- if self.rosterList[jid.short][0].has_key("name"):
- name=self.rosterList[jid.short][0]["name"]
- if self.rosterList[jid.short][0].has_key("show"):
- name=self.rosterList[jid.short][0]["show"]
- if self.rosterList[jid.short][0].has_key("status"):
- name=self.rosterList[jid.short][0]["status"]
- if len(self.rosterList[jid.short][1]):
- group=self.rosterList[jid.short][1][0]
+ if self.rosterList.has_key(from_jid.short):
+ if self.rosterList[from_jid.short][0].has_key("name"):
+ name=self.rosterList[from_jid.short][0]["name"]
+ if len(self.rosterList[from_jid.short][1]):
+ group=self.rosterList[from_jid.short][1][0]
#FIXME: must be moved in a plugin
- if jid.short in self.watched and not jid.short in self.onlineContact:
- self.showAlert("Watched jid [%s] is connected !" % jid.short)
+ if from_jid.short in self.watched and not from_jid.short in self.onlineContact:
+ self.showAlert("Watched jid [%s] is connected !" % from_jid.short)
- self.onlineContact.add(jid) #FIXME onlineContact is useless with CM, must be removed
- self.CM.add(jid)
- self.contactList.replace(jid, show=show, status=status, name=name, group=group)
+ self.onlineContact.add(from_jid) #FIXME onlineContact is useless with CM, must be removed
+ self.CM.add(from_jid)
+ self.CM.update(from_jid, 'name', name)
+ self.CM.update(from_jid, 'show', show)
+ self.CM.update(from_jid, 'statuses', statuses)
+ self.CM.update(from_jid, 'group', group)
+ cache = self.bridge.getProfileCache(from_jid)
+ if cache.has_key('nick'):
+ self.CM.update(from_jid, 'nick', cache['nick'])
+ if cache.has_key('avatar'):
+ self.CM.update(from_jid, 'avatar', self.bridge.getAvatarFile(cache['avatar']))
+ self.contactList.replace(from_jid)
+ if show=="unavailable" and from_jid in self.onlineContact:
+ self.onlineContact.remove(from_jid)
+ self.CM.remove(from_jid)
+ if not self.CM.isConnected(from_jid):
+ self.contactList.disconnect(from_jid)
- if type=="unavailable" and jid in self.onlineContact:
- self.onlineContact.remove(jid)
- self.CM.remove(jid)
- self.contactList.remove(jid)
-
+ def subscribe(self, type, raw_jid):
+ """Called when a subsciption maangement signal is received"""
+ entity = JID(raw_jid)
+ if type=="subscribed":
+ # this is a subscription confirmation, we just have to inform user
+ self.showDialog("The contact %s has accepted your subscription" % entity.short, 'Subscription confirmation')
+ elif type=="unsubscribed":
+ # this is a subscription refusal, we just have to inform user
+ self.showDialog("The contact %s has refused your subscription" % entity.short, 'Subscription refusal', 'error')
+ elif type=="subscribe":
+ # this is a subscriptionn request, we have to ask for user confirmation
+ answer = self.showDialog("The contact %s wants to subscribe to your presence.\nDo you accept ?" % entity.short, 'Subscription confirmation', 'yes/no')
+ if answer:
+ self.bridge.subscription("subscribed", entity.short)
+ else:
+ self.bridge.subscribed("unsubscribed", entity.short)
def showDialog(self, message, title, type="info"):
raise NotImplementedError
@@ -151,13 +163,26 @@ class QuickApp():
def contactDeleted(self, jid):
target = JID(jid)
+ self.CM.remove(target)
+ self.contactList.remove(self.CM.get_full(target))
try:
self.onlineContact.remove(target.short)
except KeyError:
pass
- self.contactList.remove(self.CM.get_full(jid))
- self.CM.remove(target)
-
+
+ def updatedValue(self, name, data):
+ print "toto"
+ print "updatedValue", name, data
+ if name == "profile_nick":
+ target = JID(data['jid'])
+ self.CM.update(target, 'nick', data['nick'])
+ self.contactList.replace(target)
+ elif name == "profile_avatar":
+ target = JID(data['jid'])
+ filename = self.bridge.getAvatarFile(data['avatar'])
+ self.CM.update(target, 'avatar', filename)
+ self.contactList.replace(target)
+
def askConfirmation(self, type, id, data):
raise NotImplementedError
diff --git a/frontends/quick_frontend/quick_chat_list.py b/frontends/quick_frontend/quick_chat_list.py
index da05131b..d6406bcc 100644
--- a/frontends/quick_frontend/quick_chat_list.py
+++ b/frontends/quick_frontend/quick_chat_list.py
@@ -30,12 +30,12 @@ class QuickChatList(dict):
dict.__init__(self)
self.host = host
- def __getitem__(self,name_param):
- name=JID(name_param).short
- if not self.has_key(name):
+ def __getitem__(self,to_jid):
+ target=JID(to_jid)
+ if not self.has_key(target.short):
#we have to create the chat win
- self[name] = self.createChat(name)
- return dict.__getitem__(self,name)
+ self[target.short] = self.createChat(target)
+ return dict.__getitem__(self,target.short)
- def createChat(self, name):
+ def createChat(self, target):
raise NotImplementedError
diff --git a/frontends/quick_frontend/quick_contact_list.py b/frontends/quick_frontend/quick_contact_list.py
index 401a37e5..eb333ab5 100644
--- a/frontends/quick_frontend/quick_contact_list.py
+++ b/frontends/quick_frontend/quick_contact_list.py
@@ -24,19 +24,27 @@ from tools.jid import JID
class QuickContactList():
+ """This class manage the visual representation of contacts"""
- def __init__(self):
+ def __init__(self, CM):
+ """
+ @param CM: instance of QuickContactManagement
+ """
debug("Contact List init")
- self.jid_ids={}
+ self.CM = CM
- def replace(self, jid, name="", show="", status="", group=""):
- """add a contact to the list"""
+ def replace(self, jid):
+ """add a contact to the list if doesn't exist, else update it"""
+ raise NotImplementedError
+
+ def disconnect(self, jid):
+ """mark a contact disconnected"""
raise NotImplementedError
def remove(self, jid):
"""remove a contact from the list"""
raise NotImplementedError
- def add(self, jid, name="", show="", status="", group=""):
+ def add(self, jid):
"""add a contact to the list"""
raise NotImplementedError
diff --git a/frontends/quick_frontend/quick_contact_management.py b/frontends/quick_frontend/quick_contact_management.py
index 8329d021..266c9870 100644
--- a/frontends/quick_frontend/quick_contact_management.py
+++ b/frontends/quick_frontend/quick_contact_management.py
@@ -19,29 +19,68 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
"""
-from logging import debug, info, error
+from logging import debug, info, warning, error
from tools.jid import JID
import pdb
class QuickContactManagement():
"""This helper class manage the contacts and ease the use of nicknames and shortcuts"""
+ ### FIXME: is SàT a better place for all this stuff ??? ###
def __init__(self):
self.__contactlist = {}
- def add(self, jid_param):
- jid=JID(jid_param)
- self.__contactlist[jid.short] = {'name':jid, 'last_resource':jid.resource}
+ def add(self, entity):
+ """Add contact to the list, update resources"""
+ if not self.__contactlist.has_key(entity.short):
+ self.__contactlist[entity.short] = {'resources':[]}
+ if entity.resource in self.__contactlist[entity.short]['resources']:
+ self.__contactlist[entity.short]['resources'].remove(entity.resource)
+ self.__contactlist[entity.short]['resources'].append(entity.resource)
- def remove(self, jid_param):
- jid=JID(jid_param)
+ def getAttr(self, entity, name):
+ """Return a specific attribute of contact, or all attributes
+ @param entity: jid of the contact
+ @param name: name of the attribute
+ @return: asked attribute"""
+ if self.__contactlist.has_key(entity.short):
+ if name == 'status': #FIXME: for the moment, we only use the first status
+ if self.__contactlist[entity.short]['statuses']:
+ return self.__contactlist[entity.short]['statuses'].values()[0]
+ if self.__contactlist[entity.short].has_key(name):
+ return self.__contactlist[entity.short][name]
+ else:
+ debug('Trying to get attribute for an unknown contact')
+ return None
+
+ def isConnected(self, entity):
+ """Tell if the contact is online"""
+ print "is connected (%s): %s" %(entity, str(self.__contactlist.has_key(entity.short))) #gof
+ return self.__contactlist.has_key(entity.short)
+
+ def remove(self, entity):
+ """remove resource. If no more resource is online or is no resource is specified, contact is deleted"""
try:
- del self.__contactlist[jid.short]
+ if entity.resource:
+ self.__contactlist[entity.short]['resources'].remove(entity.resource)
+ if not entity.resource or not self.__contactlist[entity.short]['resources']:
+ #no more resource available: the contact seems really disconnected
+ del self.__contactlist[entity.short]
except KeyError:
pass
- def get_full(self, jid_param):
- jid=JID(jid_param)
- return jid.short+'/'+self.__contactlist[jid.short]['last_resource']
+ def update(self, entity, key, value):
+ """Update attribute of contact
+ @param entity: jid of the contact
+ @param key: name of the attribute
+ @param value: value of the attribute
+ """
+ if self.__contactlist.has_key(entity.short):
+ self.__contactlist[entity.short][key] = value
+ else:
+ debug ('Trying to update an uknown contact: %s', entity.short)
+
+ def get_full(self, entity):
+ return entity.short+'/'+self.__contactlist[entity.short]['resources'][-1]
diff --git a/frontends/sat_bridge_frontend/DBus.py b/frontends/sat_bridge_frontend/DBus.py
index ec855d13..646fa9f1 100755
--- a/frontends/sat_bridge_frontend/DBus.py
+++ b/frontends/sat_bridge_frontend/DBus.py
@@ -52,6 +52,9 @@ class DBusBridgeFrontend(BridgeFrontend):
def getPresenceStatus(self):
return self.db_comm_iface.getPresenceStatus()
+ def getWaitingSub(self):
+ return self.db_comm_iface.getWaitingSub()
+
def sendMessage(self, to, message):
return self.db_comm_iface.sendMessage(to, message)
@@ -64,14 +67,20 @@ class DBusBridgeFrontend(BridgeFrontend):
def getProfile(self, target):
return self.db_comm_iface.getProfile(target)
+ def getProfileCache(self, target):
+ return self.db_comm_iface.getProfileCache(target)
+
def getAvatarFile(self, hash):
return self.db_comm_iface.getAvatarFile(hash)
def in_band_register(self, target):
return self.db_comm_iface.in_band_register(target)
- def setPresence(self, to="", type="", show="", status="", priority=0):
- return self.db_comm_iface.setPresence(to, type, show, status, priority)
+ def setPresence(self, to="", show="", priority=0, statuses={}):
+ return self.db_comm_iface.setPresence(to, show, priority, statuses)
+
+ def subscription(self, type, entity):
+ return self.db_comm_iface.subscription(type, entity)
def setParam(self, name, value, category):
return self.db_comm_iface.setParam(name, value, category)
diff --git a/frontends/sortilege/sortilege b/frontends/sortilege/sortilege
index 7257760c..99eb50f3 100755
--- a/frontends/sortilege/sortilege
+++ b/frontends/sortilege/sortilege
@@ -43,6 +43,7 @@ from boxsizer import BoxSizer
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
### logging configuration FIXME: put this elsewhere ###
logging.basicConfig(level=logging.CRITICAL, #TODO: configure it top put messages in a log file
@@ -80,8 +81,10 @@ class ChatList(QuickChatList):
class ContactList(Window, QuickContactList):
- def __init__(self):
- QuickContactList.__init__(self)
+ def __init__(self, host, CM):
+ QuickContactList.__init__(self, CM)
+ self.host = host
+ self.jid_list = []
self.__index=0 #indicate which contact is selected (ie: where we are)
Window.__init__(self, stdscr, stdscr.getmaxyx()[0]-2,const_CONTACT_WIDTH,0,0, True, "Contact List", code=code)
@@ -98,14 +101,15 @@ class ContactList(Window, QuickContactList):
def registerEnterCB(self, CB):
self.__enterCB=CB
- def replace(self, jid, name="", show="", status="", group=""):
+ def replace(self, jid):
"""add a contact to the list"""
- self.jid_ids[jid] = name or jid
+ name = self.CM.getAttr(jid,'name')
+ self.jid_list.append(jid.short)
self.update()
def indexUp(self):
"""increment select contact index"""
- if self.__index < len(self.jid_ids)-1: #we dont want to select a missing contact
+ if self.__index < len(self.jid_list)-1: #we dont want to select a missing contact
self.__index = self.__index + 1
self.update()
@@ -115,11 +119,15 @@ class ContactList(Window, QuickContactList):
self.__index = self.__index - 1
self.update()
+ def disconnect(self, jid):
+ """for now, we just remove the contact"""
+ self.remove(jid)
+
def remove(self, jid):
"""remove a contact from the list"""
- del self.jid_ids[jid]
- if self.__index >= len(self.jid_ids) and self.__index > 0: #if select index is out of border, we put it on the last contact
- self.__index = len(self.jid_ids)-1
+ self.jid_list.remove(jid.short)
+ if self.__index >= len(self.jid_list) and self.__index > 0: #if select index is out of border, we put it on the last contact
+ self.__index = len(self.jid_list)-1
self.update()
def update(self):
@@ -127,13 +135,10 @@ class ContactList(Window, QuickContactList):
if self.isHidden():
return
Window.update(self)
- viewList=[]
- for jid in self.jid_ids:
- viewList.append(self.jid_ids[jid])
- viewList.sort()
+ self.jid_list.sort()
begin=0 if self.__index ", self.code)
self.editBar.activate(False)
self.statusBar = StatusBar(stdscr, self.code)
@@ -237,10 +243,10 @@ class SortilegeApp(QuickApp):
def showChat(self, chat):
debug ("show chat")
if self.currentChat:
- debug ("hide de %s", self.currentChat)
+ debug ("hiding %s", self.currentChat)
self.chat_wins[self.currentChat].hide()
self.currentChat=chat
- debug ("show de %s", self.currentChat)
+ debug ("showing %s", self.currentChat)
self.chat_wins[self.currentChat].show()
self.chat_wins[self.currentChat].update()
@@ -268,8 +274,8 @@ class SortilegeApp(QuickApp):
pass
- 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)
self.editBar.replace_cur()
curses.doupdate()
diff --git a/frontends/wix/main_window.py b/frontends/wix/main_window.py
index bb631fcf..f1265f12 100644
--- a/frontends/wix/main_window.py
+++ b/frontends/wix/main_window.py
@@ -34,24 +34,28 @@ from logging import debug, info, error
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 @@ class ChatList(QuickChatList):
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 __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 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)
+ def replace(self, jid):
+ debug("update %s" % jid)
+ if not self.__find_idx(jid):
+ self.add(jid)
else:
- debug ("updating %s",jid)
- self.__presentItem(jid, name, show, status, group)
+ for i in self.__find_idx(jid):
+ self.SetString(i, self.__presentItem(jid))
- def __presentItem(self, jid, name, show, status, group):
+ def disconnect(self, jid):
+ self.remove(jid) #for now, we only show online contacts
+
+ 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 = "[%s]" % (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 = """
+
+
+
+ |
+
+ %s %s
+ %s
+ |
+
+ """ % (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 @@ class MainWindow(wx.Frame, QuickApp):
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 @@ class MainWindow(wx.Frame, QuickApp):
#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 @@ class MainWindow(wx.Frame, QuickApp):
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 @@ class MainWindow(wx.Frame, QuickApp):
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 @@ class MainWindow(wx.Frame, QuickApp):
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 @@ class MainWindow(wx.Frame, QuickApp):
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 @@ class MainWindow(wx.Frame, QuickApp):
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 @@ class MainWindow(wx.Frame, QuickApp):
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 @@ class MainWindow(wx.Frame, QuickApp):
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 @@ class MainWindow(wx.Frame, QuickApp):
)
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 @@ class MainWindow(wx.Frame, QuickApp):
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"""