Mercurial > libervia-desktop-kivy
comparison cagou/plugins/plugin_wid_contact_list.py @ 221:e1a385a791cc
plugin contact list: implemented contact addition
author | Goffi <goffi@goffi.org> |
---|---|
date | Tue, 26 Jun 2018 07:36:11 +0200 |
parents | 9faccd140119 |
children | 9e5f9f0cee48 |
comparison
equal
deleted
inserted
replaced
220:24f8ab7c08be | 221:e1a385a791cc |
---|---|
25 from sat_frontends.quick_frontend.quick_contact_list import QuickContactList | 25 from sat_frontends.quick_frontend.quick_contact_list import QuickContactList |
26 from sat_frontends.tools import jid | 26 from sat_frontends.tools import jid |
27 from kivy.uix.boxlayout import BoxLayout | 27 from kivy.uix.boxlayout import BoxLayout |
28 from kivy.uix.behaviors import ButtonBehavior | 28 from kivy.uix.behaviors import ButtonBehavior |
29 from cagou.core.utils import FilterBehavior | 29 from cagou.core.utils import FilterBehavior |
30 from cagou.core.menu import SideMenu | |
30 from kivy.metrics import dp | 31 from kivy.metrics import dp |
31 from kivy import properties | 32 from kivy import properties |
32 from cagou.core import cagou_widget | 33 from cagou.core import cagou_widget |
33 from cagou.core import image | 34 from cagou.core import image |
34 from cagou import G | 35 from cagou import G |
36 from functools import partial | |
35 import bisect | 37 import bisect |
38 import re | |
36 | 39 |
37 | 40 |
38 PLUGIN_INFO = { | 41 PLUGIN_INFO = { |
39 "name": _(u"contacts"), | 42 "name": _(u"contacts"), |
40 "main": "ContactList", | 43 "main": "ContactList", |
41 "description": _(u"list of contacts"), | 44 "description": _(u"list of contacts"), |
42 "icon_medium": u"{media}/icons/muchoslava/png/contact_list_no_border_blue_44.png" | 45 "icon_medium": u"{media}/icons/muchoslava/png/contact_list_no_border_blue_44.png" |
43 } | 46 } |
44 | 47 |
45 | 48 |
49 class AddContactMenu(SideMenu): | |
50 profile = properties.StringProperty() | |
51 instructions = properties.StringProperty(_(u"Please enter new contact JID")) | |
52 size_hint_close = (1, 0) | |
53 size_hint_open = (1, 0.5) | |
54 | |
55 def __init__(self, **kwargs): | |
56 super(AddContactMenu, self).__init__(**kwargs) | |
57 if self.profile is None: | |
58 log.warning(_(u"profile not set in AddContactMenu")) | |
59 self.profile = next(iter(G.host.profiles)) | |
60 | |
61 def addContact(self, contact_jid): | |
62 """Actually add the contact | |
63 | |
64 @param contact_jid(unicode): jid of the contact to add | |
65 """ | |
66 contact_jid = contact_jid.strip() | |
67 # FIXME: trivial jid verification | |
68 if not contact_jid or not re.match(r"[^@ ]+@[^@ ]+", contact_jid): | |
69 return | |
70 contact_jid = jid.JID(contact_jid).bare | |
71 G.host.bridge.addContact(contact_jid, | |
72 self.profile, | |
73 callback=lambda: G.host.addNote( | |
74 _(u"contact request"), | |
75 _(u"a contact request has been sent to {contact_jid}").format( | |
76 contact_jid=contact_jid)), | |
77 errback=partial(G.host.errback, | |
78 title=_(u"can't add contact"), | |
79 message=_(u"error while trying to add contact: {msg}"))) | |
80 self.hide() | |
81 | |
82 | |
46 class Avatar(image.Image): | 83 class Avatar(image.Image): |
47 pass | 84 pass |
48 | 85 |
49 | 86 |
50 class ContactItem(ButtonBehavior, BoxLayout): | 87 class ContactItem(ButtonBehavior, BoxLayout): |
51 base_width = dp(150) | 88 base_width = dp(150) |
89 profile = properties.StringProperty() | |
52 data = properties.DictProperty() | 90 data = properties.DictProperty() |
53 jid = properties.StringProperty('') | 91 jid = properties.StringProperty('') |
54 | 92 |
55 def __init__(self, **kwargs): | 93 def __init__(self, **kwargs): |
56 super(ContactItem, self).__init__(**kwargs) | 94 super(ContactItem, self).__init__(**kwargs) |
57 | 95 |
58 def on_release(self): | 96 def on_release(self): |
97 assert self.profile | |
59 # XXX: for now clicking on an item launch the corresponding Chat widget | 98 # XXX: for now clicking on an item launch the corresponding Chat widget |
60 # behaviour should change in the future | 99 # behaviour should change in the future |
61 try: | 100 try: |
62 # FIXME: Q&D way to get chat plugin, should be replaced by a clean method | 101 # FIXME: Q&D way to get chat plugin, should be replaced by a clean method |
63 # in host | 102 # in host |
67 log.warning(u"No plugin widget found to display chat") | 106 log.warning(u"No plugin widget found to display chat") |
68 else: | 107 else: |
69 factory = plg_infos['factory'] | 108 factory = plg_infos['factory'] |
70 G.host.switchWidget(self, factory(plg_infos, | 109 G.host.switchWidget(self, factory(plg_infos, |
71 jid.JID(self.jid), | 110 jid.JID(self.jid), |
72 profiles=iter(G.host.profiles))) | 111 profiles=[self.profile])) |
73 | 112 |
74 | 113 |
75 class ContactList(QuickContactList, cagou_widget.CagouWidget, FilterBehavior): | 114 class ContactList(QuickContactList, cagou_widget.CagouWidget, FilterBehavior): |
76 float_layout = properties.ObjectProperty() | 115 float_layout = properties.ObjectProperty() |
77 layout = properties.ObjectProperty() | 116 layout = properties.ObjectProperty() |
83 self._wid_map = {} # (profile, bare_jid) to widget map | 122 self._wid_map = {} # (profile, bare_jid) to widget map |
84 self.postInit() | 123 self.postInit() |
85 if len(self.profiles) != 1: | 124 if len(self.profiles) != 1: |
86 raise NotImplementedError('multi profiles is not implemented yet') | 125 raise NotImplementedError('multi profiles is not implemented yet') |
87 self.update(profile=next(iter(self.profiles))) | 126 self.update(profile=next(iter(self.profiles))) |
127 | |
128 def addContactMenu(self): | |
129 """Show the "add a contact" menu""" | |
130 # FIXME: for now we add contact to the first profile we find | |
131 profile = next(iter(self.profiles)) | |
132 AddContactMenu(profile=profile).show() | |
88 | 133 |
89 def onHeaderInputComplete(self, wid, text): | 134 def onHeaderInputComplete(self, wid, text): |
90 self.do_filter(self.layout.children, | 135 self.do_filter(self.layout.children, |
91 text, | 136 text, |
92 lambda c: c.jid, | 137 lambda c: c.jid, |
100 item will be added in a sorted position | 145 item will be added in a sorted position |
101 @param bare_jid(jid.JID): entity bare JID | 146 @param bare_jid(jid.JID): entity bare JID |
102 @param profile(unicode): profile where the contact is | 147 @param profile(unicode): profile where the contact is |
103 """ | 148 """ |
104 data = G.host.contact_lists[profile].getItem(bare_jid) | 149 data = G.host.contact_lists[profile].getItem(bare_jid) |
105 wid = ContactItem(data=data, jid=bare_jid) | 150 wid = ContactItem(profile=profile, data=data, jid=bare_jid) |
106 child_jids = [c.jid for c in reversed(self.layout.children)] | 151 child_jids = [c.jid for c in reversed(self.layout.children)] |
107 idx = bisect.bisect_right(child_jids, bare_jid) | 152 idx = bisect.bisect_right(child_jids, bare_jid) |
108 self.layout.add_widget(wid, -idx) | 153 self.layout.add_widget(wid, -idx) |
109 self._wid_map[(profile, bare_jid)] = wid | 154 self._wid_map[(profile, bare_jid)] = wid |
110 | 155 |
112 log.debug("update: %s %s %s" % (entities, type_, profile)) | 157 log.debug("update: %s %s %s" % (entities, type_, profile)) |
113 if type_ == None or type_ == C.UPDATE_STRUCTURE: | 158 if type_ == None or type_ == C.UPDATE_STRUCTURE: |
114 log.debug("full contact list update") | 159 log.debug("full contact list update") |
115 self.layout.clear_widgets() | 160 self.layout.clear_widgets() |
116 for bare_jid, data in self.items_sorted.iteritems(): | 161 for bare_jid, data in self.items_sorted.iteritems(): |
117 wid = ContactItem(data=data, jid=bare_jid) | 162 wid = ContactItem(profile=profile, data=data, jid=bare_jid) |
118 self.layout.add_widget(wid) | 163 self.layout.add_widget(wid) |
119 self._wid_map[(profile, bare_jid)] = wid | 164 self._wid_map[(profile, bare_jid)] = wid |
120 elif type_ == C.UPDATE_MODIFY: | 165 elif type_ == C.UPDATE_MODIFY: |
121 for entity in entities: | 166 for entity in entities: |
122 entity_bare = entity.bare | 167 entity_bare = entity.bare |