changeset 348:38fd457b2158

core (common, share_widget): new JidSelector widget: - A widget to select jid among a list is commonly needed, so it has been implemented in core.common, based on the code from ShareWidget - ShareWidget has been adapted accordingly - new ContactButton class in core.common
author Goffi <goffi@goffi.org>
date Fri, 17 Jan 2020 18:44:32 +0100
parents bf9474e164f3
children 33244f944bd8
files cagou/core/common.py cagou/core/share_widget.py cagou/kv/common.kv cagou/kv/share_widget.kv
diffstat 4 files changed, 95 insertions(+), 66 deletions(-) [+]
line wrap: on
line diff
--- a/cagou/core/common.py	Sat Jan 04 16:24:57 2020 +0100
+++ b/cagou/core/common.py	Fri Jan 17 18:44:32 2020 +0100
@@ -1,5 +1,4 @@
-#!/usr//bin/env python2
-# -*- coding: utf-8 -*-
+#!/usr/bin/env python3
 
 # Cagou: desktop/mobile frontend for Salut à Toi XMPP client
 # Copyright (C) 2016-2019 Jérôme Poisson (goffi@goffi.org)
@@ -19,18 +18,21 @@
 
 """common simple widgets"""
 
+import json
+from functools import partial
 from sat.core.i18n import _
+from sat.core import log as logging
 from kivy.uix.image import Image
 from kivy.uix.label import Label
 from kivy.uix.behaviors import ButtonBehavior
 from kivy.uix.behaviors import ToggleButtonBehavior
 from kivy.uix.boxlayout import BoxLayout
+from kivy.uix.scrollview import ScrollView
+from kivy.event import EventDispatcher
 from kivy.metrics import dp
-from cagou.core.constants import Const as C
 from kivy import properties
+from cagou.core.constants import Const as C
 from cagou import G
-import json
-from sat.core import log as logging
 
 log = logging.getLogger(__name__)
 
@@ -46,12 +48,20 @@
 
 
 class ContactItem(BoxLayout):
+    """An item from ContactList
+
+    The item will drawn as an icon (JID avatar) with its jid below
+    """
     base_width = dp(150)
     profile = properties.StringProperty()
     data = properties.DictProperty()
     jid = properties.StringProperty('')
 
 
+class ContactButton(ButtonBehavior, ContactItem):
+    pass
+
+
 class JidItem(BoxLayout):
     bg_color = properties.ListProperty([0.2, 0.2, 0.2, 1])
     color = properties.ListProperty([1, 1, 1, 1])
@@ -144,3 +154,42 @@
         else:
             icon_wid = ActionSymbol(symbol=symbol)
             self.add_widget(icon_wid)
+
+
+class JidSelector(ScrollView, EventDispatcher):
+    layout = properties.ObjectProperty(None)
+
+    def __init__(self, **kwargs):
+        self.register_event_type('on_select')
+        super().__init__(**kwargs)
+
+    def on_kv_post(self, wid):
+        self.addRosterContacts()
+
+    def on_select(self, wid):
+        pass
+
+    def on_parent(self, wid, parent):
+        if parent is None:
+            log.debug("removing contactsFilled listener")
+            G.host.removeListener("contactsFilled", self.onContactsFilled)
+        else:
+            G.host.addListener("contactsFilled", self.onContactsFilled)
+
+    def onContactsFilled(self, profile):
+        log.debug("onContactsFilled event received")
+        self.addRosterContacts()
+
+    def addRosterContacts(self):
+        log.debug("starting addRosterContacts")
+        self.layout.clear_widgets()
+        for profile in G.host.profiles:
+            contact_list = G.host.contact_lists[profile]
+            for entity_jid in sorted(contact_list.roster):
+                item = ContactButton(
+                    jid=entity_jid,
+                    data=contact_list.getItem(entity_jid),
+                    profile=profile,
+                )
+                item.bind(on_press=partial(self.dispatch, 'on_select'))
+                self.layout.add_widget(item)
--- a/cagou/core/share_widget.py	Sat Jan 04 16:24:57 2020 +0100
+++ b/cagou/core/share_widget.py	Fri Jan 17 18:44:32 2020 +0100
@@ -1,5 +1,4 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
+#!/usr/bin/env python3
 
 # Cagou: desktop/mobile frontend for Salut à Toi XMPP client
 # Copyright (C) 2016-2019 Jérôme Poisson (goffi@goffi.org)
@@ -19,16 +18,15 @@
 
 
 from pathlib import Path
+from functools import partial
 from sat.core import log as logging
 from sat.core.i18n import _
 from sat.tools.common import data_format
 from sat_frontends.tools import jid
 from kivy.uix.boxlayout import BoxLayout
-from kivy.uix.behaviors import ButtonBehavior
 from kivy.properties import StringProperty, DictProperty, ObjectProperty
 from kivy.core.window import Window
 from kivy.metrics import dp
-from .common import ContactItem
 from .constants import Const as C
 from cagou import G
 
@@ -43,30 +41,6 @@
     "icon_symbol": "share",
 }
 
-class ShareContactItem(ButtonBehavior, ContactItem):
-
-    def filterDataCb(self, data):
-        G.host.doAction('chat', jid.JID(self.jid), [self.profile])
-        chat_wid = G.host.selected_widget
-
-        if self.share_wid.type == 'text':
-            text = self.share_wid.data['text']
-            chat_wid.message_input.text += text
-        else:
-            path = self.share_wid.data['path']
-            chat_wid.transferFile(path, cleaning_cb=data.get('cleaning_cb'))
-        self.share_wid.close()
-
-    def filterDataEb(self, failure_):
-        G.host.addNote(
-            _("file filter error"),
-            _("Can't apply filter to file: {msg}").format(msg=failure_),
-            level=C.XMLUI_DATA_LVL_ERROR)
-
-    def on_press(self):
-        self.share_wid = G.host.getAncestorWidget(self, ShareWidget)
-        self.share_wid.getFilteredData(self.filterDataCb, self.filterDataEb)
-
 
 class TextPreview(BoxLayout):
     """Widget previewing shared text"""
@@ -126,11 +100,9 @@
     media_type = StringProperty()
     data = DictProperty()
     preview_box = ObjectProperty()
-    layout = ObjectProperty()
 
     def __init__(self, **kwargs):
         super().__init__(**kwargs)
-        G.host.addListener("contactsFilled", self.onContactsFilled)
         Window.bind(on_keyboard=self.key_input)
 
     def on_kv_post(self, wid):
@@ -141,34 +113,10 @@
             self.preview_box.add_widget(ImagePreview(path=self.data['path']))
         else:
             self.preview_box.add_widget(GenericPreview(path=self.data['path']))
-        self.addRosterContacts()
 
     def close(self):
         G.host.closeUI()
 
-    def on_parent(self, wid, parent):
-        if parent is None:
-            log.debug("removing contactsFilled listener")
-            G.host.removeListener("contactsFilled", self.onContactsFilled)
-
-
-    def addRosterContacts(self):
-        log.debug("starting addRosterContacts")
-        self.layout.clear_widgets()
-        for profile in G.host.profiles:
-            contact_list = G.host.contact_lists[profile]
-            for entity_jid in sorted(contact_list.roster):
-                item = ShareContactItem(
-                    jid=entity_jid,
-                    data=contact_list.getItem(entity_jid),
-                    profile=profile,
-                )
-                self.layout.add_widget(item)
-
-    def onContactsFilled(self, profile):
-        log.debug("onContactsFilled event received")
-        self.addRosterContacts()
-
     def getFilteredData(self, callback, errback):
         """Apply filter if suitable, and call callback with with modified data"""
         try:
@@ -179,6 +127,34 @@
             filter_ = getFilter()
             filter_(self.data, callback=callback, errback=errback)
 
+    def filterDataCb(self, data, contact_jid, profile):
+        G.host.doAction('chat', contact_jid, [profile])
+        chat_wid = G.host.selected_widget
+
+        if self.type == 'text':
+            text = self.data['text']
+            chat_wid.message_input.text += text
+        else:
+            path = self.data['path']
+            chat_wid.transferFile(path, cleaning_cb=data.get('cleaning_cb'))
+        self.close()
+
+    def filterDataEb(self, failure_):
+        G.host.addNote(
+            _("file filter error"),
+            _("Can't apply filter to file: {msg}").format(msg=failure_),
+            level=C.XMLUI_DATA_LVL_ERROR)
+
+    def on_select(self, contact_button):
+        contact_jid = jid.JID(contact_button.jid)
+        self.getFilteredData(
+            partial(
+                self.filterDataCb,
+                contact_jid=contact_jid,
+                profile=contact_button.profile),
+            self.filterDataEb
+        )
+
     def key_input(self, window, key, scancode, codepoint, modifier):
         if key == 27:
             self.close()
--- a/cagou/kv/common.kv	Sat Jan 04 16:24:57 2020 +0100
+++ b/cagou/kv/common.kv	Fri Jan 17 18:44:32 2020 +0100
@@ -109,3 +109,12 @@
 <ActionSymbol>:
     bg_color: 0, 0, 0, 0
     color: app.c_sec_light
+
+
+<JidSelector>:
+    layout: layout
+    StackLayout:
+        id: layout
+        size_hint: 1, None
+        height: self.minimum_height
+        spacing: 0
--- a/cagou/kv/share_widget.kv	Sat Jan 04 16:24:57 2020 +0100
+++ b/cagou/kv/share_widget.kv	Fri Jan 17 18:44:32 2020 +0100
@@ -20,7 +20,6 @@
 
 <ShareWidget>:
     preview_box: preview_box
-    layout: layout
     orientation: 'vertical'
     Label:
         size_hint: 1, None
@@ -44,12 +43,8 @@
         height: self.font_size + dp(5)
         bold: True
         font_size: '25sp'
-    ScrollView:
-        StackLayout:
-            id: layout
-            size_hint: 1, None
-            height: self.minimum_height
-            spacing: 0
+    JidSelector:
+        on_select: root.on_select(args[1])
     Button:
         size_hint: 1, None
         height: C.BTN_HEIGHT