comparison cagou/plugins/plugin_wid_contact_list.py @ 223:9e5f9f0cee48

plugin contact list: use new TouchMenuBehaviour to implement contact deletion
author Goffi <goffi@goffi.org>
date Tue, 26 Jun 2018 20:27:23 +0200
parents e1a385a791cc
children ff1efdeff53f
comparison
equal deleted inserted replaced
222:a676cb07c1cb 223:9e5f9f0cee48
23 from cagou.core.constants import Const as C 23 from cagou.core.constants import Const as C
24 from sat.core.i18n import _ 24 from sat.core.i18n import _
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
29 from cagou.core.utils import FilterBehavior 28 from cagou.core.utils import FilterBehavior
30 from cagou.core.menu import SideMenu 29 from cagou.core.menu import SideMenu, TouchMenuBehaviour, TouchMenuItemBehaviour
31 from kivy.metrics import dp 30 from kivy.metrics import dp
32 from kivy import properties 31 from kivy import properties
33 from cagou.core import cagou_widget 32 from cagou.core import cagou_widget
34 from cagou.core import image 33 from cagou.core import image
35 from cagou import G 34 from cagou import G
46 } 45 }
47 46
48 47
49 class AddContactMenu(SideMenu): 48 class AddContactMenu(SideMenu):
50 profile = properties.StringProperty() 49 profile = properties.StringProperty()
51 instructions = properties.StringProperty(_(u"Please enter new contact JID"))
52 size_hint_close = (1, 0) 50 size_hint_close = (1, 0)
53 size_hint_open = (1, 0.5) 51 size_hint_open = (1, 0.5)
54 52
55 def __init__(self, **kwargs): 53 def __init__(self, **kwargs):
56 super(AddContactMenu, self).__init__(**kwargs) 54 super(AddContactMenu, self).__init__(**kwargs)
61 def addContact(self, contact_jid): 59 def addContact(self, contact_jid):
62 """Actually add the contact 60 """Actually add the contact
63 61
64 @param contact_jid(unicode): jid of the contact to add 62 @param contact_jid(unicode): jid of the contact to add
65 """ 63 """
64 self.hide()
66 contact_jid = contact_jid.strip() 65 contact_jid = contact_jid.strip()
67 # FIXME: trivial jid verification 66 # FIXME: trivial jid verification
68 if not contact_jid or not re.match(r"[^@ ]+@[^@ ]+", contact_jid): 67 if not contact_jid or not re.match(r"[^@ ]+@[^@ ]+", contact_jid):
69 return 68 return
70 contact_jid = jid.JID(contact_jid).bare 69 contact_jid = jid.JID(contact_jid).bare
75 _(u"a contact request has been sent to {contact_jid}").format( 74 _(u"a contact request has been sent to {contact_jid}").format(
76 contact_jid=contact_jid)), 75 contact_jid=contact_jid)),
77 errback=partial(G.host.errback, 76 errback=partial(G.host.errback,
78 title=_(u"can't add contact"), 77 title=_(u"can't add contact"),
79 message=_(u"error while trying to add contact: {msg}"))) 78 message=_(u"error while trying to add contact: {msg}")))
79
80
81 class DelContactMenu(SideMenu):
82 size_hint_close = (1, 0)
83 size_hint_open = (1, 0.5)
84
85 def __init__(self, contact_item, **kwargs):
86 self.contact_item = contact_item
87 super(DelContactMenu, self).__init__(**kwargs)
88
89 def do_delete_contact(self):
80 self.hide() 90 self.hide()
91 G.host.bridge.delContact(self.contact_item.jid.bare,
92 self.contact_item.profile,
93 callback=lambda: G.host.addNote(
94 _(u"contact removed"),
95 _(u"{contact_jid} has been removed from your contacts list").format(
96 contact_jid=self.contact_item.jid.bare)),
97 errback=partial(G.host.errback,
98 title=_(u"can't remove contact"),
99 message=_(u"error while trying to remove contact: {msg}")))
100
81 101
82 102
83 class Avatar(image.Image): 103 class Avatar(image.Image):
84 pass 104 pass
85 105
86 106
87 class ContactItem(ButtonBehavior, BoxLayout): 107 class ContactItem(TouchMenuItemBehaviour, BoxLayout):
88 base_width = dp(150) 108 base_width = dp(150)
89 profile = properties.StringProperty() 109 profile = properties.StringProperty()
90 data = properties.DictProperty() 110 data = properties.DictProperty()
91 jid = properties.StringProperty('') 111 jid = properties.StringProperty('')
92 112
93 def __init__(self, **kwargs): 113 def __init__(self, **kwargs):
94 super(ContactItem, self).__init__(**kwargs) 114 super(ContactItem, self).__init__(**kwargs)
95 115
96 def on_release(self): 116 def do_item_action(self, touch):
97 assert self.profile 117 assert self.profile
98 # XXX: for now clicking on an item launch the corresponding Chat widget 118 # XXX: for now clicking on an item launch the corresponding Chat widget
99 # behaviour should change in the future 119 # behaviour should change in the future
100 try: 120 try:
101 # FIXME: Q&D way to get chat plugin, should be replaced by a clean method 121 # FIXME: Q&D way to get chat plugin, should be replaced by a clean method
108 factory = plg_infos['factory'] 128 factory = plg_infos['factory']
109 G.host.switchWidget(self, factory(plg_infos, 129 G.host.switchWidget(self, factory(plg_infos,
110 jid.JID(self.jid), 130 jid.JID(self.jid),
111 profiles=[self.profile])) 131 profiles=[self.profile]))
112 132
113 133 def getMenuChoices(self):
114 class ContactList(QuickContactList, cagou_widget.CagouWidget, FilterBehavior): 134 choices = []
135 choices.append(dict(text=_(u'delete'),
136 index=len(choices)+1,
137 callback=self.main_wid.removeContact))
138 return choices
139
140
141 class ContactList(QuickContactList, cagou_widget.CagouWidget, FilterBehavior,
142 TouchMenuBehaviour):
115 float_layout = properties.ObjectProperty() 143 float_layout = properties.ObjectProperty()
116 layout = properties.ObjectProperty() 144 layout = properties.ObjectProperty()
117 145
118 def __init__(self, host, target, profiles): 146 def __init__(self, host, target, profiles):
119 QuickContactList.__init__(self, G.host, profiles) 147 QuickContactList.__init__(self, G.host, profiles)
129 """Show the "add a contact" menu""" 157 """Show the "add a contact" menu"""
130 # FIXME: for now we add contact to the first profile we find 158 # FIXME: for now we add contact to the first profile we find
131 profile = next(iter(self.profiles)) 159 profile = next(iter(self.profiles))
132 AddContactMenu(profile=profile).show() 160 AddContactMenu(profile=profile).show()
133 161
162 def removeContact(self, menu_label):
163 item = self.menu_item
164 self.clear_menu()
165 DelContactMenu(contact_item=item).show()
166
134 def onHeaderInputComplete(self, wid, text): 167 def onHeaderInputComplete(self, wid, text):
135 self.do_filter(self.layout.children, 168 self.do_filter(self.layout.children,
136 text, 169 text,
137 lambda c: c.jid, 170 lambda c: c.jid,
138 width_cb=lambda c: c.base_width, 171 width_cb=lambda c: c.base_width,
145 item will be added in a sorted position 178 item will be added in a sorted position
146 @param bare_jid(jid.JID): entity bare JID 179 @param bare_jid(jid.JID): entity bare JID
147 @param profile(unicode): profile where the contact is 180 @param profile(unicode): profile where the contact is
148 """ 181 """
149 data = G.host.contact_lists[profile].getItem(bare_jid) 182 data = G.host.contact_lists[profile].getItem(bare_jid)
150 wid = ContactItem(profile=profile, data=data, jid=bare_jid) 183 wid = ContactItem(profile=profile, data=data, jid=bare_jid, main_wid=self)
151 child_jids = [c.jid for c in reversed(self.layout.children)] 184 child_jids = [c.jid for c in reversed(self.layout.children)]
152 idx = bisect.bisect_right(child_jids, bare_jid) 185 idx = bisect.bisect_right(child_jids, bare_jid)
153 self.layout.add_widget(wid, -idx) 186 self.layout.add_widget(wid, -idx)
154 self._wid_map[(profile, bare_jid)] = wid 187 self._wid_map[(profile, bare_jid)] = wid
155 188
157 log.debug("update: %s %s %s" % (entities, type_, profile)) 190 log.debug("update: %s %s %s" % (entities, type_, profile))
158 if type_ == None or type_ == C.UPDATE_STRUCTURE: 191 if type_ == None or type_ == C.UPDATE_STRUCTURE:
159 log.debug("full contact list update") 192 log.debug("full contact list update")
160 self.layout.clear_widgets() 193 self.layout.clear_widgets()
161 for bare_jid, data in self.items_sorted.iteritems(): 194 for bare_jid, data in self.items_sorted.iteritems():
162 wid = ContactItem(profile=profile, data=data, jid=bare_jid) 195 wid = ContactItem(profile=profile, data=data, jid=bare_jid, main_wid=self)
163 self.layout.add_widget(wid) 196 self.layout.add_widget(wid)
164 self._wid_map[(profile, bare_jid)] = wid 197 self._wid_map[(profile, bare_jid)] = wid
165 elif type_ == C.UPDATE_MODIFY: 198 elif type_ == C.UPDATE_MODIFY:
166 for entity in entities: 199 for entity in entities:
167 entity_bare = entity.bare 200 entity_bare = entity.bare