comparison browser_side/panels.py @ 230:266e9678eec0

browser_side: added the flag REUSE_EXISTING_LIBERVIA_WIDGETS - do not create a new chat panel for contacts/groups if a similar one is found in the same tab - this goes with a modification of the methods to create new panels, especially arguments handling - improvement of the accepted groups list for MicroblogPanel (remove duplicates and keep sorted) Details for the new flag: # Set to true to not create a new LiberviaWidget when a similar one # already exist (i.e. a chat panel with the same target). Instead # the existing widget will be eventually removed from its parent # and added to new WidgetsPanel, or replaced to the expected # position if the previous and the new parent are the same.
author souliane <souliane@mailoo.org>
date Tue, 08 Oct 2013 13:57:35 +0200
parents 744426c2b699
children fab7aa366576
comparison
equal deleted inserted replaced
229:e632f77c4219 230:266e9678eec0
299 299
300 def __init__(self, host, accepted_groups): 300 def __init__(self, host, accepted_groups):
301 """Panel used to show microblog 301 """Panel used to show microblog
302 @param accepted_groups: groups displayed in this panel, if empty, show all microblogs from all contacts 302 @param accepted_groups: groups displayed in this panel, if empty, show all microblogs from all contacts
303 """ 303 """
304 base_widget.LiberviaWidget.__init__(self, host, ", ".join(accepted_groups), selectable = True) 304 base_widget.LiberviaWidget.__init__(self, host, ", ".join(accepted_groups), selectable=True)
305 #base_widget.ScrollPanelWrapper.__init__(self) 305 self.setAcceptedGroup(accepted_groups)
306 #DropCell.__init__(self)
307 self.accepted_groups = accepted_groups
308 self.entries = {} 306 self.entries = {}
309 self.comments = {} 307 self.comments = {}
310 self.selected_entry = None 308 self.selected_entry = None
311 self.vpanel = VerticalPanel() 309 self.vpanel = VerticalPanel()
312 self.vpanel.setStyleName('microblogPanel') 310 self.vpanel.setStyleName('microblogPanel')
313 self.setWidget(self.vpanel) 311 self.setWidget(self.vpanel)
314 312
315 @classmethod 313 @classmethod
316 def registerClass(cls): 314 def registerClass(cls):
317 base_widget.LiberviaWidget.addDropKey("GROUP", cls.createGroup) 315 base_widget.LiberviaWidget.addDropKey("GROUP", cls.createPanel)
318 base_widget.LiberviaWidget.addDropKey("CONTACT_TITLE", cls.createMeta) 316 base_widget.LiberviaWidget.addDropKey("CONTACT_TITLE", cls.createMetaPanel)
319 317
320 @classmethod 318 @classmethod
321 def createGroup(cls, host, item): 319 def createPanel(cls, host, item):
322 _new_panel = MicroblogPanel(host, [item]) #XXX: pyjamas doesn't support use of cls directly 320 """Generic panel creation for one, several or all groups (meta).
323 _new_panel.setAcceptedGroup(item) 321 @parem host: the SatWebFrontend instance
322 @param item: single group as a string, list of groups
323 (as an array) or None (for the meta group = "all groups")
324 @return: the created MicroblogPanel
325 """
326 _items = item if isinstance(item, list) else ([] if item is None else [item])
327 _type = 'ALL' if _items == [] else 'GROUP'
328 # XXX: pyjamas doesn't support use of cls directly
329 _new_panel = MicroblogPanel(host, _items)
324 host.FillMicroblogPanel(_new_panel) 330 host.FillMicroblogPanel(_new_panel)
325 host.bridge.call('getMassiveLastMblogs', _new_panel.massiveInsert, 'GROUP', [item], 10) 331 host.bridge.call('getMassiveLastMblogs', _new_panel.massiveInsert, _type, _items, 10)
332 host.setSelected(_new_panel)
326 return _new_panel 333 return _new_panel
327 334
328 @classmethod 335 @classmethod
329 def createMeta(cls, host, item): 336 def createMetaPanel(cls, host, item):
330 _new_panel = MicroblogPanel(host, []) #XXX: pyjamas doesn't support use of cls directly 337 """Needed for the drop keys to not be mixed between meta panel and panel for "Contacts" group"""
331 host.FillMicroblogPanel(_new_panel) 338 return MicroblogPanel.createPanel(host, None)
332 host.bridge.call('getMassiveLastMblogs', _new_panel.massiveInsert, 'ALL', [], 10) 339
333 return _new_panel 340 @property
341 def accepted_groups(self):
342 return self._accepted_groups
343
344 def matchEntity(self, entity):
345 """
346 @param entity: single group as a string, list of groups
347 (as an array) or None (for the meta group = "all groups")
348 @return: True if self matches the given entity
349 """
350 entity = entity if isinstance(entity, list) else ([] if entity is None else [entity])
351 entity.sort() # sort() do not return the sorted list: do it here, not on the "return" line
352 return self.accepted_groups == entity
334 353
335 def getWarningData(self): 354 def getWarningData(self):
336 if self.selected_entry: 355 if self.selected_entry:
337 if not self.selected_entry.comments: 356 if not self.selected_entry.comments:
338 print ("ERROR: an item without comment is selected") 357 print ("ERROR: an item without comment is selected")
339 return ("NONE", None) 358 return ("NONE", None)
340 return ("PUBLIC", "This is a <span class='warningTarget'>comment</span> and keep the initial post visibility, so it is potentialy public") 359 return ("PUBLIC", "This is a <span class='warningTarget'>comment</span> and keep the initial post visibility, so it is potentialy public")
341 360
342 elif not self.accepted_groups: 361 elif not self._accepted_groups:
343 # we have a meta MicroblogPanel, we publish publicly 362 # we have a meta MicroblogPanel, we publish publicly
344 return ("PUBLIC", self.warning_msg_public) 363 return ("PUBLIC", self.warning_msg_public)
345 else: 364 else:
346 # we only accept one group at the moment 365 # we only accept one group at the moment
347 # FIXME: manage several groups 366 # FIXME: manage several groups
348 return ("GROUP", self.warning_msg_group % self.accepted_groups[0]) 367 return ("GROUP", self.warning_msg_group % self._accepted_groups[0])
349 368
350 def onTextEntered(self, text): 369 def onTextEntered(self, text):
351 if self.selected_entry: 370 if self.selected_entry:
352 # we are entering a comment 371 # we are entering a comment
353 comments_node = self.selected_entry.comments 372 comments_node = self.selected_entry.comments
354 if not comments_node: 373 if not comments_node:
355 raise Exception("ERROR: comments node is empty") 374 raise Exception("ERROR: comments node is empty")
356 self.host.bridge.call("sendMblogComment", None, comments_node, text) 375 self.host.bridge.call("sendMblogComment", None, comments_node, text)
357 elif not self.accepted_groups: 376 elif not self._accepted_groups:
358 # we are entering a public microblog 377 # we are entering a public microblog
359 self.host.bridge.call("sendMblog", None, "PUBLIC", None, text) 378 self.host.bridge.call("sendMblog", None, "PUBLIC", None, text)
360 else: 379 else:
361 # we are entering a microblog restricted to a group 380 # we are entering a microblog restricted to a group
362 # FIXME: manage several groups 381 # FIXME: manage several groups
363 self.host.bridge.call("sendMblog", None, "GROUP", self.accepted_groups[0], text) 382 self.host.bridge.call("sendMblog", None, "GROUP", self._accepted_groups[0], text)
364 383
365 def accept_all(self): 384 def accept_all(self):
366 return not self.accepted_groups #we accept every microblog only if we are not filtering by groups 385 return not self._accepted_groups # we accept every microblog only if we are not filtering by groups
367 386
368 def getEntries(self): 387 def getEntries(self):
369 """Ask all the entries for the currenly accepted groups, 388 """Ask all the entries for the currenly accepted groups,
370 and fill the panel""" 389 and fill the panel"""
371 390
479 updateVPanel(child) 498 updateVPanel(child)
480 if type == 'avatar': 499 if type == 'avatar':
481 updateVPanel(self.vpanel) 500 updateVPanel(self.vpanel)
482 501
483 def setAcceptedGroup(self, group): 502 def setAcceptedGroup(self, group):
484 """Set the group which can be displayed in this panel 503 """Add one or more group(s) which can be displayed in this panel.
504 Prevent from duplicate values and keep the list sorted.
485 @param group: string of the group, or list of string 505 @param group: string of the group, or list of string
486 """ 506 """
487 if isinstance(group, list): 507 if not hasattr(self, "_accepted_groups"):
488 self.accepted_groups.extend(group) 508 self._accepted_groups = []
489 else: 509 groups = group if isinstance(group, list) else [group]
490 self.accepted_groups.append(group) 510 for _group in groups:
511 if _group not in self._accepted_groups:
512 self._accepted_groups.append(_group)
513 self._accepted_groups.sort()
491 514
492 def isJidAccepted(self, jid): 515 def isJidAccepted(self, jid):
493 """Tell if a jid is actepted and shown in this panel 516 """Tell if a jid is actepted and shown in this panel
494 @param jid: jid 517 @param jid: jid
495 @return: True if the jid is accepted""" 518 @return: True if the jid is accepted"""
496 if self.accept_all(): 519 if self.accept_all():
497 return True 520 return True
498 for group in self.accepted_groups: 521 for group in self._accepted_groups:
499 if self.host.contact_panel.isContactInGroup(group, jid): 522 if self.host.contact_panel.isContactInGroup(group, jid):
500 return True 523 return True
501 return False 524 return False
502 525
503 526
617 #the event will not propagate to children 640 #the event will not propagate to children
618 base_widget.ScrollPanelWrapper.doAttachChildren(self)""" 641 base_widget.ScrollPanelWrapper.doAttachChildren(self)"""
619 642
620 @classmethod 643 @classmethod
621 def registerClass(cls): 644 def registerClass(cls):
622 base_widget.LiberviaWidget.addDropKey("CONTACT", cls.createChat) 645 base_widget.LiberviaWidget.addDropKey("CONTACT", cls.createPanel)
623 646
624 @classmethod 647 @classmethod
625 def createChat(cls, host, item): 648 def createPanel(cls, host, item):
626 _contact = JID(item) 649 _contact = item if isinstance(item, JID) else JID(item)
627 host.contact_panel.setContactMessageWaiting(_contact.bare, False) 650 host.contact_panel.setContactMessageWaiting(_contact.bare, False)
628 _new_panel = ChatPanel(host, _contact) # XXX: pyjamas doesn't seems to support creating with cls directly 651 _new_panel = ChatPanel(host, _contact) # XXX: pyjamas doesn't seems to support creating with cls directly
629 _new_panel.historyPrint() 652 _new_panel.historyPrint()
653 host.setSelected(_new_panel)
630 return _new_panel 654 return _new_panel
655
656 def refresh(self):
657 """Refresh the display of this widget."""
658 self.host.contact_panel.setContactMessageWaiting(self.target.bare, False)
659 self.content_scroll.scrollToBottom()
660
661 def matchEntity(self, entity):
662 """
663 @param entity: target jid as a string or JID instance
664 @return: True if self matches the given entity
665 """
666 entity = entity if isinstance(entity, JID) else JID(entity)
667 try:
668 return self.target.bare == entity.bare
669 except AttributeError as e:
670 e.include_traceback()
671 return False
631 672
632 def getWarningData(self): 673 def getWarningData(self):
633 if self.type not in ["one2one", "group"]: 674 if self.type not in ["one2one", "group"]:
634 raise Exception("Unmanaged type !") 675 raise Exception("Unmanaged type !")
635 if self.type == "one2one": 676 if self.type == "one2one":