comparison 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
comparison
equal deleted inserted replaced
388:de066b72f5a8 389:442756495a96
20 20
21 import json 21 import json
22 from functools import partial 22 from functools import partial
23 from sat.core.i18n import _ 23 from sat.core.i18n import _
24 from sat.core import log as logging 24 from sat.core import log as logging
25 from kivy.uix.widget import Widget
25 from kivy.uix.image import Image 26 from kivy.uix.image import Image
26 from kivy.uix.label import Label 27 from kivy.uix.label import Label
27 from kivy.uix.behaviors import ButtonBehavior 28 from kivy.uix.behaviors import ButtonBehavior
28 from kivy.uix.behaviors import ToggleButtonBehavior 29 from kivy.uix.behaviors import ToggleButtonBehavior
29 from kivy.uix.boxlayout import BoxLayout 30 from kivy.uix.boxlayout import BoxLayout
30 from kivy.uix.scrollview import ScrollView 31 from kivy.uix.scrollview import ScrollView
31 from kivy.event import EventDispatcher 32 from kivy.event import EventDispatcher
32 from kivy.metrics import dp 33 from kivy.metrics import dp
33 from kivy import properties 34 from kivy import properties
35 from sat_frontends.quick_frontend import quick_chat
34 from cagou.core.constants import Const as C 36 from cagou.core.constants import Const as C
35 from cagou import G 37 from cagou import G
36 38
37 log = logging.getLogger(__name__) 39 log = logging.getLogger(__name__)
38 40
156 self.add_widget(icon_wid) 158 self.add_widget(icon_wid)
157 159
158 160
159 class JidSelector(ScrollView, EventDispatcher): 161 class JidSelector(ScrollView, EventDispatcher):
160 layout = properties.ObjectProperty(None) 162 layout = properties.ObjectProperty(None)
163 # list of item to show, can be:
164 # - a well-known string like:
165 # * "roster": to show all roster jids
166 # * "opened_chats": to show jids of all opened chat widgets
167 # - a kivy Widget, which will be added to the layout (notable useful with
168 # common_widgets.CategorySeparator)
169 # - a callable, which must return an iterable of kwargs for ContactButton
170 to_show = properties.ListProperty(['roster'])
171 # if True, update() is called automatically when widget is created
172 # if False, you'll have to call update() at least once manually
173 implicit_update = properties.ObjectProperty(True)
161 174
162 def __init__(self, **kwargs): 175 def __init__(self, **kwargs):
163 self.register_event_type('on_select') 176 self.register_event_type('on_select')
164 super().__init__(**kwargs) 177 super().__init__(**kwargs)
165 178
166 def on_kv_post(self, wid): 179 def on_kv_post(self, wid):
167 self.addRosterContacts() 180 if self.implicit_update:
181 self.update()
168 182
169 def on_select(self, wid): 183 def on_select(self, wid):
170 pass 184 pass
171 185
172 def on_parent(self, wid, parent): 186 def on_parent(self, wid, parent):
176 else: 190 else:
177 G.host.addListener("contactsFilled", self.onContactsFilled) 191 G.host.addListener("contactsFilled", self.onContactsFilled)
178 192
179 def onContactsFilled(self, profile): 193 def onContactsFilled(self, profile):
180 log.debug("onContactsFilled event received") 194 log.debug("onContactsFilled event received")
181 self.addRosterContacts() 195 self.update()
182 196
183 def addRosterContacts(self): 197 def update(self):
184 log.debug("starting addRosterContacts") 198 log.debug("starting update")
185 self.layout.clear_widgets() 199 self.layout.clear_widgets()
200 for item in self.to_show:
201 if isinstance(item, str):
202 if item == 'roster':
203 self.addRosterItems()
204 elif item == 'bookmarks':
205 self.addBookmarksItems()
206 elif item == 'opened_chats':
207 self.addOpenedChatsItems()
208 else:
209 log.error(f'unknown "to_show" magic string {item!r}')
210 elif isinstance(item, Widget):
211 self.layout.add_widget(item)
212 elif callable(item):
213 items_kwargs = item()
214 for item_kwargs in items_kwargs:
215 item = ContactButton(**item_kwargs)
216 item.bind(on_press=partial(self.dispatch, 'on_select'))
217 self.layout.add_widget(item)
218 else:
219 log.error(f"unmanaged to_show item type: {item!r}")
220
221 def addOpenedChatsItems(self):
222 opened_chats = G.host.widgets.getWidgets(
223 quick_chat.QuickChat,
224 profiles = G.host.profiles)
225
226 for wid in opened_chats:
227 contact_list = G.host.contact_lists[wid.profile]
228 try:
229 item = ContactButton(
230 jid=wid.target,
231 data=contact_list.getItem(wid.target),
232 profile=wid.profile,
233 )
234 except Exception as e:
235 log.warning(f"Can't add contact {wid.target}: {e}")
236 continue
237 item.bind(on_press=partial(self.dispatch, 'on_select'))
238 self.layout.add_widget(item)
239
240 def addRosterItems(self):
186 for profile in G.host.profiles: 241 for profile in G.host.profiles:
187 contact_list = G.host.contact_lists[profile] 242 contact_list = G.host.contact_lists[profile]
188 for entity_jid in sorted(contact_list.roster): 243 for entity_jid in sorted(contact_list.roster):
189 item = ContactButton( 244 item = ContactButton(
190 jid=entity_jid, 245 jid=entity_jid,
191 data=contact_list.getItem(entity_jid), 246 data=contact_list.getItem(entity_jid),
192 profile=profile, 247 profile=profile,
193 ) 248 )
194 item.bind(on_press=partial(self.dispatch, 'on_select')) 249 item.bind(on_press=partial(self.dispatch, 'on_select'))
195 self.layout.add_widget(item) 250 self.layout.add_widget(item)
251
252 def addBookmarksItems(self):
253 for profile in G.host.profiles:
254 profile_manager = G.host.profiles[profile]
255 try:
256 bookmarks = profile_manager._bookmarks
257 except AttributeError:
258 log.warning(f"no bookmark in cache for profile {profile}")
259 continue
260
261 contact_list = G.host.contact_lists[profile]
262 for entity_jid in bookmarks:
263 try:
264 cache = contact_list.getItem(entity_jid)
265 except KeyError:
266 cache = {}
267 item = ContactButton(
268 jid=entity_jid,
269 data=cache,
270 profile=profile,
271 )
272 item.bind(on_press=partial(self.dispatch, 'on_select'))
273 self.layout.add_widget(item)