Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomeu Vizoso <tomeu.vizoso@collabora.co.uk>2010-07-19 12:08:50 (GMT)
committer Tomeu Vizoso <tomeu.vizoso@collabora.co.uk>2010-08-20 13:02:27 (GMT)
commit0d79b38aa5b14f4db4c04d6c825503198c828f41 (patch)
tree6eb3c9ba4bcfce7cd87e62603a49cec7b8f37619
parent6422268efc87bca915e5c53c4e134d9c66236365 (diff)
Track the buddies' current activity
-rw-r--r--src/jarabe/desktop/meshbox.py70
-rw-r--r--src/jarabe/model/buddy.py19
-rw-r--r--src/jarabe/model/neighborhood.py145
-rw-r--r--src/jarabe/view/buddymenu.py4
4 files changed, 144 insertions, 94 deletions
diff --git a/src/jarabe/desktop/meshbox.py b/src/jarabe/desktop/meshbox.py
index 79954ef..cacc404 100644
--- a/src/jarabe/desktop/meshbox.py
+++ b/src/jarabe/desktop/meshbox.py
@@ -66,6 +66,9 @@ class ActivityView(hippo.CanvasBox):
hippo.CanvasBox.__init__(self)
self._model = model
+ self._model.connect('buddy-added', self.__buddy_added_cb)
+ self._model.connect('buddy-removed', self.__buddy_removed_cb)
+
self._icons = {}
self._palette = None
@@ -78,6 +81,9 @@ class ActivityView(hippo.CanvasBox):
self._palette = self._create_palette()
self._icon.set_palette(self._palette)
+ for buddy in self._model.props.buddies:
+ self._add_buddy(buddy)
+
def _create_icon(self):
icon = CanvasIcon(file_name=self._model.bundle.get_icon(),
xo_color=self._model.get_color(), cache=True,
@@ -118,13 +124,17 @@ class ActivityView(hippo.CanvasBox):
def has_buddy_icon(self, key):
return self._icons.has_key(key)
- def add_buddy_icon(self, key, icon):
- self._icons[key] = icon
+ def __buddy_added_cb(self, activity, buddy):
+ self._add_buddy(buddy)
+
+ def _add_buddy(self, buddy):
+ icon = BuddyIcon(buddy, style.STANDARD_ICON_SIZE)
+ self._icons[buddy.props.key] = icon
self._layout.add(icon)
- def remove_buddy_icon(self, key):
- icon = self._icons[key]
- del self._icons[key]
+ def __buddy_removed_cb(self, activity, buddy):
+ icon = self._icons[buddy.props.key]
+ del self._icons[buddy.props.key]
icon.destroy()
def _clicked_cb(self, item):
@@ -430,11 +440,10 @@ class MeshBox(gtk.VBox):
self._layout_box.set_layout(self._layout)
for buddy_model in self._model.get_buddies():
- self._add_alone_buddy(buddy_model)
+ self._add_buddy(buddy_model)
self._model.connect('buddy-added', self._buddy_added_cb)
self._model.connect('buddy-removed', self._buddy_removed_cb)
- self._model.connect('buddy-moved', self._buddy_moved_cb)
for activity_model in self._model.get_activities():
self._add_activity(activity_model)
@@ -458,24 +467,23 @@ class MeshBox(gtk.VBox):
gtk.VBox.do_size_allocate(self, allocation)
def _buddy_added_cb(self, model, buddy_model):
- self._add_alone_buddy(buddy_model)
+ self._add_buddy(buddy_model)
def _buddy_removed_cb(self, model, buddy_model):
self._remove_buddy(buddy_model)
- def _buddy_moved_cb(self, model, buddy_model, activity_model):
- # Owner doesn't move from the center
- if buddy_model.is_owner():
- return
- self._move_buddy(buddy_model, activity_model)
-
def _activity_added_cb(self, model, activity_model):
self._add_activity(activity_model)
def _activity_removed_cb(self, model, activity_model):
self._remove_activity(activity_model)
- def _add_alone_buddy(self, buddy_model):
+ def _add_buddy(self, buddy_model):
+ logging.debug('MeshBox._add_buddy %r', buddy_model.props.key)
+ buddy_model.connect('notify::current-activity',
+ self.__buddy_notify_current_activity_cb)
+ if buddy_model.props.current_activity is not None:
+ return
icon = BuddyIcon(buddy_model)
if buddy_model.is_owner():
self._owner_icon = icon
@@ -486,34 +494,20 @@ class MeshBox(gtk.VBox):
self._buddies[buddy_model.props.key] = icon
- def _remove_alone_buddy(self, buddy_model):
+ def _remove_buddy(self, buddy_model):
+ logging.debug('MeshBox._remove_buddy')
icon = self._buddies[buddy_model.props.key]
self._layout.remove(icon)
del self._buddies[buddy_model.props.key]
icon.destroy()
- def _remove_buddy(self, buddy_model):
- if self._buddies.has_key(buddy_model.props.key):
- self._remove_alone_buddy(buddy_model)
- else:
- object_path = buddy_model.get_buddy().object_path()
- for activity in self._activities.values():
- if activity.has_buddy_icon(object_path):
- activity.remove_buddy_icon(object_path)
-
- def _move_buddy(self, buddy_model, activity_model):
- self._remove_buddy(buddy_model)
-
- if activity_model == None:
- self._add_alone_buddy(buddy_model)
- elif activity_model.activity_id in self._activities:
- activity = self._activities[activity_model.activity_id]
-
- icon = BuddyIcon(buddy_model, style.STANDARD_ICON_SIZE)
- activity.add_buddy_icon(buddy_model.get_buddy().object_path(), icon)
-
- if hasattr(icon, 'set_filter'):
- icon.set_filter(self._query)
+ def __buddy_notify_current_activity_cb(self, buddy_model, pspec):
+ logging.debug('MeshBox.__buddy_notify_current_activity_cb')
+ if buddy_model.props.current_activity is None:
+ if not buddy_model.props.key in self._buddies:
+ self._add_buddy(buddy_model)
+ elif buddy_model.props.key in self._buddies:
+ self._remove_buddy(buddy_model)
def _add_activity(self, activity_model):
icon = ActivityView(activity_model)
diff --git a/src/jarabe/model/buddy.py b/src/jarabe/model/buddy.py
index b908e10..2c2e28d 100644
--- a/src/jarabe/model/buddy.py
+++ b/src/jarabe/model/buddy.py
@@ -39,6 +39,7 @@ class BaseBuddyModel(gobject.GObject):
self._color = None
self._tags = None
self._present = False
+ self._current_activity = None
gobject.GObject.__init__(self, **kwargs)
@@ -81,10 +82,16 @@ class BaseBuddyModel(gobject.GObject):
tags = gobject.property(type=object, getter=get_tags)
def get_current_activity(self):
- raise NotImplementedError
+ return self._current_activity
+
+ def set_current_activity(self, current_activity):
+ if self._current_activity != current_activity:
+ self._current_activity = current_activity
+ self.notify('current-activity')
current_activity = gobject.property(type=object,
- getter=get_current_activity)
+ getter=get_current_activity,
+ setter=set_current_activity)
def is_owner(self):
raise NotImplementedError
@@ -164,9 +171,6 @@ class BuddyModel(BaseBuddyModel):
def is_owner(self):
return False
- def get_current_activity(self):
- return None
-
def get_buddy(self):
raise NotImplementedError
@@ -234,11 +238,6 @@ class BuddyModel(BaseBuddyModel):
def is_owner(self):
return False
- def get_current_activity(self):
- if self._buddy:
- return self._buddy.props.current_activity
- return None
-
def is_present(self):
if self._buddy:
return True
diff --git a/src/jarabe/model/neighborhood.py b/src/jarabe/model/neighborhood.py
index 56d8696..bf49073 100644
--- a/src/jarabe/model/neighborhood.py
+++ b/src/jarabe/model/neighborhood.py
@@ -59,6 +59,12 @@ CONNECTION_INTERFACE_BUDDY_INFO = 'org.laptop.Telepathy.BuddyInfo'
CONNECTION_INTERFACE_ACTIVITY_PROPERTIES = 'org.laptop.Telepathy.ActivityProperties'
class ActivityModel(gobject.GObject):
+ __gsignals__ = {
+ 'buddy-added': (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, ([object])),
+ 'buddy-removed': (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, ([object])),
+ }
def __init__(self, activity_id, room_handle):
gobject.GObject.__init__(self)
@@ -66,6 +72,7 @@ class ActivityModel(gobject.GObject):
self.room_handle = room_handle
self._bundle = None
self._color = None
+ self._buddies = []
def get_color(self):
return self._color
@@ -91,8 +98,20 @@ class ActivityModel(gobject.GObject):
name = gobject.property(type=object, getter=get_name, setter=set_name)
- def join(self):
- pass
+ def get_buddies(self):
+ return self._buddies
+
+ def add_buddy(self, buddy):
+ self._buddies.append(buddy)
+ self.notify('buddies')
+ self.emit('buddy-added', buddy)
+
+ def remove_buddy(self, buddy):
+ self._buddies.remove(buddy)
+ self.notify('buddies')
+ self.emit('buddy-removed', buddy)
+
+ buddies = gobject.property(type=object, getter=get_buddies)
class _Account(gobject.GObject):
__gsignals__ = {
@@ -103,11 +122,13 @@ class _Account(gobject.GObject):
'activity-removed': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, ([object])),
'buddy-added': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([object])),
+ gobject.TYPE_NONE, ([object, object, object])),
'buddy-updated': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, ([object, object])),
'buddy-removed': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([object]))
+ gobject.TYPE_NONE, ([object])),
+ 'current-activity-updated': (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, ([object, object])),
}
def __init__(self, account_path):
@@ -167,6 +188,9 @@ class _Account(gobject.GObject):
connection[CONNECTION_INTERFACE_BUDDY_INFO].connect_to_signal(
'ActivitiesChanged', self.__buddy_activities_changed_cb)
+
+ connection[CONNECTION_INTERFACE_BUDDY_INFO].connect_to_signal(
+ 'CurrentActivityChanged', self.__current_activity_changed_cb)
else:
logging.warning('Connection %s does not support OLPC buddy '
'properties', connection.object_path)
@@ -217,6 +241,18 @@ class _Account(gobject.GObject):
def __buddy_info_updated_cb(self, handle, properties):
logging.debug('__buddy_info_updated_cb %r %r', handle, properties)
+ def __current_activity_changed_cb(self, contact_handle, activity_id, room_handle):
+ logging.debug('__current_activity_changed_cb %r %r %r', contact_handle, activity_id, room_handle)
+ if contact_handle in self._buddy_handles:
+ contact_id = self._buddy_handles[contact_handle]
+ self.emit('current-activity-updated', contact_id, activity_id)
+
+ def __get_current_activity_cb(self, contact_handle, activity_id, room_handle):
+ logging.debug('__get_current_activity_cb %r %r %r', contact_handle, activity_id, room_handle)
+ logging.debug('__get_current_activity_cb %r', self._buddy_handles)
+ contact_id = self._buddy_handles[contact_handle]
+ self.emit('current-activity-updated', contact_id, activity_id)
+
def __buddy_activities_changed_cb(self, buddy_handle, activities):
logging.debug('__buddy_activities_changed_cb %r %r', buddy_handle, activities)
self._update_buddy_activities(buddy_handle, activities)
@@ -247,26 +283,28 @@ class _Account(gobject.GObject):
current_activity_ids = [activity_id for activity_id, room_handle in activities]
for activity_id in self._activities_per_buddy[buddy_handle].copy():
if not activity_id in current_activity_ids:
- self._remove_activity(buddy_handle, activity_id)
+ self._remove_buddy_from_activity(buddy_handle, activity_id)
def __get_properties_cb(self, room_handle, properties):
logging.debug('__get_properties_cb %r %r', room_handle, properties)
self._update_activity(room_handle, properties)
- def _remove_activity(self, buddy_handle, activity_id):
+ def _remove_buddy_from_activity(self, buddy_handle, activity_id):
if buddy_handle in self._buddies_per_activity[activity_id]:
self._buddies_per_activity[activity_id].remove(buddy_handle)
- if not self._buddies_per_activity[activity_id]:
- del self._buddies_per_activity[activity_id]
- self._activities_per_buddy[buddy_handle].remove(activity_id)
+ if activity_id in self._activities_per_buddy[buddy_handle]:
+ self._activities_per_buddy[buddy_handle].remove(activity_id)
- for room_handle in self._activity_handles.copy():
- if self._activity_handles[room_handle] == activity_id:
- del self._activity_handles[room_handle]
- break
+ if not self._buddies_per_activity[activity_id]:
+ del self._buddies_per_activity[activity_id]
- self.emit('activity-removed', activity_id)
+ for room_handle in self._activity_handles.copy():
+ if self._activity_handles[room_handle] == activity_id:
+ del self._activity_handles[room_handle]
+ break
+
+ self.emit('activity-removed', activity_id)
def __activity_properties_changed_cb(self, room_handle, properties):
logging.debug('__activity_properties_changed_cb %r %r', room_handle, properties)
@@ -298,23 +336,10 @@ class _Account(gobject.GObject):
reply_handler=self.__get_contact_attributes_cb,
error_handler=self.__error_handler_cb)
- if CONNECTION_INTERFACE_BUDDY_INFO not in self._connection:
- return
-
- for handle in handles:
- self._connection[CONNECTION_INTERFACE_BUDDY_INFO].GetProperties(
- handle,
- reply_handler=partial(self.__got_buddy_info_cb, handle),
- error_handler=self.__error_handler_cb,
- byte_arrays=True)
-
- self._connection[CONNECTION_INTERFACE_BUDDY_INFO].GetActivities(
- handle,
- reply_handler=partial(self.__got_activities_cb, handle),
- error_handler=self.__error_handler_cb)
-
- def __got_buddy_info_cb(self, handle, properties):
+ def __got_buddy_info_cb(self, handle, nick, properties):
logging.debug('__got_buddy_info_cb %r', properties)
+ self.emit('buddy-added', self._buddy_handles[handle], nick,
+ properties.get('key', None))
self.emit('buddy-updated', self._buddy_handles[handle], properties)
def __get_contact_attributes_cb(self, attributes):
@@ -332,7 +357,26 @@ class _Account(gobject.GObject):
contact_id = attributes[handle][CONNECTION + '/contact-id']
self._buddy_handles[handle] = contact_id
- self.emit('buddy-added', attributes[handle])
+ if CONNECTION_INTERFACE_BUDDY_INFO in self._connection:
+ connection = self._connection[CONNECTION_INTERFACE_BUDDY_INFO]
+
+ connection.GetProperties(
+ handle,
+ reply_handler=partial(self.__got_buddy_info_cb, handle, nick),
+ error_handler=self.__error_handler_cb,
+ byte_arrays=True)
+
+ connection.GetActivities(
+ handle,
+ reply_handler=partial(self.__got_activities_cb, handle),
+ error_handler=self.__error_handler_cb)
+
+ connection.GetCurrentActivity(
+ handle,
+ reply_handler=partial(self.__get_current_activity_cb, handle),
+ error_handler=self.__error_handler_cb)
+ else:
+ self.emit('buddy-added', contact_id, nick, None)
def __got_activities_cb(self, buddy_handle, activities):
logging.debug('__got_activities_cb %r %r', buddy_handle, activities)
@@ -346,10 +390,6 @@ class Neighborhood(gobject.GObject):
gobject.TYPE_NONE, ([object])),
'buddy-added': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, ([object])),
- 'buddy-moved': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ([object,
- object])),
'buddy-removed': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, ([object]))
}
@@ -393,6 +433,7 @@ class Neighborhood(gobject.GObject):
account.connect('activity-added', self.__activity_added_cb)
account.connect('activity-updated', self.__activity_updated_cb)
account.connect('activity-removed', self.__activity_removed_cb)
+ account.connect('current-activity-updated', self.__current_activity_updated_cb)
self._accounts.append(account)
def _ensure_link_local_account(self, account_manager, accounts):
@@ -459,20 +500,18 @@ class Neighborhood(gobject.GObject):
'jabber', params, properties)
accounts.append(account)
- def __buddy_added_cb(self, account, properties):
- logging.debug('__buddy_added_cb %r', properties)
-
- contact_id = properties[CONNECTION + '/contact-id']
- assert contact_id is not None
+ def __buddy_added_cb(self, account, contact_id, nick, key):
+ logging.debug('__buddy_added_cb %r', contact_id)
if contact_id in self._buddies:
logging.debug('__buddy_added_cb buddy already tracked')
return
buddy = BuddyModel(
- nick=properties[CONNECTION_INTERFACE_ALIASING + '/alias'],
+ nick=nick,
account=account.object_path,
- contact_id=contact_id)
+ contact_id=contact_id,
+ key=key)
self._buddies[contact_id] = buddy
self.emit('buddy-added', buddy)
@@ -486,8 +525,6 @@ class Neighborhood(gobject.GObject):
buddy = self._buddies[contact_id]
if 'color' in properties:
buddy.props.color = XoColor(properties['color'])
- if 'key' in properties:
- buddy.props.key = properties['key']
def __activity_added_cb(self, account, room_handle, activity_id):
logging.debug('__activity_added_cb %r %r', room_handle, activity_id)
@@ -531,6 +568,26 @@ class Neighborhood(gobject.GObject):
del self._activities[activity_id]
self.emit('activity-removed', activity)
+ def __current_activity_updated_cb(self, account, contact_id, activity_id):
+ logging.debug('__current_activity_updated_cb %r %r', contact_id, activity_id)
+ if contact_id not in self._buddies:
+ logging.debug('__current_activity_updated_cb Unknown buddy with '
+ 'contact_id %r', contact_id)
+ return
+
+ buddy = self._buddies[contact_id]
+ if buddy.props.current_activity is not None:
+ if buddy.props.current_activity.activity_id == activity_id:
+ return
+ buddy.props.current_activity.remove_buddy(buddy)
+
+ if activity_id:
+ activity = self._activities[activity_id]
+ buddy.props.current_activity = activity
+ activity.add_buddy(buddy)
+ else:
+ buddy.props.current_activity = None
+
def get_activities(self):
return []
diff --git a/src/jarabe/view/buddymenu.py b/src/jarabe/view/buddymenu.py
index 6c67d36..9305ca1 100644
--- a/src/jarabe/view/buddymenu.py
+++ b/src/jarabe/view/buddymenu.py
@@ -113,9 +113,9 @@ class BuddyMenu(Palette):
panel.show()
def _update_invite_menu(self, activity):
- buddy_activity = self._buddy.get_current_activity()
+ buddy_activity = self._buddy.props.current_activity
if buddy_activity is not None:
- buddy_activity_id = buddy_activity.props.id
+ buddy_activity_id = buddy_activity.activity_id
else:
buddy_activity_id = None