Changeset 4671


Ignore:
Timestamp:
Dec 4, 2013 2:46:42 AM (7 years ago)
Author:
nanang
Message:

Re #1708: Initial work on chat window.

Location:
pjproject/branches/projects/pjsua2/pjsip-apps/src/pygui
Files:
2 added
3 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/projects/pjsua2/pjsip-apps/src/pygui/account.py

    r4663 r4671  
    3535import application 
    3636import call 
     37import chat as ch 
    3738 
    3839# Account class 
     
    4849                self.cfgChanged = False 
    4950                self.buddyList = [] 
    50                 self.callList = [] 
    51  
     51                self.chatList = [] 
     52 
     53        def findBuddy(self, uri): 
     54                # TODO: proper URI comparison 
     55                for bud in self.buddyList: 
     56                        if bud.cfg.uri in uri or uri in bud.cfg.uri: 
     57                                return bud 
     58                return None 
     59                 
     60        def findChat(self, buddy, call_inst = None): 
     61                for chat in self.chatList: 
     62                        if chat.isBuddyParticipant(buddy): 
     63                                if call_inst and chat.isCallRegistered(call_inst): 
     64                                        return chat 
     65                                elif not call_inst and chat.isPrivate(): 
     66                                        return chat 
     67                return None 
     68         
     69        def newChat(self, buddy): 
     70                chat = ch.Chat(self, buddy) 
     71                self.chatList.append(chat) 
     72                return chat 
     73         
    5274        def statusText(self): 
    5375                status = '?' 
     
    7597                        status = '- not created -' 
    7698                return status 
    77          
    78         def makeCall(self): 
    79                 mycall = call.Call(self.app, self, pj.PJSUA_INVALID_ID) 
    80                 callPrm = pj.CallOpParam() 
    81                 callPrm.opt.audioCount = 1 
    82                 callPrm.opt.videoCount = 0 
    83                 mycall.uri = "sip:test1@pjsip.org" 
    84                 self.callList.append(mycall) 
    85                 mycall.makeCall(mycall.uri, callPrm) 
    86          
     99                 
    87100        def onRegState(self, prm): 
    88101                self.app.updateAccount(self) 
    89102 
    90103        def onIncomingCall(self, prm): 
    91                 mycall = call.Call(self.app, self, prm.callId) 
    92                 self.callList.append(mycall) 
    93                 self.app.updateCall(self) 
    94                 callPrm = pj.CallOpParam() 
    95                 msg = "Incoming call for account '%s'" % self.cfg.idUri 
    96                 if msgbox.askquestion(msg, 'Accept call?', default=msgbox.YES) == u'yes': 
    97                         callPrm.statusCode = 200 
    98                         mycall.answer(callPrm) 
    99                 else: 
    100                         mycall.hangup(callPrm) 
    101  
    102  
     104                c = call.Call(self, call_id=prm.callId) 
     105                call_prm = pj.CallOpParam() 
     106                call_prm.statusCode = 180 
     107                c.answer(call_prm) 
     108                ci = c.getInfo() 
     109                msg = "Incoming call for account '%s'" % self.cfg.idUri 
     110                if msgbox.askquestion(msg, "Accept call from '%s'?" % (ci.remoteURI), default=msgbox.YES) == u'yes': 
     111                        call_prm.statusCode = 200 
     112                        c.answer(call_prm) 
     113                         
     114                        # create chat instance 
     115                        bud = self.findBuddy(ci.remoteURI) 
     116                        if not bud: return 
     117                        chat = self.findChat(bud) 
     118                        if not chat: chat = self.newChat(bud, c) 
     119                         
     120                        chat.registerCall(bud, c) 
     121                        chat.showWindow() 
     122                else: 
     123                        c.hangup(call_prm) 
     124                         
     125        def onInstantMessage(self, prm): 
     126                bud = self.findBuddy(prm.fromUri) 
     127                if not bud: return 
     128                chat = self.findChat(bud) 
     129                if not chat: chat = self.newChat(bud) 
     130                         
     131                chat.addMessage(bud.cfg.uri, prm.msgBody) 
     132                chat.showWindow() 
     133                 
     134        def onInstantMessageStatus(self, prm): 
     135                if prm.code/100 == 2: return 
     136                 
     137                bud = self.findBuddy(prm.toUri) 
     138                if not bud: return 
     139                chat = self.findChat(bud) 
     140                if not chat: return 
     141                 
     142                chat.addMessage(None, "Failed sending message to '%s': %s" % (bud.cfg.uri, prm.reason)) 
     143                 
     144        def onTypingIndication(self, prm): 
     145                bud = self.findBuddy(prm.fromUri) 
     146                if not bud: return 
     147                chat = self.findChat(bud) 
     148                if not chat: return 
     149                 
     150                chat.setTypingIndication(bud.cfg.uri, prm.isTyping) 
     151 
     152                 
    103153# Account frame, to list accounts 
    104154class AccountListFrame(ttk.Frame): 
  • pjproject/branches/projects/pjsua2/pjsip-apps/src/pygui/application.py

    r4665 r4671  
    5252                 
    5353                # Logger 
    54                 self.logger = log.Logger() 
     54                self.logger = None #log.Logger() 
    5555                 
    5656                # Accounts 
     
    136136                # Start polling 
    137137                self._onTimer() 
    138  
    139         def updateCall(self, acc): 
    140                 iid = str(acc.randId) 
    141                 for call in acc.callList: 
    142                         calliid = str(call.randId) 
    143                         uri, status = call.statusText() 
    144                         if self.tv.exists(calliid): 
    145                                 self.tv.item(call.iid, text=uri, values=(status,)) 
    146                         else: 
    147                                 call.iid = self.tv.insert(iid, 0, calliid, open=True, text=uri, values=(status,)) 
    148138 
    149139        def updateAccount(self, acc): 
     
    226216                self.accMenu = tk.Menu(top, tearoff=False) 
    227217                # Labels, must match with _onAccContextMenu() 
    228                 labels = ['Call', '-', 'Unregister', 'Reregister', 'Add buddy...', '-', 
     218                labels = ['Unregister', 'Reregister', 'Add buddy...', '-', 
    229219                          'Online', 'Invisible', 'Away', 'Busy', '-', 
    230220                          'Settings...', '-', 
     
    238228                 
    239229                # Create Buddy context menu 
    240                 # Labels, must match with _onAccContextMenu() 
     230                # Labels, must match with _onBuddyContextMenu() 
    241231                self.buddyMenu = tk.Menu(top, tearoff=False) 
    242                 labels = ['Video call', 'Audio call', 'Send instant message', '-', 
     232                labels = ['Audio call', 'Send instant message', '-', 
    243233                          'Subscribe', 'Unsubscribe', '-', 
    244234                          'Settings...', '-', 
     
    257247                else: 
    258248                        self.tv.bind('<3>', self._onTvRightClick) 
     249                self.tv.bind('<Double-Button-1>', self._onTvDoubleClick) 
    259250 
    260251        def _getSelectedAccount(self): 
     
    303294                                self.buddyMenu.post(event.x_root, event.y_root) 
    304295         
     296        def _onTvDoubleClick(self, event): 
     297                iid = self.tv.identify_row(event.y) 
     298                if iid: 
     299                        self.tv.selection_set( (iid,) ) 
     300                        acc = self._getSelectedAccount() 
     301                        if acc: 
     302                                self.cfgChanged = False 
     303                                dlg = accountsetting.Dialog(self.master, acc.cfg) 
     304                                if dlg.doModal(): 
     305                                        self.updateAccount(acc) 
     306                                        acc.modify(acc.cfg) 
     307                        else: 
     308                                bud = self._getSelectedBuddy() 
     309                                acc = bud.account 
     310                                chat = acc.findChat(bud) 
     311                                if not chat: 
     312                                        chat = acc.newChat(bud) 
     313                                chat.showWindow() 
     314         
    305315        def _onAccContextMenu(self, label): 
    306316                acc = self._getSelectedAccount() 
     
    308318                        return 
    309319                 
    310                 if label=='Call': 
    311                         acc.makeCall() 
    312                 elif label=='Unregister': 
     320                if label=='Unregister': 
    313321                        acc.setRegistration(False) 
    314322                elif label=='Reregister': 
     
    362370                acc = bud.account 
    363371                         
    364                 if label=='Video call': 
    365                         pass 
    366                 elif label=='Audio call': 
    367                         pass 
     372                if label=='Audio call': 
     373                        chat = acc.findChat(bud) 
     374                        if not chat: chat = acc.newChat(bud) 
     375                        chat.showWindow() 
     376                        chat.startAudio() 
    368377                elif label=='Send instant message': 
    369                         pass 
     378                        chat = acc.findChat(bud) 
     379                        if not chat: chat = acc.newChat(bud) 
     380                        chat.showWindow() 
    370381                elif label=='Subscribe': 
    371382                        bud.subscribePresence(True) 
     
    476487                 
    477488if __name__ == '__main__': 
     489        print pj 
    478490        main() 
  • pjproject/branches/projects/pjsua2/pjsip-apps/src/pygui/call.py

    r4663 r4671  
    3838        High level Python Call object, derived from pjsua2's Call object. 
    3939        """ 
    40         def __init__(self, app, acc, callId): 
    41                 pj.Call.__init__(self, acc, callId) 
    42                 self.app = app 
     40        def __init__(self, acc, peer_uri='', chat=None, call_id = pj.PJSUA_INVALID_ID): 
     41                pj.Call.__init__(self, acc, call_id) 
    4342                self.acc = acc 
    44                 self.uri = '' 
    45                 self.randId = random.randint(1, 9999) 
     43                self.peerUri = peer_uri 
     44                self.chat = chat 
     45                self.connected = False 
    4646 
    47         def statusText(self): 
    48                 uri = '' 
    49                 status = '?' 
    50                 if self.isActive(): 
    51                         ci = self.getInfo() 
    52                         status = ci.stateText 
    53                         uri = ci.remoteURI 
    54                 else: 
    55                         status = '- not established -' 
    56                 return uri, status 
    57          
    5847        def onCallState(self, prm): 
    59                 ci = self.getInfo() 
    60                 if ci.state == pj.PJSIP_INV_STATE_DISCONNECTED: 
    61                         iid = str(self.randId) 
    62                         self.acc.callList.remove(self) 
    63                         self.app.tv.delete( (iid,) ) 
    64                         del self 
    65                 else: 
    66                         self.app.updateCall(self.acc) 
    67  
     48                ci = self.getInfo() 
     49                self.connected = ci.state == pj.PJSIP_INV_STATE_CONFIRMED                        
     50                if self.chat: 
     51                        self.chat.updateCallState(self, ci) 
     52                         
     53        def onInstantMessage(self, prm): 
     54                # chat instance should have been initalized 
     55                if not self.chat: return 
     56                         
     57                self.chat.addMessage(self.peerUri, prm.msgBody) 
     58                self.chat.showWindow() 
     59                         
     60        def onInstantMessageStatus(self, prm): 
     61                if prm.code/100 == 2: return 
     62                # chat instance should have been initalized 
     63                if not self.chat: return 
     64                 
     65                self.chat.addMessage(None, "Failed sending message to '%s' (%d): %s" % (self.peerUri, prm.code, prm.reason)) 
     66                 
     67        def onTypingIndication(self, prm): 
     68                # chat instance should have been initalized 
     69                if not self.chat: return 
     70                 
     71                self.chat.setTypingIndication(self.peerUri, prm.isTyping) 
     72                         
    6873if __name__ == '__main__': 
    6974        application.main() 
Note: See TracChangeset for help on using the changeset viewer.