Mercurial > libervia-backend
annotate frontends/src/wix/contact_list.py @ 299:e044d1dc37d1
dbus bridge: asynchrone methods management
author | Goffi <goffi@goffi.org> |
---|---|
date | Sun, 20 Feb 2011 23:59:43 +0100 |
parents | b1794cbb88e5 |
children | 3a21d586dae4 |
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 '' | |
117 avatar = self.CM.getAttr(jid,'avatar') or IMAGE_DIR+'/empty_avatar.png' | |
118 | |
119 html = """ | |
120 <table border='0'> | |
121 <td> | |
122 <img height='64' width='64' src='%s' /> | |
123 </td> | |
124 <td> | |
125 <b>%s</b> %s<br /> | |
126 <i>%s</i> | |
127 </td> | |
128 </table> | |
129 """ % (avatar, | |
130 escape(nick or name or jid.node or jid.short), | |
131 show_html, | |
132 escape(status)) | |
133 | |
134 return html | |
135 | |
136 def clear_contacts(self): | |
137 """Clear all the contact list""" | |
138 self.Clear() | |
139 | |
140 def add(self, contact, groups = None): | |
141 """add a contact to the list""" | |
142 debug (_("adding %s"),contact) | |
143 if not groups: | |
144 idx = self.Insert(self.__presentItem(contact), 0, contact) | |
145 else: | |
146 for group in groups: | |
147 indexes = self.__find_idx(group) | |
148 gp_idx = 0 | |
149 if not indexes: #this is a new group, we have to create it | |
150 gp_idx = self.Append(self.__presentGroup(group), Group(group)) | |
151 else: | |
152 gp_idx = indexes[0] | |
153 | |
154 self.Insert(self.__presentItem(contact), gp_idx+1, contact) | |
155 | |
156 | |
157 | |
158 def remove(self, contact): | |
159 """remove a contact from the list""" | |
160 debug (_("removing %s"), contact) | |
161 list_idx = self.__find_idx(contact) | |
75 | 162 list_idx.reverse() #as we make some deletions, we have to reverse the order |
72 | 163 for i in list_idx: |
164 self.Delete(i) | |
165 | |
166 def onSelected(self, event): | |
167 """Called when a contact is selected.""" | |
168 data = self.getSelection() | |
169 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
|
170 first_visible = self.GetVisibleBegin() |
72 | 171 group = self.GetClientData(self.GetSelection()) |
172 erased = self.__eraseGroup(group) | |
173 if not erased: #the group was already erased, we can add again the contacts | |
174 contacts = self.CM.getContFromGroup(group) | |
175 contacts.sort() | |
176 id_insert = self.GetSelection()+1 | |
177 for contact in contacts: | |
178 self.Insert(self.__presentItem(contact), id_insert, contact) | |
179 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
|
180 self.ScrollToLine(first_visible) |
72 | 181 event.Skip(False) |
182 else: | |
183 event.Skip() | |
184 | |
185 def onActivated(self, event): | |
186 """Called when a contact is clicked or activated with keyboard.""" | |
187 data = self.getSelection() | |
188 self.onActivatedCB(data) | |
189 event.Skip() | |
190 | |
191 def getSelection(self): | |
192 """Return the selected contact, or an empty string if there is not""" | |
193 if self.GetSelection() == wx.NOT_FOUND: | |
194 return None | |
195 data = self.GetClientData(self.GetSelection()) | |
196 if type(data) == Group: | |
197 return None | |
198 return data | |
199 | |
200 def registerActivatedCB(self, cb): | |
201 """Register a callback with manage contact activation.""" | |
202 self.onActivatedCB=cb | |
203 |