Mercurial > libervia-backend
comparison frontends/src/primitivus/primitivus @ 637:3b02554d4c8b
primitivus: chat state implementation
for now chat states are displayed in primitivus surrended text (after the contact's name)
author | souliane <souliane@mailoo.org> |
---|---|
date | Sun, 08 Sep 2013 19:13:02 +0200 |
parents | ca2cae6b2c6d |
children | 6821fc06a324 |
comparison
equal
deleted
inserted
replaced
636:7ea6d5a86e58 | 637:3b02554d4c8b |
---|---|
46 class ChatList(QuickChatList): | 46 class ChatList(QuickChatList): |
47 """This class manage the list of chat windows""" | 47 """This class manage the list of chat windows""" |
48 | 48 |
49 def createChat(self, target): | 49 def createChat(self, target): |
50 return Chat(target, self.host) | 50 return Chat(target, self.host) |
51 | |
52 | |
53 class EditBar(sat_widgets.ModalEdit): | |
54 """ | |
55 The modal edit bar where you would enter messages and commands. | |
56 """ | |
57 | |
58 def __init__(self, app): | |
59 modes = {None: ('NORMAL', u''), | |
60 'i': ('INSERTION', u'> '), | |
61 ':': ('COMMAND', u':')} #XXX: captions *MUST* be unicode | |
62 super(EditBar, self).__init__(modes) | |
63 self.app = app | |
64 self.setCompletionMethod(self._text_completion) | |
65 urwid.connect_signal(self, 'click', self.onTextEntered) | |
66 | |
67 def _text_completion(self, text, completion_data, mode): | |
68 if mode == 'INSERTION': | |
69 return self._nick_completion(text, completion_data) | |
70 else: | |
71 return text | |
72 | |
73 def _nick_completion(self, text, completion_data): | |
74 """Completion method which complete pseudo in group chat | |
75 for params, see AdvancedEdit""" | |
76 contact = self.app.contact_list.getContact() ###Based on the fact that there is currently only one contact selectable at once | |
77 if contact: | |
78 chat = self.app.chat_wins[contact] | |
79 if chat.type != "group": | |
80 return text | |
81 space = text.rfind(" ") | |
82 start = text[space+1:] | |
83 nicks = list(chat.occupants) | |
84 nicks.sort() | |
85 try: | |
86 start_idx=nicks.index(completion_data['last_nick'])+1 | |
87 if start_idx == len(nicks): | |
88 start_idx = 0 | |
89 except (KeyError,ValueError): | |
90 start_idx = 0 | |
91 for idx in range(start_idx,len(nicks)) + range(0,start_idx): | |
92 if nicks[idx].lower().startswith(start.lower()): | |
93 completion_data['last_nick'] = nicks[idx] | |
94 return text[:space+1] + nicks[idx] + (': ' if space < 0 else '') | |
95 return text | |
96 | |
97 def onTextEntered(self, editBar): | |
98 """Called when text is entered in the main edit bar""" | |
99 if self.mode == 'INSERTION': | |
100 contact = self.app.contact_list.getContact() ###Based on the fact that there is currently only one contact selectableat once | |
101 if contact: | |
102 chat = self.app.chat_wins[contact] | |
103 try: | |
104 self.app.sendMessage(contact, | |
105 editBar.get_edit_text(), | |
106 mess_type = "groupchat" if chat.type == 'group' else "chat", | |
107 profile_key=self.app.profile) | |
108 except: | |
109 self.app.notify(_("Error while sending message")) | |
110 editBar.set_edit_text('') | |
111 elif self.mode == 'COMMAND': | |
112 self.commandHandler() | |
113 | |
114 def commandHandler(self): | |
115 #TODO: separate class with auto documentation (with introspection) | |
116 # and completion method | |
117 command = self.get_edit_text() | |
118 if command == 'quit': | |
119 self.app.onExit() | |
120 raise urwid.ExitMainLoop() | |
121 | |
122 def keypress(self, size, key): | |
123 """Callback when a key is pressed. Send "composing" states.""" | |
124 if key != "enter": | |
125 contact = self.app.contact_list.getContact() | |
126 if contact: | |
127 self.app.bridge.chatStateComposing(contact, self.app.profile) | |
128 return super(EditBar, self).keypress(size, key) | |
129 | |
51 | 130 |
52 class PrimitivusApp(QuickApp): | 131 class PrimitivusApp(QuickApp): |
53 | 132 |
54 def __init__(self): | 133 def __init__(self): |
55 QuickApp.__init__(self) | 134 QuickApp.__init__(self) |
170 try: | 249 try: |
171 return self.menu_roller.checkShortcuts(input) | 250 return self.menu_roller.checkShortcuts(input) |
172 except AttributeError: | 251 except AttributeError: |
173 return input | 252 return input |
174 | 253 |
175 def commandHandler(self, editBar): | |
176 #TODO: separate class with auto documentation (with introspection) | |
177 # and completion method | |
178 command = editBar.get_edit_text() | |
179 if command == 'quit': | |
180 self.onExit() | |
181 raise urwid.ExitMainLoop() | |
182 | 254 |
183 def __buildMenuRoller(self): | 255 def __buildMenuRoller(self): |
184 menu = sat_widgets.Menu(self.loop) | 256 menu = sat_widgets.Menu(self.loop) |
185 general = _("General") | 257 general = _("General") |
186 menu.addMenu(general, _("Connect"), self.onConnectRequest) | 258 menu.addMenu(general, _("Connect"), self.onConnectRequest) |
213 def __buildMainWidget(self): | 285 def __buildMainWidget(self): |
214 self.contact_list = ContactList(self, on_click = self.contactSelected, on_change=lambda w: self.redraw()) | 286 self.contact_list = ContactList(self, on_click = self.contactSelected, on_change=lambda w: self.redraw()) |
215 #self.center_part = urwid.Columns([('weight',2,self.contact_list),('weight',8,Chat('',self))]) | 287 #self.center_part = urwid.Columns([('weight',2,self.contact_list),('weight',8,Chat('',self))]) |
216 self.center_part = urwid.Columns([('weight',2,self.contact_list), ('weight',8,urwid.Filler(urwid.Text('')))]) | 288 self.center_part = urwid.Columns([('weight',2,self.contact_list), ('weight',8,urwid.Filler(urwid.Text('')))]) |
217 | 289 |
218 modes = {None: ('NORMAL', u''), | 290 self.editBar = EditBar(self) |
219 'i': ('INSERTION', u'> '), | |
220 ':': ('COMMAND', u':')} #XXX: captions *MUST* be unicode | |
221 self.editBar = sat_widgets.ModalEdit(modes) | |
222 self.editBar.setCompletionMethod(self._text_completion) | |
223 urwid.connect_signal(self.editBar,'click',self.onTextEntered) | |
224 self.menu_roller = self.__buildMenuRoller() | 291 self.menu_roller = self.__buildMenuRoller() |
225 self.main_widget = sat_widgets.FocusFrame(self.center_part, header=self.menu_roller, footer=self.editBar, focus_part='footer') | 292 self.main_widget = sat_widgets.FocusFrame(self.center_part, header=self.menu_roller, footer=self.editBar, focus_part='footer') |
226 return self.main_widget | 293 return self.main_widget |
227 | |
228 def _text_completion(self, text, completion_data, mode): | |
229 if mode == 'INSERTION': | |
230 return self._nick_completion(text, completion_data) | |
231 else: | |
232 return text | |
233 | |
234 def _nick_completion(self, text, completion_data): | |
235 """Completion method which complete pseudo in group chat | |
236 for params, see AdvancedEdit""" | |
237 contact = self.contact_list.getContact() ###Based on the fact that there is currently only one contact selectable at once | |
238 if contact: | |
239 chat = self.chat_wins[contact] | |
240 if chat.type != "group": | |
241 return text | |
242 space = text.rfind(" ") | |
243 start = text[space+1:] | |
244 nicks = list(chat.occupants) | |
245 nicks.sort() | |
246 try: | |
247 start_idx=nicks.index(completion_data['last_nick'])+1 | |
248 if start_idx == len(nicks): | |
249 start_idx = 0 | |
250 except (KeyError,ValueError): | |
251 start_idx = 0 | |
252 for idx in range(start_idx,len(nicks)) + range(0,start_idx): | |
253 if nicks[idx].lower().startswith(start.lower()): | |
254 completion_data['last_nick'] = nicks[idx] | |
255 return text[:space+1] + nicks[idx] + (': ' if space < 0 else '') | |
256 return text | |
257 | |
258 | |
259 | 294 |
260 def plug_profile(self, profile_key='@DEFAULT@'): | 295 def plug_profile(self, profile_key='@DEFAULT@'): |
261 self.loop.widget = self.__buildMainWidget() | 296 self.loop.widget = self.__buildMainWidget() |
262 self.redraw() | 297 self.redraw() |
263 QuickApp.plug_profile(self, profile_key) | 298 QuickApp.plug_profile(self, profile_key) |
317 contact = contact_list.getContact() | 352 contact = contact_list.getContact() |
318 if contact: | 353 if contact: |
319 assert(len(self.center_part.widget_list)==2) | 354 assert(len(self.center_part.widget_list)==2) |
320 self.center_part.widget_list[1] = self.chat_wins[contact] | 355 self.center_part.widget_list[1] = self.chat_wins[contact] |
321 self.menu_roller.addMenu(_('Chat menu'), self.chat_wins[contact].getMenu()) | 356 self.menu_roller.addMenu(_('Chat menu'), self.chat_wins[contact].getMenu()) |
322 | |
323 def onTextEntered(self, editBar): | |
324 """Called when text is entered in the main edit bar""" | |
325 if self.mode == 'INSERTION': | |
326 contact = self.contact_list.getContact() ###Based on the fact that there is currently only one contact selectableat once | |
327 if contact: | |
328 chat = self.chat_wins[contact] | |
329 try: | |
330 self.sendMessage(contact, | |
331 editBar.get_edit_text(), | |
332 mess_type = "groupchat" if chat.type == 'group' else "chat", | |
333 profile_key=self.profile) | |
334 except: | |
335 self.notify(_("Error while sending message")) | |
336 editBar.set_edit_text('') | |
337 elif self.mode == 'COMMAND': | |
338 self.commandHandler(editBar) | |
339 | 357 |
340 def newMessage(self, from_jid, to_jid, msg, _type, extra, profile): | 358 def newMessage(self, from_jid, to_jid, msg, _type, extra, profile): |
341 QuickApp.newMessage(self, from_jid, to_jid, msg, _type, extra, profile) | 359 QuickApp.newMessage(self, from_jid, to_jid, msg, _type, extra, profile) |
342 | 360 |
343 if not from_jid in self.contact_list and from_jid.short != self.profiles[profile]['whoami'].short: | 361 if not from_jid in self.contact_list and from_jid.short != self.profiles[profile]['whoami'].short: |
574 ui.show('window') | 592 ui.show('window') |
575 def failure(error): | 593 def failure(error): |
576 self.showPopUp(sat_widgets.Alert(_("Error"), _("Can't get search UI"), ok_cb=self.removePopUp)) | 594 self.showPopUp(sat_widgets.Alert(_("Error"), _("Can't get search UI"), ok_cb=self.removePopUp)) |
577 self.bridge.searchRequest(search_jid, dict(data), self.profile, callback=success, errback=failure) | 595 self.bridge.searchRequest(search_jid, dict(data), self.profile, callback=success, errback=failure) |
578 | 596 |
597 def chatStateReceived(self, from_jid_s, state, profile): | |
598 """Signal observer to display a contact chat state | |
599 @param from_jid_s: contact who sent his new state | |
600 @state: state | |
601 @profile: current profile | |
602 """ | |
603 if not self.check_profile(profile): | |
604 return | |
605 | |
606 if from_jid_s == "@ALL@": | |
607 for win in self.chat_wins: | |
608 self.chat_wins[win].updateChatState(state) | |
609 return | |
610 | |
611 from_bare = JID(from_jid_s).short | |
612 if from_bare in self.chat_wins: | |
613 self.chat_wins[from_bare].updateChatState(state) | |
614 | |
579 sat = PrimitivusApp() | 615 sat = PrimitivusApp() |
580 sat.start() | 616 sat.start() |
581 | 617 |