comparison frontends/src/primitivus/chat.py @ 1987:ab439ffe4113

primitivus (chat): moved occupants widget to a dedicated class + display occupants count in footer
author Goffi <goffi@goffi.org>
date Fri, 01 Jul 2016 00:00:11 +0200
parents 2a85c818751a
children 3f0d22565684
comparison
equal deleted inserted replaced
1986:fbd313cfd40b 1987:ab439ffe4113
34 from sat_frontends.tools import jid 34 from sat_frontends.tools import jid
35 from functools import total_ordering 35 from functools import total_ordering
36 import bisect 36 import bisect
37 37
38 38
39 OCCUPANTS_FOOTER = _(u"{} occupants")
40
39 class MessageWidget(urwid.WidgetWrap): 41 class MessageWidget(urwid.WidgetWrap):
40 42
41 def __init__(self, mess_data): 43 def __init__(self, mess_data):
42 """ 44 """
43 @param mess_data(quick_chat.Message, None): message data 45 @param mess_data(quick_chat.Message, None): message data
196 ))) 198 )))
197 markup.append(o.nick) 199 markup.append(o.nick)
198 return markup 200 return markup
199 201
200 202
203 class OccupantsWidget(urwid.WidgetWrap):
204
205 def __init__(self, parent):
206 self.parent = parent
207 self.occupants_walker = urwid.SimpleListWalker([])
208 self.occupants_footer = urwid.Text('', align='center')
209 self.updateFooter()
210 occupants_widget = urwid.Frame(urwid.ListBox(self.occupants_walker), footer=self.occupants_footer)
211 super(OccupantsWidget, self).__init__(occupants_widget)
212 occupants_list = sorted(self.parent.occupants.keys(), key=lambda o:o.lower())
213 for occupant in occupants_list:
214 occupant_data = self.parent.occupants[occupant]
215 self.occupants_walker.append(OccupantWidget(occupant_data))
216
217 def updateFooter(self):
218 """update footer widget"""
219 txt = OCCUPANTS_FOOTER.format(len(self.parent.occupants))
220 self.occupants_footer.set_text(txt)
221
222 def getNicks(self, start=u''):
223 """Return nicks of all occupants
224
225 @param start(unicode): only return nicknames which start with this text
226 """
227 return [w.nick for w in self.occupants_walker if isinstance(w, OccupantWidget) and w.nick.startswith(start)]
228
229 def addUser(self, occupant_data):
230 """add a user to the list"""
231 bisect.insort(self.occupants_walker, OccupantWidget(occupant_data))
232 self.updateFooter()
233 self.parent.host.redraw() # FIXME: should not be necessary
234
235 def removeUser(self, occupant_data):
236 """remove a user from the list"""
237 for widget in occupant_data.widgets:
238 self.occupants_walker.remove(widget)
239 self.updateFooter()
240 self.parent.host.redraw() # FIXME: should not be necessary
241
242
201 class Chat(PrimitivusWidget, quick_chat.QuickChat): 243 class Chat(PrimitivusWidget, quick_chat.QuickChat):
202 244
203 def __init__(self, host, target, type_=C.CHAT_ONE2ONE, occupants=None, subject=None, profiles=None): 245 def __init__(self, host, target, type_=C.CHAT_ONE2ONE, occupants=None, subject=None, profiles=None):
204 quick_chat.QuickChat.__init__(self, host, target, type_, occupants, subject, profiles=profiles) 246 quick_chat.QuickChat.__init__(self, host, target, type_, occupants, subject, profiles=profiles)
205 self.filters = [] # list of filter callbacks to apply 247 self.filters = [] # list of filter callbacks to apply
211 PrimitivusWidget.__init__(self, self.pile, self.target) 253 PrimitivusWidget.__init__(self, self.pile, self.target)
212 254
213 # we must adapt the behaviour with the type 255 # we must adapt the behaviour with the type
214 if type_ == C.CHAT_GROUP: 256 if type_ == C.CHAT_GROUP:
215 if len(self.chat_colums.contents) == 1: 257 if len(self.chat_colums.contents) == 1:
216 self.occupants_walker = urwid.SimpleListWalker([]) 258 self.occupants_widget = OccupantsWidget(self)
217 # TODO: put a real ContactPanel class here, based on FocusWidget ?
218 self.occupants_widgets = urwid.ListBox(self.occupants_walker)
219 # FIXME 259 # FIXME
220 # , option_type=sat_widgets.ClickableText, on_click=self._occupantsClicked) 260 # , option_type=sat_widgets.ClickableText, on_click=self._occupantsClicked)
221 self.occupants_panel = sat_widgets.VerticalSeparator(self.occupants_widgets) 261 self.occupants_panel = sat_widgets.VerticalSeparator(self.occupants_widget)
222 self._appendOccupantsPanel() 262 self._appendOccupantsPanel()
223 occupants_list = sorted(self.occupants.keys(), key=lambda o:o.lower())
224 for occupant in occupants_list:
225 occupant_data = self.occupants[occupant]
226 self.occupants_walker.append(OccupantWidget(occupant_data))
227
228 self.host.addListener('presence', self.presenceListener, [profiles]) 263 self.host.addListener('presence', self.presenceListener, [profiles])
229 264
230 # focus marker is a separator indicated last visible message before focus was lost 265 # focus marker is a separator indicated last visible message before focus was lost
231 self.focus_marker = None # link to current marker 266 self.focus_marker = None # link to current marker
232 self.focus_marker_set = None # True if a new marker has been inserted 267 self.focus_marker_set = None # True if a new marker has been inserted
271 if self.type != C.CHAT_GROUP: 306 if self.type != C.CHAT_GROUP:
272 return text 307 return text
273 308
274 space = text.rfind(" ") 309 space = text.rfind(" ")
275 start = text[space + 1:] 310 start = text[space + 1:]
276 words = [w.nick for w in self.occupants_walker if isinstance(w, OccupantWidget) and w.nick.startswith(start)] 311 words = self.occupants_widget.getNicks(start)
277 if not words: 312 if not words:
278 return text 313 return text
279 try: 314 try:
280 word_idx = words.index(completion_data['last_word']) + 1 315 word_idx = words.index(completion_data['last_word']) + 1
281 except (KeyError, ValueError): 316 except (KeyError, ValueError):
413 )) 448 ))
414 self.host.notify(C.NOTIFY_MESSAGE, from_jid, msg, widget=self, profile=self.profile) 449 self.host.notify(C.NOTIFY_MESSAGE, from_jid, msg, widget=self, profile=self.profile)
415 450
416 def addUser(self, nick): 451 def addUser(self, nick):
417 occupant = super(Chat, self).addUser(nick) 452 occupant = super(Chat, self).addUser(nick)
418 bisect.insort(self.occupants_walker, OccupantWidget(occupant)) 453 self.occupants_widget.addUser(occupant)
419 454
420 def removeUser(self, occupant_data): 455 def removeUser(self, occupant_data):
421 occupant = super(Chat, self).removeUser(occupant_data) 456 occupant = super(Chat, self).removeUser(occupant_data)
422 if occupant is not None: 457 if occupant is not None:
423 for widget in occupant.widgets: 458 self.occupants_widget.removeUser(occupant)
424 self.occupants_walker.remove(widget)
425 459
426 def _occupantsClicked(self, list_wid, clicked_wid): 460 def _occupantsClicked(self, list_wid, clicked_wid):
427 # FIXME: not called anymore after refactoring 461 # FIXME: not called anymore after refactoring
428 assert self.type == C.CHAT_GROUP 462 assert self.type == C.CHAT_GROUP
429 nick = clicked_wid.getValue().value 463 nick = clicked_wid.getValue().value