diff cagou/core/common.py @ 389:442756495a96

core (common): improved flexibility of jid selector: - JidSelector can now display a custom set of jids, using the new `to_show` property, see comments for details. - a new "implicit_update" property can be set to False (it's True by default) to avoid the automatic "update" on instance initiation. If unset, use must call "update" explicitly.
author Goffi <goffi@goffi.org>
date Thu, 06 Feb 2020 21:16:21 +0100
parents 4d660b252487
children 54f6a47cc60a
line wrap: on
line diff
--- a/cagou/core/common.py	Thu Feb 06 21:16:21 2020 +0100
+++ b/cagou/core/common.py	Thu Feb 06 21:16:21 2020 +0100
@@ -22,6 +22,7 @@
 from functools import partial
 from sat.core.i18n import _
 from sat.core import log as logging
+from kivy.uix.widget import Widget
 from kivy.uix.image import Image
 from kivy.uix.label import Label
 from kivy.uix.behaviors import ButtonBehavior
@@ -31,6 +32,7 @@
 from kivy.event import EventDispatcher
 from kivy.metrics import dp
 from kivy import properties
+from sat_frontends.quick_frontend import quick_chat
 from cagou.core.constants import Const as C
 from cagou import G
 
@@ -158,13 +160,25 @@
 
 class JidSelector(ScrollView, EventDispatcher):
     layout = properties.ObjectProperty(None)
+    # list of item to show, can be:
+    #    - a well-known string like:
+    #       * "roster": to show all roster jids
+    #       * "opened_chats": to show jids of all opened chat widgets
+    #    - a kivy Widget, which will be added to the layout (notable useful with
+    #      common_widgets.CategorySeparator)
+    #    - a callable, which must return an iterable of kwargs for ContactButton
+    to_show = properties.ListProperty(['roster'])
+    # if True, update() is called automatically when widget is created
+    # if False, you'll have to call update() at least once manually
+    implicit_update = properties.ObjectProperty(True)
 
     def __init__(self, **kwargs):
         self.register_event_type('on_select')
         super().__init__(**kwargs)
 
     def on_kv_post(self, wid):
-        self.addRosterContacts()
+        if self.implicit_update:
+            self.update()
 
     def on_select(self, wid):
         pass
@@ -178,11 +192,52 @@
 
     def onContactsFilled(self, profile):
         log.debug("onContactsFilled event received")
-        self.addRosterContacts()
+        self.update()
 
-    def addRosterContacts(self):
-        log.debug("starting addRosterContacts")
+    def update(self):
+        log.debug("starting update")
         self.layout.clear_widgets()
+        for item in self.to_show:
+            if isinstance(item, str):
+                if item == 'roster':
+                    self.addRosterItems()
+                elif item == 'bookmarks':
+                    self.addBookmarksItems()
+                elif item == 'opened_chats':
+                    self.addOpenedChatsItems()
+                else:
+                    log.error(f'unknown "to_show" magic string {item!r}')
+            elif isinstance(item, Widget):
+                self.layout.add_widget(item)
+            elif callable(item):
+                items_kwargs = item()
+                for item_kwargs in items_kwargs:
+                    item = ContactButton(**item_kwargs)
+                    item.bind(on_press=partial(self.dispatch, 'on_select'))
+                    self.layout.add_widget(item)
+            else:
+                log.error(f"unmanaged to_show item type: {item!r}")
+
+    def addOpenedChatsItems(self):
+        opened_chats = G.host.widgets.getWidgets(
+            quick_chat.QuickChat,
+            profiles = G.host.profiles)
+
+        for wid in opened_chats:
+            contact_list = G.host.contact_lists[wid.profile]
+            try:
+                item = ContactButton(
+                    jid=wid.target,
+                    data=contact_list.getItem(wid.target),
+                    profile=wid.profile,
+                )
+            except Exception as e:
+                log.warning(f"Can't add contact {wid.target}: {e}")
+                continue
+            item.bind(on_press=partial(self.dispatch, 'on_select'))
+            self.layout.add_widget(item)
+
+    def addRosterItems(self):
         for profile in G.host.profiles:
             contact_list = G.host.contact_lists[profile]
             for entity_jid in sorted(contact_list.roster):
@@ -193,3 +248,26 @@
                 )
                 item.bind(on_press=partial(self.dispatch, 'on_select'))
                 self.layout.add_widget(item)
+
+    def addBookmarksItems(self):
+        for profile in G.host.profiles:
+            profile_manager = G.host.profiles[profile]
+            try:
+                bookmarks = profile_manager._bookmarks
+            except AttributeError:
+                log.warning(f"no bookmark in cache for profile {profile}")
+                continue
+
+            contact_list = G.host.contact_lists[profile]
+            for entity_jid in bookmarks:
+                try:
+                    cache = contact_list.getItem(entity_jid)
+                except KeyError:
+                    cache = {}
+                item = ContactButton(
+                    jid=entity_jid,
+                    data=cache,
+                    profile=profile,
+                )
+                item.bind(on_press=partial(self.dispatch, 'on_select'))
+                self.layout.add_widget(item)