comparison src/browser/sat_browser/contact_panel.py @ 648:6d3142b782c3 frontends_multi_profiles

browser_side: classes reorganisation: - moved widgets in dedicated modules (base, contact, editor, libervia) and a widget module for single classes - same thing for panels (base, main, contact) - libervia_widget mix main panels and widget and drag n drop for technical reasons (see comments) - renamed WebPanel to WebWidget
author Goffi <goffi@goffi.org>
date Thu, 26 Feb 2015 18:10:54 +0100
parents src/browser/sat_browser/base_panels.py@e0021d571eef
children 267761bf7f08
comparison
equal deleted inserted replaced
647:e0021d571eef 648:6d3142b782c3
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3
4 # Libervia: a Salut à Toi frontend
5 # Copyright (C) 2011, 2012, 2013, 2014 Jérôme Poisson <goffi@goffi.org>
6
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU Affero General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
11
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU Affero General Public License for more details.
16
17 # You should have received a copy of the GNU Affero General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20 """ Contacts / jids related panels """
21
22 import pyjd # this is dummy in pyjs
23 from sat.core.log import getLogger
24 log = getLogger(__name__)
25 from sat_frontends.tools import jid
26
27 from pyjamas.ui.AbsolutePanel import AbsolutePanel
28 from pyjamas.ui.VerticalPanel import VerticalPanel
29 from pyjamas.ui.HTML import HTML
30
31 import html_tools
32 import contact_widget
33 from constants import Const as C
34
35
36 # FIXME: must be removed
37 class Occupant(HTML):
38 """Occupant of a MUC room"""
39
40 def __init__(self, nick, state=None, special=""):
41 """
42 @param nick: the user nickname
43 @param state: the user chate state (XEP-0085)
44 @param special: a string of symbols (e.g: for activities)
45 """
46 HTML.__init__(self, StyleName="occupant")
47 self.nick = nick
48 self._state = state
49 self.special = special
50 self._refresh()
51
52 def __str__(self):
53 return self.nick
54
55 def setState(self, state):
56 self._state = state
57 self._refresh()
58
59 def addSpecial(self, special):
60 """@param special: unicode"""
61 if special not in self.special:
62 self.special += special
63 self._refresh()
64
65 def removeSpecials(self, special):
66 """@param special: unicode or list"""
67 if not isinstance(special, list):
68 special = [special]
69 for symbol in special:
70 self.special = self.special.replace(symbol, "")
71 self._refresh()
72
73 def _refresh(self):
74 state = (' %s' % C.MUC_USER_STATES[self._state]) if self._state else ''
75 special = "" if len(self.special) == 0 else " %s" % self.special
76 self.setHTML("%s%s%s" % (html_tools.html_sanitize(self.nick), special, state))
77
78
79 class ContactsPanel(VerticalPanel):
80 """ContactList graphic representation
81
82 Special features like popup menu panel or changing the contact states must be done in a sub-class.
83 """
84
85 def __init__(self, parent, on_click=None, handle_menu=True):
86 """
87 @param on_click (callable): click callback (used if ContactBox is created)
88 @param handle_menu (bool): if True, bind a popup menu to the avatar (used if ContactBox is created)
89 """ # FIXME
90 VerticalPanel.__init__(self)
91 self._parent = parent
92 self.host = parent.host
93 self._contacts = {} # entity jid to ContactBox map
94 self.click_listener = None
95 self.handle_menu = handle_menu
96
97 if on_click is not None:
98 self.onClick = on_click
99
100 def display(self, jids):
101 """Display a contact in the list.
102
103 @param jids (list[jid.JID]): jids to display (the order is kept)
104 @param name (unicode): optional name of the contact
105 """
106 # FIXME: we do a full clear and add boxes after, we should only remove recently hidden boxes and add new ones, and re-order
107 current = [box.jid for box in self.children if isinstance(box, contact_widget.ContactBox)]
108 if current == jids:
109 # the display doesn't change
110 return
111 self.clear()
112 for jid_ in jids:
113 assert isinstance(jid_, jid.JID)
114 box = self.getContactBox(jid_)
115 VerticalPanel.append(self, box)
116
117 def isContactPresent(self, contact_jid):
118 """Return True if a contact is present in the panel"""
119 return contact_jid in self._contacts
120
121 def getContacts(self):
122 return self._contacts
123
124 def getContactBox(self, contact_jid):
125 """get the Contactbox of a contact
126
127 if the Contactbox doesn't exists, it will be created
128 @param contact_jid (jid.JID): the contact
129 @return: ContactBox instance
130 """
131 try:
132 return self._contacts[contact_jid.bare]
133 except KeyError:
134 box = contact_widget.ContactBox(self, contact_jid)
135 self._contacts[contact_jid.bare] = box
136 return box
137
138 def updateAvatar(self, jid_, url):
139 """Update the avatar of the given contact
140
141 @param jid_ (jid.JID): contact jid
142 @param url (unicode): image url
143 """
144 try:
145 self.getContactBox(jid_).updateAvatar(url)
146 except TypeError:
147 pass
148
149 def updateNick(self, jid_, new_nick):
150 """Update the avatar of the given contact
151
152 @param jid_ (jid.JID): contact jid
153 @param new_nick (unicode): new nick of the contact
154 """
155 try:
156 self.getContactBox(jid_).updateNick(new_nick)
157 except TypeError:
158 pass
159
160
161
162 # FIXME: must be removed and ContactsPanel must be used instead
163 class OccupantsList(AbsolutePanel):
164 """Panel user to show occupants of a room"""
165
166 def __init__(self):
167 AbsolutePanel.__init__(self)
168 self.occupants_list = {}
169 self.setStyleName('occupantsList')
170
171 def addOccupant(self, nick):
172 if nick in self.occupants_list:
173 return
174 _occupant = Occupant(nick)
175 self.occupants_list[nick] = _occupant
176 self.add(_occupant)
177
178 def removeOccupant(self, nick):
179 try:
180 self.remove(self.occupants_list[nick])
181 except KeyError:
182 log.error("trying to remove an unexisting nick")
183
184 def getOccupantBox(self, nick):
185 """Get the widget element of the given nick.
186
187 @return: Occupant
188 """
189 try:
190 return self.occupants_list[nick]
191 except KeyError:
192 return None
193
194 def clear(self):
195 self.occupants_list.clear()
196 AbsolutePanel.clear(self)
197
198 def updateSpecials(self, occupants=[], html=""):
199 """Set the specified html "symbol" to the listed occupants,
200 and eventually remove it from the others (if they got it).
201 This is used for example to visualize who is playing a game.
202 @param occupants: list of the occupants that need the symbol
203 @param html: unicode symbol (actually one character or more)
204 or a list to assign different symbols of the same family.
205 """
206 index = 0
207 special = html
208 for occupant in self.occupants_list.keys():
209 if occupant in occupants:
210 if isinstance(html, list):
211 special = html[index]
212 index = (index + 1) % len(html)
213 self.occupants_list[occupant].addSpecial(special)
214 else:
215 self.occupants_list[occupant].removeSpecials(html)