view browser_side/contact.py @ 54:f25c4077f6b9

addind contact + subscription management + misc - removed bad html_sanitize (not needed in Label !) - added isContactInRoster method in ContactPanel
author Goffi <goffi@goffi.org>
date Sat, 28 May 2011 20:18:14 +0200
parents 9f19e16187ff
children d5266c41ca24
line wrap: on
line source

#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
Libervia: a Salut à Toi frontend
Copyright (C) 2011  Jérôme Poisson (goffi@goffi.org)

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""

import pyjd # this is dummy in pyjs
from pyjamas.ui.SimplePanel import SimplePanel
from pyjamas.ui.VerticalPanel import VerticalPanel
from pyjamas.ui.HorizontalPanel import HorizontalPanel
from pyjamas.ui.Label import Label
from pyjamas import Window
from pyjamas import DOM

from pyjamas.dnd import makeDraggable
from pyjamas.ui.DragWidget import DragWidget, DragContainer
from jid import JID

class DragLabel(DragWidget):

    def __init__(self, text, type):
        DragWidget.__init__(self)
        self._text = text
        self._type = type
    
    def onDragStart(self, event):
        print "onDragStart"
        dt = event.dataTransfer
        #self.addMessage('types is %s' % dt.getTypes())
        dt.setData('Text', self._text)
        dt.setData('type', self._type)
        #self.addMessage('after setting, len is %s' % len(dt.dataStore.items))
        #self.addMessage('types is %s' % dt.getTypes())
        dt.setDragImage(self.getElement(), 15, 15)
        #dt.effectAllowed = 'copy'
        #self.addMessage('mode is %s' % dt.dataStore.items.mode)

    def onDragEnd(self, event):
        print "onDragEnd"
        #self.addMessage('Drag ended')
        #self.addMessage('mode is %s' % dt._data.mode)

    def addMessage(self, message):
        print "addMessage"
        #parent = self.getParent()
        #while not hasattr(parent, 'addMessage'):
        #    parent = parent.getParent()
        #parent.addMessage(message)

class GroupLabel(DragLabel, Label):
    def __init__(self, group):
        self.group = group
        Label.__init__(self, group) #, Element=DOM.createElement('div')
        self.setStyleName('group')
        DragLabel.__init__(self, group, "GROUP")
    

class ContactLabel(DragLabel, Label):
    def __init__(self, jid, name=None):
        if not name:
            name=jid
        Label.__init__(self, name)
        self.jid=jid
        self.setStyleName('contact')
        DragLabel.__init__(self, jid, "CONTACT")

class GroupList(VerticalPanel):

    def __init__(self, parent):
        VerticalPanel.__init__(self)
        self._parent = parent

    def add(self, group):
        _item = GroupLabel(group)
        _item.addMouseListener(self._parent)
        DOM.setStyleAttribute(_item.getElement(), "cursor", "pointer")
        VerticalPanel.add(self, _item)
    
class ContactList(VerticalPanel):

    def __init__(self):
        VerticalPanel.__init__(self)
        self.contacts=[]

    def __iter__(self):
        return self.contacts.__iter__()
    
    def add(self, jid, name=None):
        _item = ContactLabel(jid, name)
        DOM.setStyleAttribute(_item.getElement(), "cursor", "pointer")
        VerticalPanel.add(self, _item)
        self.contacts.append(_item)

    def setState(self, jid, state):
        """Change the appearance of the contact, according to the state
        @param jid: jid which need to change state
        @param state: 'unavailable' if not connected, else presence like RFC6121 #4.7.2.1"""
        _item = None
        for contact in self.contacts:
            if contact.jid == jid:
                _item = contact
                break
        if _item:
            if state == 'unavailable':
                _item.removeStyleName('contactConnected')
            else:
                _item.addStyleName('contactConnected')

class ContactTitleLabel(DragLabel, Label):
    def __init__(self, text):
        Label.__init__(self, text) #, Element=DOM.createElement('div')
        self.setStyleName('contactTitle')
        DragLabel.__init__(self, text, "CONTACT_TITLE")

class ContactPanel(SimplePanel):
    """Manage the contacts and groups"""
    
    def __init__(self, host):
        SimplePanel.__init__(self)
        self.host = host
        self.groups={}
        self.connected = {} #jid connected as key and their status

        self.vPanel = VerticalPanel()
        _title = ContactTitleLabel('Contacts')
        DOM.setStyleAttribute(_title.getElement(), "cursor", "pointer")

        self._contact_list = ContactList()
        self._contact_list.setStyleName('contactList')
        self._groupList = GroupList(self)
        self._groupList.setStyleName('groupList')
        
        self.vPanel.add(_title)
        self.vPanel.add(self._groupList)
        self.vPanel.add(self._contact_list)
        self.add(self.vPanel)
        self.setStyleName('contactBox')

    def addContact(self, jid, attributes, groups):
        """Add a contact to the panel
        @param jid: jid
        @attributes: cf SàT Bridge API's newContact
        @param groups: list of groups"""
        for group in groups:
            if not self.groups.has_key(group):
                self.groups[group] = set()
                self._groupList.add(group)
                self.host.uni_box.addKey("@%s: " % group)
            self.groups[group].add(jid)
        self._contact_list.add(jid)

    def setConnected(self, jid, resource, availability, priority, statuses):
        """Set connection status"""
        if availability=='unavailable':
            if self.connected.has_key(jid):
                if self.connected[jid].has_key(resource):
                    del self.connected[jid][resource]
                if not self.connected[jid]:
                    del self.connected[jid]
        else: 
            if not self.connected.has_key(jid):
                self.connected[jid] = {}
            self.connected[jid][resource] = (availability, priority, statuses)
        self._contact_list.setState(jid, availability)

    def getConnected(self):
        """return a list of all jid (bare jid) connected"""
        return self.connected.keys()

    def isContactInGroup(self, group, contact_jid):
       """Test if the contact_jid is in the group
       @param group: string of single group, or list of string
       @param contact_jid: jid to test
       @return: True if contact_jid is in on of the groups"""
       if self.groups.has_key(group) and contact_jid in self.groups[group]:
           return True
       return False

    def isContactInRoster(self, contact_jid):
        """Test if the contact is in our roster list"""
        for _contact_label in self._contact_list:
            if contact_jid == _contact_label.jid:
                return True
        return False

    def getGroups(self):
        return self.groups.keys()

    def onMouseMove(self, sender, x, y):
        pass
        
    def onMouseDown(self, sender, x, y):
        pass

    def onMouseUp(self, sender, x, y):
        pass

    def onMouseEnter(self, sender):
        if isinstance(sender, GroupLabel):
            for contact in self._contact_list:
                if contact.jid in self.groups[sender.group]:
                    contact.addStyleName("selected")
    
    def onMouseLeave(self, sender):
        if isinstance(sender, GroupLabel):
            for contact in self._contact_list:
                if contact.jid in self.groups[sender.group]:
                    contact.removeStyleName("selected")