comparison frontends/src/primitivus/contact_list.py @ 501:e9634d2e7b38

core, quick_frontend, primitivus, wix: Contacts List refactoring phase 1: - QuickContactManagement is not used anymore and will be removed, ContactList + Core are used instead - disconnected contacts are now displayed in Primitivus (M-d to show/hide them) - avatars are temporary unavailable in wix - new bridge method: getContactsFromGroup
author Goffi <goffi@goffi.org>
date Tue, 25 Sep 2012 00:58:34 +0200
parents 00d3679976ab
children debcf5dd404a
comparison
equal deleted inserted replaced
500:00d3679976ab 501:e9634d2e7b38
26 26
27 27
28 class ContactList(urwid.WidgetWrap, QuickContactList): 28 class ContactList(urwid.WidgetWrap, QuickContactList):
29 signals = ['click','change'] 29 signals = ['click','change']
30 30
31 def __init__(self, host, CM, on_click=None, on_change=None, user_data=None): 31 def __init__(self, host, on_click=None, on_change=None, user_data=None):
32 self.host = host 32 self.host = host
33 self.selected = None 33 self.selected = None
34 self.groups={} 34 self.groups={}
35 self.alert_jid=set() 35 self.alert_jid=set()
36 self.show_status = False 36 self.show_status = False
37 self.show_disconnected = False
37 38
38 #we now build the widget 39 #we now build the widget
39 self.frame = urwid.Frame(self.__buildList()) 40 self.frame = urwid.Frame(self.__buildList())
40 self.main_widget = sat_widgets.LabelLine(self.frame, sat_widgets.SurroundedText(_("Contacts"))) 41 self.main_widget = sat_widgets.LabelLine(self.frame, sat_widgets.SurroundedText(_("Contacts")))
41 urwid.WidgetWrap.__init__(self, self.main_widget) 42 urwid.WidgetWrap.__init__(self, self.main_widget)
42 if on_click: 43 if on_click:
43 urwid.connect_signal(self, 'click', on_click, user_data) 44 urwid.connect_signal(self, 'click', on_click, user_data)
44 if on_change: 45 if on_change:
45 urwid.connect_signal(self, 'change', on_change, user_data) 46 urwid.connect_signal(self, 'change', on_change, user_data)
46 QuickContactList.__init__(self, CM) 47 QuickContactList.__init__(self)
47 48
48 def _update(self): 49 def update(self):
49 """Update display, keep focus""" 50 """Update display, keep focus"""
50 widget, position = self.frame.body.get_focus() 51 widget, position = self.frame.body.get_focus()
51 self.frame.body = self.__buildList() 52 self.frame.body = self.__buildList()
52 if position: 53 if position:
53 self.frame.body.set_focus(position) 54 self.frame.body.set_focus(position)
54 self.host.redraw() 55 self.host.redraw()
55 56
57 def update_jid(self, jid):
58 self.update()
59
56 def keypress(self, size, key): 60 def keypress(self, size, key):
57 if key == "meta s": #user wants to (un)hide contacts' statuses 61 if key == "meta s": #user wants to (un)hide contacts' statuses
58 self.show_status = not self.show_status 62 self.show_status = not self.show_status
59 self._update() 63 self.update()
64 elif key == "meta d": #user wants to (un)hide disconnected contacts
65 self.show_disconnected = not self.show_disconnected
66 self.update()
60 return super(ContactList, self).keypress(size, key) 67 return super(ContactList, self).keypress(size, key)
61 68
62 def __contains__(self, jid): 69 def __contains__(self, jid):
63 for group in self.groups: 70 for group in self.groups:
64 if jid.short in self.groups[group][1]: 71 if jid.short in self.groups[group][1]:
75 idx+=1 82 idx+=1
76 83
77 def putAlert(self, jid): 84 def putAlert(self, jid):
78 """Put an alert on the jid to get attention from user (e.g. for new message)""" 85 """Put an alert on the jid to get attention from user (e.g. for new message)"""
79 self.alert_jid.add(jid.short) 86 self.alert_jid.add(jid.short)
80 self._update() 87 self.update()
81 88
82 def __groupClicked(self, group_wid): 89 def __groupClicked(self, group_wid):
83 group = self.groups[group_wid.getValue()] 90 group = self.groups[group_wid.getValue()]
84 group[0] = not group[0] 91 group[0] = not group[0]
85 self._update() 92 self.update()
86 self.setFocus(group_wid.getValue()) 93 self.setFocus(group_wid.getValue())
87 94
88 def __contactClicked(self, contact_wid, selected): 95 def __contactClicked(self, contact_wid, selected):
89 self.selected = contact_wid.data 96 self.selected = contact_wid.data
90 for widget in self.frame.body.body: 97 for widget in self.frame.body.body:
91 if widget.__class__ == sat_widgets.SelectableText: 98 if widget.__class__ == sat_widgets.SelectableText:
92 widget.setState(widget.data == self.selected, invisible=True) 99 widget.setState(widget.data == self.selected, invisible=True)
93 if self.selected in self.alert_jid: 100 if self.selected in self.alert_jid:
94 self.alert_jid.remove(self.selected) 101 self.alert_jid.remove(self.selected)
95 self._update() 102 self.update()
96 self._emit('click') 103 self._emit('click')
97 104
98 def __buildContact(self, content, param_contacts): 105 def __buildContact(self, content, param_contacts):
99 """Add contact representation in widget list 106 """Add contact representation in widget list
100 @param content: widget list, e.g. SimpleListWalker 107 @param content: widget list, e.g. SimpleListWalker
101 @param contacts: list of JID""" 108 @param contacts: list of JID"""
102 contacts = list(param_contacts) 109 contacts = list(param_contacts)
103 contacts.sort() 110
111 widgets = [] #list of built widgets
112
104 for contact in contacts: 113 for contact in contacts:
105 jid=JID(contact) 114 jid=JID(contact)
106 name = self.CM.getAttr(jid,'name') 115 name = self.getCache(jid, 'name')
107 nick = self.CM.getAttr(jid,'nick') 116 nick = self.getCache(jid, 'nick')
108 status = self.CM.getAttr(jid, 'status') 117 status = self.getCache(jid, 'status')
109 show = self.CM.getAttr(jid, 'show') 118 show = self.getCache(jid, 'show')
119 if show == None:
120 show = "unavailable"
121 if (not self.show_disconnected and show == "unavailable"
122 and not contact in self.alert_jid and contact != self.selected):
123 continue
110 show_icon, show_attr = const_SHOW_ICON.get(show,('','default')) 124 show_icon, show_attr = const_SHOW_ICON.get(show,('','default'))
111 contact_disp = ('alert' if contact in self.alert_jid else show_attr, nick or name or jid.node or jid.short) 125 contact_disp = ('alert' if contact in self.alert_jid else show_attr, nick or name or jid.node or jid.short)
112 display = [ show_icon + " " , contact_disp] 126 display = [ show_icon + " " , contact_disp]
113 if self.show_status: 127 if self.show_status:
114 status_disp = ('status',"\n " + status) if status else "" 128 status_disp = ('status',"\n " + status) if status else ""
116 header = '(*) ' if contact in self.alert_jid else '' 130 header = '(*) ' if contact in self.alert_jid else ''
117 widget = sat_widgets.SelectableText(display, 131 widget = sat_widgets.SelectableText(display,
118 selected = contact==self.selected, 132 selected = contact==self.selected,
119 header=header) 133 header=header)
120 widget.data = contact 134 widget.data = contact
135 widget.comp = contact_disp[1].lower() #value to use for sorting
136 widgets.append(widget)
137
138 widgets.sort(key=lambda widget: widget.comp)
139
140 for widget in widgets:
121 content.append(widget) 141 content.append(widget)
122 urwid.connect_signal(widget, 'change', self.__contactClicked) 142 urwid.connect_signal(widget, 'change', self.__contactClicked)
123 143
124 def __buildList(self): 144 def __buildList(self):
125 """Build the main contact list widget""" 145 """Build the main contact list widget"""
126 content = urwid.SimpleListWalker([]) 146 content = urwid.SimpleListWalker([])
127 group_keys = self.groups.keys() 147 group_keys = self.groups.keys()
128 group_keys.sort() 148 group_keys.sort(key = lambda x: x.lower() if x else x)
129 for key in group_keys: 149 for key in group_keys:
130 unfolded = self.groups[key][0] 150 unfolded = self.groups[key][0]
131 if key!=None: 151 if key!=None:
132 header = '[-]' if unfolded else '[+]' 152 header = '[-]' if unfolded else '[+]'
133 widget = sat_widgets.ClickableText(key,header=header+' ') 153 widget = sat_widgets.ClickableText(key,header=header+' ')
143 for widget in self.frame.body.body: 163 for widget in self.frame.body.body:
144 if widget.__class__ == sat_widgets.SelectableText: 164 if widget.__class__ == sat_widgets.SelectableText:
145 widget.setState(False, invisible=True) 165 widget.setState(False, invisible=True)
146 166
147 167
148 def get_contact(self): 168 def getContact(self):
149 """Return contact currently selected""" 169 """Return contact currently selected"""
150 return self.selected 170 return self.selected
151 171
152 def clear_contacts(self): 172 def clearContacts(self):
153 """clear all the contact list""" 173 """clear all the contact list"""
154 self.groups={} 174 self.groups={}
155 self.selected = None 175 self.selected = None
156 self.unselectAll() 176 self.unselectAll()
157 self._update() 177 self.update()
158 178
159 def replace(self, jid, groups=[None]): 179 def replace(self, jid, groups=None, attributes=None):
160 """add a contact to the list if doesn't exist, else update it""" 180 """add a contact to the list if doesn't exist, else update it"""
181 if not groups:
182 groups = [None]
183 if not attributes:
184 attributes={}
161 assert isinstance(groups, list) 185 assert isinstance(groups, list)
162 assert isinstance(jid, JID) 186 assert isinstance(jid, JID)
163 if not groups:
164 groups=[None]
165 for group in groups: 187 for group in groups:
166 if not self.groups.has_key(group): 188 if not self.groups.has_key(group):
167 self.groups[group] = [True,set()] #[unfold,list_of_contacts] 189 self.groups[group] = [True,set()] #[unfold,list_of_contacts]
168 self.groups[group][1].add(jid.short) 190 self.groups[group][1].add(jid.short)
169 self._update() 191 self.update()
170 192
171 193
172 """contacts = self.list_wid.getAllValues() 194 """contacts = self.list_wid.getAllValues()
173 if jid.short not in contacts: 195 if jid.short not in contacts:
174 contacts.append(jid.short) 196 contacts.append(jid.short)
175 contacts.sort() 197 contacts.sort()
176 self.list_wid.changeValues(contacts) 198 self.list_wid.changeValues(contacts)
177 self._emit('change')""" 199 self._emit('change')"""
178
179 def disconnect(self, jid):
180 """mark a contact disconnected"""
181 self.remove(jid.short)
182 200
183 def remove(self, param_jid): 201 def remove(self, param_jid):
184 """remove a contact from the list""" 202 """remove a contact from the list"""
185 groups_to_remove = [] 203 groups_to_remove = []
186 jid = JID(param_jid) 204 jid = JID(param_jid)
190 contacts.remove(jid.short) 208 contacts.remove(jid.short)
191 if not len(contacts): 209 if not len(contacts):
192 groups_to_remove.append(group) 210 groups_to_remove.append(group)
193 for group in groups_to_remove: 211 for group in groups_to_remove:
194 del self.groups[group] 212 del self.groups[group]
195 self._update() 213 self.update()
196 214
197 def add(self, jid, param_groups=[None]): 215 def add(self, jid, param_groups=[None]):
198 """add a contact to the list""" 216 """add a contact to the list"""
199 self.replace(jid,param_groups) 217 self.replace(jid,param_groups)
200 218