Mercurial > libervia-backend
annotate frontends/src/wix/contact_list.py @ 352:8ee8b8d78c40
Added tag SàT v0.2.0 for changeset d782c22d5e34
author | Goffi <goffi@goffi.org> |
---|---|
date | Tue, 31 May 2011 21:57:50 +0200 |
parents | 3a21d586dae4 |
children | 0806a65a5fa9 |
rev | line source |
---|---|
227 | 1 #!/usr/bin/python |
2 # -*- coding: utf-8 -*- | |
3 | |
4 """ | |
5 wix: a SAT frontend | |
228 | 6 Copyright (C) 2009, 2010, 2011 Jérôme Poisson (goffi@goffi.org) |
227 | 7 |
8 This program is free software: you can redistribute it and/or modify | |
9 it under the terms of the GNU General Public License as published by | |
10 the Free Software Foundation, either version 3 of the License, or | |
11 (at your option) any later version. | |
12 | |
13 This program is distributed in the hope that it will be useful, | |
14 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 GNU General Public License for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
19 along with this program. If not, see <http://www.gnu.org/licenses/>. | |
20 """ | |
21 | |
72 | 22 import wx |
227 | 23 from sat_frontends.quick_frontend.quick_contact_list import QuickContactList |
72 | 24 from logging import debug, info, error |
25 from cgi import escape | |
225
fd9b7834d98a
distutils installation script, draft
Goffi <goffi@goffi.org>
parents:
223
diff
changeset
|
26 from sat.tools.jid import JID |
72 | 27 |
28 | |
199 | 29 class Group(unicode): |
72 | 30 """Class used to recognize groups""" |
31 | |
199 | 32 class Contact(unicode): |
72 | 33 """Class used to recognize groups""" |
34 | |
35 class ContactList(wx.SimpleHtmlListBox, QuickContactList): | |
36 """Customized control to manage contacts.""" | |
37 | |
38 def __init__(self, parent, host, type="JID"): | |
39 """init the contact list | |
40 @param parent: WxWidgets parent of the widget | |
41 @param host: wix main app class | |
42 @param type: type of contact list: "JID" for the usual big jid contact list | |
43 "CUSTOM" for a customized contact list (self.__presentItem must then be overrided) | |
44 """ | |
45 wx.SimpleHtmlListBox.__init__(self, parent, -1) | |
46 QuickContactList.__init__(self, host.CM) | |
47 self.host = host | |
48 self.type = type | |
49 self.__typeSwitch() | |
50 self.groups = {} #list contacts in each groups, key = group | |
51 self.Bind(wx.EVT_LISTBOX, self.onSelected) | |
52 self.Bind(wx.EVT_LISTBOX_DCLICK, self.onActivated) | |
124 | 53 |
54 def __contains__(self, jid): | |
55 return bool(self.__find_idx(jid)) | |
72 | 56 |
57 def __typeSwitch(self): | |
58 if self.type == "JID": | |
59 self.__presentItem = self.__presentItemJID | |
60 elif type != "CUSTOM": | |
61 self.__presentItem = self.__presentItemDefault | |
62 | |
63 def __find_idx(self, entity): | |
64 """Find indexes of given contact (or groups) in contact list, manage jid | |
65 @return: list of indexes""" | |
66 result=[] | |
67 for i in range(self.GetCount()): | |
68 if (type(entity) == JID and type(self.GetClientData(i)) == JID and self.GetClientData(i).short == entity.short) or\ | |
69 self.GetClientData(i) == entity: | |
70 result.append(i) | |
71 return result | |
72 | |
73 def replace(self, contact, groups=None): | |
74 debug(_("update %s") % contact) | |
75 if not self.__find_idx(contact): | |
76 self.add(contact, groups) | |
77 else: | |
78 for i in self.__find_idx(contact): | |
79 self.SetString(i, self.__presentItem(contact)) | |
80 | |
81 def disconnect(self, contact): | |
82 self.remove(contact) #for now, we only show online contacts | |
83 | |
84 def __eraseGroup(self, group): | |
85 """Erase all contacts in group | |
86 @param group: group to erase | |
87 @return: True if something as been erased""" | |
88 erased = False | |
89 indexes = self.__find_idx(group) | |
90 for idx in indexes: | |
91 while idx<self.GetCount()-1 and type(self.GetClientData(idx+1)) != Group: | |
92 erased = True | |
93 self.Delete(idx+1) | |
94 return erased | |
95 | |
96 | |
97 def __presentGroup(self, group): | |
98 """Make a nice presentation for the contact groups""" | |
199 | 99 html = u"""-- [%s] --""" % group |
72 | 100 |
101 return html | |
102 | |
103 def __presentItemDefault(self, contact): | |
104 """Make a basic presentation of string contacts in the list.""" | |
105 return contact | |
106 | |
107 def __presentItemJID(self, jid): | |
108 """Make a nice presentation of the contact in the list for JID contacts.""" | |
109 name = self.CM.getAttr(jid,'name') | |
110 nick = self.CM.getAttr(jid,'nick') | |
111 show = filter(lambda x:x[0]==self.CM.getAttr(jid,'show'), const_STATUS)[0] | |
112 #show[0]==shortcut | |
113 #show[1]==human readable | |
114 #show[2]==color (or None) | |
115 show_html = "<font color='%s'>[%s]</font>" % (show[2], show[1]) if show[2] else "" | |
116 status = self.CM.getAttr(jid,'status') or '' | |
316
3a21d586dae4
wix: workaround a weird bug which crash wix while using empty_avatar, see comments for more information
Goffi <goffi@goffi.org>
parents:
228
diff
changeset
|
117 avatar = self.CM.getAttr(jid,'avatar') or IMAGE_DIR+'/empty_avatar' #XXX: there is a weird bug here: if the image has an extension (i.e. empty_avatar.png), |
3a21d586dae4
wix: workaround a weird bug which crash wix while using empty_avatar, see comments for more information
Goffi <goffi@goffi.org>
parents:
228
diff
changeset
|
118 #WxPython segfault, and it doesn't without nothing. I couldn't reproduce the case with a basic test script, so it need further investigation before reporting it |
3a21d586dae4
wix: workaround a weird bug which crash wix while using empty_avatar, see comments for more information
Goffi <goffi@goffi.org>
parents:
228
diff
changeset
|
119 #to WxPython dev. Anyway, the program crash with a segfault, not a python exception, so there is definitely something wrong with WxPython. |
3a21d586dae4
wix: workaround a weird bug which crash wix while using empty_avatar, see comments for more information
Goffi <goffi@goffi.org>
parents:
228
diff
changeset
|
120 #The case seems to happen when SimpleHtmlListBox parse the HTML with the <img> tag |
72 | 121 |
122 html = """ | |
123 <table border='0'> | |
124 <td> | |
125 <img height='64' width='64' src='%s' /> | |
126 </td> | |
127 <td> | |
128 <b>%s</b> %s<br /> | |
129 <i>%s</i> | |
130 </td> | |
131 </table> | |
132 """ % (avatar, | |
133 escape(nick or name or jid.node or jid.short), | |
134 show_html, | |
135 escape(status)) | |
136 | |
137 return html | |
138 | |
139 def clear_contacts(self): | |
140 """Clear all the contact list""" | |
141 self.Clear() | |
142 | |
143 def add(self, contact, groups = None): | |
144 """add a contact to the list""" | |
145 debug (_("adding %s"),contact) | |
146 if not groups: | |
147 idx = self.Insert(self.__presentItem(contact), 0, contact) | |
148 else: | |
149 for group in groups: | |
150 indexes = self.__find_idx(group) | |
151 gp_idx = 0 | |
152 if not indexes: #this is a new group, we have to create it | |
153 gp_idx = self.Append(self.__presentGroup(group), Group(group)) | |
154 else: | |
155 gp_idx = indexes[0] | |
316
3a21d586dae4
wix: workaround a weird bug which crash wix while using empty_avatar, see comments for more information
Goffi <goffi@goffi.org>
parents:
228
diff
changeset
|
156 |
72 | 157 self.Insert(self.__presentItem(contact), gp_idx+1, contact) |
158 | |
159 | |
160 | |
161 def remove(self, contact): | |
162 """remove a contact from the list""" | |
163 debug (_("removing %s"), contact) | |
164 list_idx = self.__find_idx(contact) | |
75 | 165 list_idx.reverse() #as we make some deletions, we have to reverse the order |
72 | 166 for i in list_idx: |
167 self.Delete(i) | |
168 | |
169 def onSelected(self, event): | |
170 """Called when a contact is selected.""" | |
171 data = self.getSelection() | |
172 if data == None: #we have a group | |
138
2f8c86488b05
wix: scrolling is not reseted anymore when clicking on a group on contact list
Goffi <goffi@goffi.org>
parents:
125
diff
changeset
|
173 first_visible = self.GetVisibleBegin() |
72 | 174 group = self.GetClientData(self.GetSelection()) |
175 erased = self.__eraseGroup(group) | |
176 if not erased: #the group was already erased, we can add again the contacts | |
177 contacts = self.CM.getContFromGroup(group) | |
178 contacts.sort() | |
179 id_insert = self.GetSelection()+1 | |
180 for contact in contacts: | |
181 self.Insert(self.__presentItem(contact), id_insert, contact) | |
182 self.SetSelection(wx.NOT_FOUND) | |
138
2f8c86488b05
wix: scrolling is not reseted anymore when clicking on a group on contact list
Goffi <goffi@goffi.org>
parents:
125
diff
changeset
|
183 self.ScrollToLine(first_visible) |
72 | 184 event.Skip(False) |
185 else: | |
186 event.Skip() | |
187 | |
188 def onActivated(self, event): | |
189 """Called when a contact is clicked or activated with keyboard.""" | |
190 data = self.getSelection() | |
191 self.onActivatedCB(data) | |
192 event.Skip() | |
193 | |
194 def getSelection(self): | |
195 """Return the selected contact, or an empty string if there is not""" | |
196 if self.GetSelection() == wx.NOT_FOUND: | |
197 return None | |
198 data = self.GetClientData(self.GetSelection()) | |
199 if type(data) == Group: | |
200 return None | |
201 return data | |
202 | |
203 def registerActivatedCB(self, cb): | |
204 """Register a callback with manage contact activation.""" | |
205 self.onActivatedCB=cb | |
206 |