comparison frontends/primitivus/contact_list.py @ 125:8d611eb9ae48

primitivus: contact list enhancement - primitivus: contact list now display groups and sexy name (instead of bare jid) - primitivus: contact list now show an alert when somebody want to contact you, and its chat window is not on the screen - primitivus: cursor is now visible when going to chat window (useful to go back in logs)
author Goffi <goffi@goffi.org>
date Mon, 12 Jul 2010 17:50:00 +0800
parents 961e0898271f
children 2240f34f6452
comparison
equal deleted inserted replaced
124:961e0898271f 125:8d611eb9ae48
19 along with this program. If not, see <http://www.gnu.org/licenses/>. 19 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 """ 20 """
21 21
22 import urwid 22 import urwid
23 from quick_frontend.quick_contact_list import QuickContactList 23 from quick_frontend.quick_contact_list import QuickContactList
24 from tools.jid import JID
24 import custom_widgets 25 import custom_widgets
25 26
26 27
27 class ContactList(urwid.WidgetWrap, QuickContactList): 28 class ContactList(urwid.WidgetWrap, QuickContactList):
28 signals = ['click','change'] 29 signals = ['click','change']
29 30
30 def __init__(self, host, CM, on_click=None, on_change=None, user_data=None): 31 def __init__(self, host, CM, on_click=None, on_change=None, user_data=None):
31 self.host = host 32 self.host = host
32 33 self.selected = None
33 self.list_wid = custom_widgets.GenericList([], style=['single','no_first_select'], align='left', on_click=self.__contactClicked, on_change=on_change) 34 self.groups={}
34 35 self.alert_jid=set()
36
35 #we now build the widget 37 #we now build the widget
36 frame_body = self.list_wid 38 self.frame = urwid.Frame(self.__buildList())
37 frame = urwid.Frame(frame_body) 39 self.main_widget = custom_widgets.LabelLine(self.frame, custom_widgets.SurroundedText(_("Contacts")))
38 self.main_widget = custom_widgets.LabelLine(frame, custom_widgets.SurroundedText(_("Contacts")))
39 urwid.WidgetWrap.__init__(self, self.main_widget) 40 urwid.WidgetWrap.__init__(self, self.main_widget)
40 if on_click: 41 if on_click:
41 urwid.connect_signal(self, 'click', on_click, user_data) 42 urwid.connect_signal(self, 'click', on_click, user_data)
42 if on_change: 43 if on_change:
43 urwid.connect_signal(self, 'change', on_change, user_data) 44 urwid.connect_signal(self, 'change', on_change, user_data)
44 QuickContactList.__init__(self, CM) 45 QuickContactList.__init__(self, CM)
45 46
46 def __contains__(self, jid): 47 def __contains__(self, jid):
47 contacts = self.list_wid.getAllValues() 48 for group in self.groups:
48 return jid.short in contacts 49 if jid.short in self.groups[group][1]:
50 return True
51 return False
49 52
50 def __contactClicked(self, list_wid): 53 def setFocus(self, name):
54 """give focus to the first group or contact with the given name"""
55 idx = 0
56 for widget in self.frame.body.body:
57 if widget.getValue() == name:
58 self.frame.body.set_focus(idx)
59 return
60 idx+=1
61
62 def putAlert(self, jid):
63 """Put an alert on the jid to get attention from user (e.g. for new message)"""
64 self.alert_jid.add(jid.short)
65 self.frame.body = self.__buildList()
66 self.host.redraw()
67
68 def __groupClicked(self, group_wid):
69 group = self.groups[group_wid.getValue()]
70 group[0] = not group[0]
71 self.frame.body = self.__buildList()
72 self.host.redraw()
73 self.setFocus(group_wid.getValue())
74
75 def __contactClicked(self, contact_wid, selected):
76 self.selected = contact_wid.data
77 for widget in self.frame.body.body:
78 if widget.__class__ == custom_widgets.SelectableText:
79 widget.setState(widget.data == self.selected, invisible=True)
80 if self.selected in self.alert_jid:
81 self.alert_jid.remove(self.selected)
82 self.frame.body = self.__buildList()
83 self.host.redraw()
51 self._emit('click') 84 self._emit('click')
85
86 def __buildContact(self, content, param_contacts):
87 """Add contact representation in widget list
88 @param content: widget list, e.g. SimpleListWalker
89 @param contacts: list of JID"""
90 contacts = list(param_contacts)
91 contacts.sort()
92 for contact in contacts:
93 jid=JID(contact)
94 name = self.CM.getAttr(jid,'name')
95 nick = self.CM.getAttr(jid,'nick')
96 display = nick or name or jid.node or jid.short
97 header = '(*) ' if contact in self.alert_jid else ''
98 widget = custom_widgets.SelectableText(display, selected = contact==self.selected, header=header, data=contact)
99 if contact in self.alert_jid:
100 widget.setAttribute('default','alert')
101 content.append(widget)
102 urwid.connect_signal(widget, 'change', self.__contactClicked)
103
104 def __buildList(self):
105 """Build the main contact list widget"""
106 content = urwid.SimpleListWalker([])
107 group_keys = self.groups.keys()
108 group_keys.sort()
109 for key in group_keys:
110 unfolded = self.groups[key][0]
111 if key!=None:
112 header = '[-]' if unfolded else '[+]'
113 widget = custom_widgets.ClickableText(key,header=header+' ')
114 content.append(widget)
115 urwid.connect_signal(widget, 'click', self.__groupClicked)
116 if unfolded:
117 self.__buildContact(content, self.groups[key][1])
118 return urwid.ListBox(content)
52 119
53 def get_contact(self): 120 def get_contact(self):
54 """Return contact currently selected""" 121 """Return contact currently selected"""
55 return self.list_wid.getSelectedValue() 122 return self.selected
56 123
57 def clear_contacts(self): 124 def clear_contacts(self):
58 """clear all the contact list""" 125 """clear all the contact list"""
59 self.list_wid.changeValues([]) 126 self.groups={}
60 127
61 def replace(self, jid, groups=None): 128 def replace(self, jid, groups=[None]):
62 """add a contact to the list if doesn't exist, else update it""" 129 """add a contact to the list if doesn't exist, else update it"""
63 contacts = self.list_wid.getAllValues() 130 assert groups.__class__ == list
131 assert jid.__class__ == JID
132 if not groups:
133 groups=[None]
134 for group in groups:
135 if not self.groups.has_key(group):
136 self.groups[group] = [True,set()] #[unfold,list_of_contacts]
137 self.groups[group][1].add(jid.short)
138 self.frame.body = self.__buildList()
139 self.host.redraw()
140
141
142 """contacts = self.list_wid.getAllValues()
64 if jid.short not in contacts: 143 if jid.short not in contacts:
65 contacts.append(jid.short) 144 contacts.append(jid.short)
66 contacts.sort() 145 contacts.sort()
67 self.list_wid.changeValues(contacts) 146 self.list_wid.changeValues(contacts)
68 self._emit('change') 147 self._emit('change')"""
69 148
70 def disconnect(self, jid): 149 def disconnect(self, jid):
71 """mark a contact disconnected""" 150 """mark a contact disconnected"""
72 self.remove(jid) 151 self.remove(jid.short)
73 152
74 def remove(self, jid): 153 def remove(self, jid):
75 """remove a contact from the list""" 154 """remove a contact from the list"""
76 self.list_wid.deleteValue(jid.short) 155 groups_to_remove = []
156 for group in self.groups:
157 contacts = self.groups[group][1]
158 if jid.short in contacts:
159 contacts.remove(jid.short)
160 if not len(contacts):
161 groups_to_remove.append(group)
162 for group in groups_to_remove:
163 del self.groups[group]
164 self.frame.body = self.__buildList()
165 self.host.redraw()
77 166
78 def add(self, jid, param_groups=None): 167 def add(self, jid, param_groups=[None]):
79 """add a contact to the list""" 168 """add a contact to the list"""
80 self.replace(jid) 169 self.replace(jid,param_groups)
81 170