Merge branch 'master' of git+ssh://dev.laptop.org/git/sugar

master
Marco Pesenti Gritti 18 years ago
commit ee4a416464

@ -33,6 +33,11 @@ class BuddyDBusHelper(dbus.service.Object):
def ServiceDisappeared(self, object_path):
pass
@dbus.service.signal(BUDDY_DBUS_INTERFACE,
signature="")
def Disappeared(self):
pass
@dbus.service.signal(BUDDY_DBUS_INTERFACE,
signature="")
def IconChanged(self):
@ -268,6 +273,7 @@ class Buddy(object):
if service.get_type() == PRESENCE_SERVICE_TYPE:
self._valid = False
self._dbus_helper.Disappeared()
def remove_activity(self, activity):
actid = activity.get_id()

@ -1,26 +1,53 @@
from sugar.presence import PresenceService
from sugar.canvas.IconColor import IconColor
import gobject
_NOT_PRESENT_COLOR = "#888888,#BBBBBB"
class BuddyModel(gobject.GObject):
__gsignals__ = {
'appeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
'disappeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
'color-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
'current-activity-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT]))
}
def __init__(self, name=None, buddy=None):
if name and buddy:
raise RuntimeError("Must specify only _one_ of name or buddy.")
gobject.GObject.__init__(self)
self._ba_handler = None
self._pc_handler = None
self._dis_handler = None
class BuddyModel:
def __init__(self, buddy=None):
self._cur_activity = None
self._pservice = PresenceService.get_instance()
self._buddy = buddy
if self._buddy:
self.set_name(self._buddy.get_name())
self.set_color(self._buddy.get_color())
self._buddy.connect('property-changed',
self.__buddy_property_changed_cb)
else:
# if we don't have a buddy yet, connect to the PS
# and wait until the buddy pops up on the network
self._pservice.connect('buddy-appeared', self.__buddy_appeared_cb)
self._buddy = None
def set_name(self, name):
self._name = name
# If given just a name, try to get the buddy from the PS first
if not buddy:
self._name = name
# FIXME: use public key, not name
buddy = self._pservice.get_buddy_by_name(self._name)
# If successful, copy properties from the PS buddy object
if buddy:
self.__update_buddy(buddy)
else:
# Otherwise, connect to the PS's buddy-appeared signal and
# wait for the buddy to appear
self._ba_handler = self._pservice.connect('buddy-appeared',
self.__buddy_appeared_cb)
self._name = name
# Set color to 'inactive'/'disconnected'
self.__set_color_from_string(_NOT_PRESENT_COLOR)
def set_color(self, color_string):
def __set_color_from_string(self, color_string):
self._color = IconColor(color_string)
def get_name(self):
@ -30,24 +57,53 @@ class BuddyModel:
return self._color
def get_buddy(self):
# If we have a buddy already, just return
if self._buddy:
return self._buddy
# Otherwise try to get the buddy from the PS
self._buddy = self._pservice.get_buddy_by_name(self._name)
if self._buddy:
self._buddy.connect('property-changed',
self.__buddy_property_changed_cb)
return self._buddy
def __update_buddy(self, buddy):
if not buddy:
raise ValueError("Buddy cannot be None.")
self._buddy = buddy
self._name = self._buddy.get_name()
self.__set_color_from_string(self._buddy.get_color())
self._pc_handler = self._buddy.connect('property-changed', self.__buddy_property_changed_cb)
self._dis_handler = self._buddy.connect('disappeared', self.__buddy_disappeared_cb)
def __buddy_appeared_cb(self, pservice, buddy):
# FIXME: use public key rather than buddy name
if not self._buddy and buddy.get_name() == self._name:
self.get_buddy()
if self._buddy or buddy.get_name() != self._name:
return
if self._ba_handler:
# Once we have the buddy, we no longer need to
# monitor buddy-appeared events
self._pservice.disconnect(self._ba_handler)
self._ba_handler = None
self.__update_buddy(buddy)
self.emit('appeared')
def __buddy_property_changed_cb(self, buddy, keys):
if not self._buddy:
return
# all we care about right now is current activity
curact = self._buddy.get_current_activity()
self._cur_activity = self._pservice.get_activity(curact)
if 'curact' in keys:
curact = self._buddy.get_current_activity()
self._cur_activity = self._pservice.get_activity(curact)
self.emit('current-activity-changed', self._cur_activity)
if 'color' in keys:
self.__set_color_from_string(self._buddy.get_color())
self.emit('color-changed', self.get_color())
def __buddy_disappeared_cb(self, buddy):
if buddy != self._buddy:
return
self._buddy.disconnect(self._pc_handler)
self._buddy.disconnect(self._dis_handler)
self.__set_color_from_string(_NOT_PRESENT_COLOR)
self._cur_activity = None
self.emit('current-activity-changed', self._cur_activity)
self.emit('disappeared')
self._buddy = None

@ -50,9 +50,7 @@ class Friends(gobject.GObject):
success = cp.read([self._path])
if success:
for name in cp.sections():
buddy = BuddyModel()
buddy.set_name(name)
buddy.set_color(cp.get(name, 'color'))
buddy = BuddyModel(name)
self.add_friend(buddy)
except Exception, exc:
logging.error("Error parsing friends file: %s" % exc)

@ -2,18 +2,25 @@ from sugar.canvas.MenuIcon import MenuIcon
from view.BuddyMenu import BuddyMenu
class BuddyIcon(MenuIcon):
def __init__(self, shell, menu_shell, friend):
def __init__(self, shell, menu_shell, buddy):
MenuIcon.__init__(self, menu_shell, icon_name='stock-buddy',
color=friend.get_color(), size=112)
color=buddy.get_color(), size=112)
self._shell = shell
self._friend = friend
self._buddy = buddy
self._buddy.connect('appeared', self.__buddy_presence_change_cb)
self._buddy.connect('disappeared', self.__buddy_presence_change_cb)
self._buddy.connect('color-changed', self.__buddy_presence_change_cb)
def __buddy_presence_change_cb(self, buddy, color=None):
# Update the icon's color when the buddy comes and goes
self.set_property('color', buddy.get_color())
def set_popup_distance(self, distance):
self._popup_distance = distance
def create_menu(self):
menu = BuddyMenu(self._shell, self._friend)
menu = BuddyMenu(self._shell, self._buddy)
menu.connect('action', self._popup_action_cb)
return menu
@ -22,14 +29,14 @@ class BuddyIcon(MenuIcon):
friends = self._shell.get_model().get_friends()
if action == BuddyMenu.ACTION_REMOVE_FRIEND:
friends.remove(self._friend)
friends.remove(self._buddy)
buddy = self._friend.get_buddy()
if buddy == None:
ps_buddy = self._buddy.get_buddy()
if ps_buddy == None:
return
if action == BuddyMenu.ACTION_INVITE:
activity = self._shell.get_current_activity()
activity.invite(buddy)
activity.invite(ps_buddy)
elif action == BuddyMenu.ACTION_MAKE_FRIEND:
friends.make_friend(buddy)
friends.make_friend(ps_buddy)

@ -7,6 +7,8 @@ class Buddy(gobject.GObject):
__gsignals__ = {
'icon-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([])),
'disappeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([])),
'service-appeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
'service-disappeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
@ -33,6 +35,7 @@ class Buddy(gobject.GObject):
self._buddy.connect_to_signal('IconChanged', self._icon_changed_cb)
self._buddy.connect_to_signal('ServiceAppeared', self._service_appeared_cb)
self._buddy.connect_to_signal('ServiceDisappeared', self._service_disappeared_cb)
self._buddy.connect_to_signal('Disappeared', self._disappeared_cb)
self._buddy.connect_to_signal('JoinedActivity', self._joined_activity_cb)
self._buddy.connect_to_signal('LeftActivity', self._left_activity_cb)
self._buddy.connect_to_signal('PropertyChanged', self._property_changed_cb)
@ -54,6 +57,12 @@ class Buddy(gobject.GObject):
def _icon_changed_cb(self):
gobject.idle_add(self._emit_icon_changed_signal)
def _emit_disappeared_signal(self):
self.emit('disappeared')
def _disappeared_cb(self):
gobject.idle_add(self._emit_disappeared_signal)
def _emit_service_appeared_signal(self, object_path):
self.emit('service-appeared', self._ps_new_object(object_path))
return False

Loading…
Cancel
Save