diff libervia.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 e632f77c4219
children b304cdf13a3b
line wrap: on
line diff
--- a/libervia.py	Tue Oct 08 13:48:00 2013 +0200
+++ b/libervia.py	Tue Oct 08 13:57:35 2013 +0200
@@ -34,7 +34,16 @@
 from browser_side.jid import JID
 from browser_side.tools import html_sanitize
 
-MAX_MBLOG_CACHE = 500 #Max microblog entries kept in memories
+
+MAX_MBLOG_CACHE = 500  # Max microblog entries kept in memories
+
+# 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.
+REUSE_EXISTING_LIBERVIA_WIDGETS = True
+
 
 class LiberviaJsonProxy(JSONProxy):
     def __init__(self, *args, **kwargs):
@@ -237,14 +246,14 @@
         return self.avatars_cache[jid_str]
 
     def registerWidget(self, wid):
-        print "Registering", wid
+        print "Registering", wid.getDebugName()
         self.libervia_widgets.add(wid)
 
     def unregisterWidget(self, wid):
         try:
             self.libervia_widgets.remove(wid)
         except KeyError:
-            print ('WARNING: trying to remove a non registered Widget:', wid)
+            print ('WARNING: trying to remove a non registered Widget:', wid.getDebugName())
 
     def setUniBox(self, unibox):
         """register the unibox widget"""
@@ -445,18 +454,68 @@
                 if lib_wid.isJidAccepted(entity):
                     self.bridge.call('getMassiveLastMblogs', lib_wid.massiveInsert, 'JID', [entity], 10)
 
+    def getLiberviaWidget(self, class_, entity, ignoreOtherTabs=True):
+        """Get the corresponding panel if it exists.
+        @param class_: class of the panel (ChatPanel, MicroblogPanel...)
+        @param entity: polymorphic parameter, see class_.matchEntity.
+        @param ignoreOtherTabs: if True, the widgets that are not
+        contained by the currently selected tab will be ignored
+        @return: the existing widget that has been found or None."""
+        selected_tab = self.tab_panel.getCurrentPanel()
+        for lib_wid in self.libervia_widgets:
+            parent = lib_wid.getWidgetsPanel(verbose=False)
+            if parent is None or (ignoreOtherTabs and parent != selected_tab):
+                # do not return a widget that is not in the currently selected tab
+                continue
+            if isinstance(lib_wid, class_):
+                try:
+                    if lib_wid.matchEntity(entity):
+                        print "existing widget found: %s" % lib_wid.getDebugName()
+                        return lib_wid
+                except AttributeError as e:
+                    e.stack_list()
+                    return None
+        return None
+
+    def getOrCreateLiberviaWidget(self, class_, entity, add=True, refresh=True, add=True):
+        """Get the matching LiberviaWidget if it exists, or create a new one.
+        @param class_: class of the panel (ChatPanel, MicroblogPanel...)
+        @param entity: polymorphic parameter, see class_.matchEntity.
+        @param refresh: if True, refresh the display of a widget that is found
+                        (ignored if no widget is found and a new one is created)
+        @param add: if True, add a widget that is created to the selected tab
+                    (ignored if a widget is found and no new one is created)
+        @return: the newly created wigdet if REUSE_EXISTING_LIBERVIA_WIDGETS
+         is set to False or if the widget has not been found, the existing
+         widget that has been found otherwise."""
+        lib_wid = None
+        if REUSE_EXISTING_LIBERVIA_WIDGETS:
+            lib_wid = self.getLiberviaWidget(class_, entity)
+        if lib_wid is None:
+            lib_wid = class_.createPanel(self, entity)
+        elif refresh:
+            # remove the widget from its previous panel
+            panel = lib_wid.getWidgetsPanel(verbose=False)
+            if panel is not None:
+                panel.removeWidget(lib_wid)
+        if add or refresh:
+            self.addWidget(lib_wid)
+        if refresh:
+            # must be done after the widget is added,
+            # for example to scroll to the bottom
+            self.setSelected(lib_wid)
+            lib_wid.refresh()
+        return lib_wid
 
     def _newMessageCb(self, from_jid, msg, msg_type, to_jid):
         _from = JID(from_jid)
         _to = JID(to_jid)
-        showed = False
-        for lib_wid in self.libervia_widgets:
-            if isinstance(lib_wid,panels.ChatPanel) and (lib_wid.target.bare == _from.bare or lib_wid.target.bare == _to.bare):
-                lib_wid.printMessage(_from, msg)
-                showed = True
-        if not showed:
-            #The message has not been showed, we must indicate it
-            other = _to if _from.bare == self.whoami.bare else _from
+        other = _to if _from.bare == self.whoami.bare else _from
+        lib_wid = self.getLiberviaWidget(panels.ChatPanel, other, ignoreOtherTabs=False)
+        if lib_wid is not None:
+            lib_wid.printMessage(_from, msg)
+        else:
+            # The message has not been showed, we must indicate it
             self.contact_panel.setContactMessageWaiting(other.bare, True)
 
     def _presenceUpdateCb(self, entity, show, priority, statuses):