changeset 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 7ea6d5a86e58
children 6821fc06a324
files frontends/src/primitivus/chat.py frontends/src/primitivus/primitivus
diffstat 2 files changed, 126 insertions(+), 63 deletions(-) [+]
line wrap: on
line diff
--- a/frontends/src/primitivus/chat.py	Thu Sep 05 20:48:47 2013 +0200
+++ b/frontends/src/primitivus/chat.py	Sun Sep 08 19:13:02 2013 +0200
@@ -145,7 +145,22 @@
                 self.__appendPresentPanel()
 
     def __getDecoration(self, widget):
-        return sat_widgets.LabelLine(widget, sat_widgets.SurroundedText(unicode(unescapePrivate(self.target))))
+        return sat_widgets.LabelLine(widget, self.__getSurrendedText())
+
+    def __getSurrendedText(self):
+        """Get the text to be displayed as the dialog title."""
+        if not hasattr(self, "surrended_text"):
+            self.__setSurrendedText()
+        return self.surrended_text
+
+    def __setSurrendedText(self, state=None):
+        """Set the text to be displayed as the dialog title
+        @param stat: chat state of the contact
+        """
+        text = unicode(unescapePrivate(self.target))
+        if state:
+            text += " (" + state + ")"
+        self.surrended_text = sat_widgets.SurroundedText(text)
 
     def showDecoration(self, show=True):
         """Show/Hide the decoration around the chat window"""
@@ -155,6 +170,18 @@
             main_widget = self.pile
         self._w = main_widget
 
+    def updateChatState(self, state):
+        """Update the chat state of the contact.
+        @param state: new state to set
+        """
+        if (self.type == 'one2one'):
+            self.__setSurrendedText(state)
+            self.showDecoration()
+            self.host.redraw()
+        elif (self.type == 'group'):
+            # TODO: chat state for groupchat
+            pass
+
     def _presentClicked(self, list_wid, clicked_wid):
         assert(self.type == 'group')
         nick = clicked_wid.getValue()
--- a/frontends/src/primitivus/primitivus	Thu Sep 05 20:48:47 2013 +0200
+++ b/frontends/src/primitivus/primitivus	Sun Sep 08 19:13:02 2013 +0200
@@ -49,6 +49,85 @@
     def createChat(self, target):
         return Chat(target, self.host)
 
+
+class EditBar(sat_widgets.ModalEdit):
+    """
+    The modal edit bar where you would enter messages and commands.
+    """
+
+    def __init__(self, app):
+        modes = {None: ('NORMAL', u''),
+                 'i': ('INSERTION', u'> '),
+                 ':': ('COMMAND', u':')} #XXX: captions *MUST* be unicode
+        super(EditBar, self).__init__(modes)
+        self.app = app
+        self.setCompletionMethod(self._text_completion)
+        urwid.connect_signal(self, 'click', self.onTextEntered)
+
+    def _text_completion(self, text, completion_data, mode):
+        if mode == 'INSERTION':
+            return self._nick_completion(text, completion_data)
+        else:
+            return text
+
+    def _nick_completion(self, text, completion_data):
+        """Completion method which complete pseudo in group chat
+        for params, see AdvancedEdit"""
+        contact = self.app.contact_list.getContact() ###Based on the fact that there is currently only one contact selectable at once
+        if contact:
+            chat = self.app.chat_wins[contact]
+            if chat.type != "group":
+                return text
+            space = text.rfind(" ")
+            start = text[space+1:]
+            nicks = list(chat.occupants)
+            nicks.sort()
+            try:
+                start_idx=nicks.index(completion_data['last_nick'])+1
+                if start_idx == len(nicks):
+                    start_idx = 0
+            except (KeyError,ValueError):
+                start_idx = 0
+            for idx in range(start_idx,len(nicks)) + range(0,start_idx):
+                if nicks[idx].lower().startswith(start.lower()):
+                    completion_data['last_nick'] = nicks[idx]
+                    return text[:space+1] + nicks[idx] + (': ' if space < 0 else '')
+        return text
+
+    def onTextEntered(self, editBar):
+        """Called when text is entered in the main edit bar"""
+        if self.mode == 'INSERTION':
+            contact = self.app.contact_list.getContact() ###Based on the fact that there is currently only one contact selectableat once
+            if contact:
+                chat = self.app.chat_wins[contact]
+                try:
+                    self.app.sendMessage(contact,
+                                     editBar.get_edit_text(),
+                                     mess_type = "groupchat" if chat.type == 'group' else "chat",
+                                     profile_key=self.app.profile)
+                except:
+                    self.app.notify(_("Error while sending message"))
+                editBar.set_edit_text('')
+        elif self.mode == 'COMMAND':
+            self.commandHandler()
+
+    def commandHandler(self):
+        #TODO: separate class with auto documentation (with introspection)
+        #      and completion method
+        command = self.get_edit_text()
+        if command == 'quit':
+            self.app.onExit()
+            raise urwid.ExitMainLoop()
+
+    def keypress(self, size, key):
+        """Callback when a key is pressed. Send "composing" states."""
+        if key != "enter":
+            contact = self.app.contact_list.getContact()
+            if contact:
+                self.app.bridge.chatStateComposing(contact, self.app.profile)
+        return super(EditBar, self).keypress(size, key) 
+
+
 class PrimitivusApp(QuickApp):
 
     def __init__(self):
@@ -172,13 +251,6 @@
         except AttributeError:
             return input
 
-    def commandHandler(self, editBar):
-        #TODO: separate class with auto documentation (with introspection)
-        #      and completion method
-        command = editBar.get_edit_text()
-        if command == 'quit':
-            self.onExit()
-            raise urwid.ExitMainLoop()
 
     def __buildMenuRoller(self):
         menu = sat_widgets.Menu(self.loop)
@@ -215,48 +287,11 @@
         #self.center_part = urwid.Columns([('weight',2,self.contact_list),('weight',8,Chat('',self))])
         self.center_part = urwid.Columns([('weight',2,self.contact_list), ('weight',8,urwid.Filler(urwid.Text('')))])
 
-        modes = {None: ('NORMAL', u''),
-                 'i': ('INSERTION', u'> '),
-                 ':': ('COMMAND', u':')} #XXX: captions *MUST* be unicode
-        self.editBar = sat_widgets.ModalEdit(modes)
-        self.editBar.setCompletionMethod(self._text_completion)
-        urwid.connect_signal(self.editBar,'click',self.onTextEntered)
+        self.editBar = EditBar(self)
         self.menu_roller = self.__buildMenuRoller()
         self.main_widget = sat_widgets.FocusFrame(self.center_part, header=self.menu_roller, footer=self.editBar, focus_part='footer')
         return self.main_widget
 
-    def _text_completion(self, text, completion_data, mode):
-        if mode == 'INSERTION':
-            return self._nick_completion(text, completion_data)
-        else:
-            return text
-
-    def _nick_completion(self, text, completion_data):
-        """Completion method which complete pseudo in group chat
-        for params, see AdvancedEdit"""
-        contact = self.contact_list.getContact() ###Based on the fact that there is currently only one contact selectable at once
-        if contact:
-            chat = self.chat_wins[contact]
-            if chat.type != "group":
-                return text
-            space = text.rfind(" ")
-            start = text[space+1:]
-            nicks = list(chat.occupants)
-            nicks.sort()
-            try:
-                start_idx=nicks.index(completion_data['last_nick'])+1
-                if start_idx == len(nicks):
-                    start_idx = 0
-            except (KeyError,ValueError):
-                start_idx = 0
-            for idx in range(start_idx,len(nicks)) + range(0,start_idx):
-                if nicks[idx].lower().startswith(start.lower()):
-                    completion_data['last_nick'] = nicks[idx]
-                    return text[:space+1] + nicks[idx] + (': ' if space < 0 else '')
-        return text
-
-
-
     def plug_profile(self, profile_key='@DEFAULT@'):
         self.loop.widget = self.__buildMainWidget()
         self.redraw()
@@ -320,23 +355,6 @@
             self.center_part.widget_list[1] = self.chat_wins[contact]
             self.menu_roller.addMenu(_('Chat menu'), self.chat_wins[contact].getMenu())
 
-    def onTextEntered(self, editBar):
-        """Called when text is entered in the main edit bar"""
-        if self.mode == 'INSERTION':
-            contact = self.contact_list.getContact() ###Based on the fact that there is currently only one contact selectableat once
-            if contact:
-                chat = self.chat_wins[contact]
-                try:
-                    self.sendMessage(contact,
-                                     editBar.get_edit_text(),
-                                     mess_type = "groupchat" if chat.type == 'group' else "chat",
-                                     profile_key=self.profile)
-                except:
-                    self.notify(_("Error while sending message"))
-                editBar.set_edit_text('')
-        elif self.mode == 'COMMAND':
-            self.commandHandler(editBar)
-
     def newMessage(self, from_jid, to_jid, msg, _type, extra, profile):
         QuickApp.newMessage(self, from_jid, to_jid, msg, _type, extra, profile)
 
@@ -576,6 +594,24 @@
             self.showPopUp(sat_widgets.Alert(_("Error"), _("Can't get search UI"), ok_cb=self.removePopUp))
         self.bridge.searchRequest(search_jid, dict(data), self.profile, callback=success, errback=failure)
 
+    def chatStateReceived(self, from_jid_s, state, profile):
+        """Signal observer to display a contact chat state
+        @param from_jid_s: contact who sent his new state
+        @state: state
+        @profile: current profile
+        """
+        if not self.check_profile(profile):
+            return
+
+        if from_jid_s == "@ALL@":
+            for win in self.chat_wins:
+                self.chat_wins[win].updateChatState(state)
+            return
+
+        from_bare = JID(from_jid_s).short
+        if from_bare in self.chat_wins:
+            self.chat_wins[from_bare].updateChatState(state)
+
 sat = PrimitivusApp()
 sat.start()