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

Conflicts:

	services/presence/buddy.py
This commit is contained in:
Mike's Primary Account 2007-04-20 16:42:47 -04:00
commit 81d9bed0d8
5 changed files with 117 additions and 79 deletions

View File

@ -39,6 +39,14 @@ class DBusGObjectMetaclass(dbus.service.InterfaceType, gobject.GObjectMeta): pas
class DBusGObject(dbus.service.Object, gobject.GObject): __metaclass__ = DBusGObjectMetaclass
_PROP_NICK = "nick"
_PROP_KEY = "key"
_PROP_ICON = "icon"
_PROP_CURACT = "current-activity"
_PROP_COLOR = "color"
_PROP_OWNER = "owner"
_PROP_VALID = "valid"
class Buddy(DBusGObject):
"""Person on the network (tracks properties and shared activites)
@ -71,14 +79,14 @@ class Buddy(DBusGObject):
}
__gproperties__ = {
'key' : (str, None, None, None,
_PROP_KEY : (str, None, None, None,
gobject.PARAM_READWRITE | gobject.PARAM_CONSTRUCT_ONLY),
'icon' : (object, None, None, gobject.PARAM_READWRITE),
'nick' : (str, None, None, None, gobject.PARAM_READWRITE),
'color' : (str, None, None, None, gobject.PARAM_READWRITE),
'current-activity' : (str, None, None, None, gobject.PARAM_READWRITE),
'valid' : (bool, None, None, False, gobject.PARAM_READABLE),
'owner' : (bool, None, None, False, gobject.PARAM_READABLE)
_PROP_ICON : (object, None, None, gobject.PARAM_READWRITE),
_PROP_NICK : (str, None, None, None, gobject.PARAM_READWRITE),
_PROP_COLOR : (str, None, None, None, gobject.PARAM_READWRITE),
_PROP_CURACT : (str, None, None, None, gobject.PARAM_READWRITE),
_PROP_VALID : (bool, None, None, False, gobject.PARAM_READABLE),
_PROP_OWNER : (bool, None, None, False, gobject.PARAM_READABLE)
}
def __init__(self, bus_name, object_id, **kwargs):
@ -112,9 +120,15 @@ class Buddy(DBusGObject):
self._nick = None
self._color = None
if not kwargs.get("key"):
if not kwargs.get(_PROP_KEY):
raise ValueError("key required")
_ALLOWED_INIT_PROPS = [_PROP_NICK, _PROP_KEY, _PROP_ICON, _PROP_CURACT, _PROP_COLOR]
for (key, value) in kwargs.items():
if key not in _ALLOWED_INIT_PROPS:
logging.debug("Invalid init property '%s'; ignoring..." % key)
del kwargs[key]
gobject.GObject.__init__(self, **kwargs)
def do_get_property(self, pspec):
@ -122,23 +136,23 @@ class Buddy(DBusGObject):
pspec -- property specifier with a "name" attribute
"""
if pspec.name == "key":
if pspec.name == _PROP_KEY:
return self._key
elif pspec.name == "icon":
elif pspec.name == _PROP_ICON:
return self._icon
elif pspec.name == "nick":
elif pspec.name == _PROP_NICK:
return self._nick
elif pspec.name == "color":
elif pspec.name == _PROP_COLOR:
return self._color
elif pspec.name == "current-activity":
elif pspec.name == _PROP_CURACT:
if not self._current_activity:
return None
if not self._activities.has_key(self._current_activity):
return None
return self._current_activity
elif pspec.name == "valid":
elif pspec.name == _PROP_VALID:
return self._valid
elif pspec.name == "owner":
elif pspec.name == _PROP_OWNER:
return self._owner
def do_set_property(self, pspec, value):
@ -150,18 +164,18 @@ class Buddy(DBusGObject):
emits 'icon-changed' signal on icon setting
calls _update_validity on all calls
"""
if pspec.name == "icon":
if pspec.name == _PROP_ICON:
if str(value) != self._icon:
self._icon = str(value)
self.IconChanged(self._icon)
self.emit('icon-changed', self._icon)
elif pspec.name == "nick":
elif pspec.name == _PROP_NICK:
self._nick = value
elif pspec.name == "color":
elif pspec.name == _PROP_COLOR:
self._color = value
elif pspec.name == "current-activity":
elif pspec.name == _PROP_CURACT:
self._current_activity = value
elif pspec.name == "key":
elif pspec.name == _PROP_KEY:
self._key = value
self._update_validity()
@ -239,14 +253,14 @@ class Buddy(DBusGObject):
"" if no current activity
"""
props = {}
props['nick'] = self.props.nick
props['owner'] = self.props.owner
props['key'] = self.props.key
props['color'] = self.props.color
props[_PROP_NICK] = self.props.nick
props[_PROP_OWNER] = self.props.owner
props[_PROP_KEY] = self.props.key
props[_PROP_COLOR] = self.props.color
if self.props.current_activity:
props['current-activity'] = self.props.current_activity
props[_PROP_CURACT] = self.props.current_activity
else:
props['current-activity'] = ""
props[_PROP_CURACT] = ""
return props
# methods
@ -300,31 +314,35 @@ class Buddy(DBusGObject):
calls _update_validity
"""
changed = False
if "nick" in properties.keys():
nick = properties["nick"]
changed_props = {}
if _PROP_NICK in properties.keys():
nick = properties[_PROP_NICK]
if nick != self._nick:
self._nick = nick
changed_props[_PROP_NICK] = nick
changed = True
if "color" in properties.keys():
color = properties["color"]
if _PROP_COLOR in properties.keys():
color = properties[_PROP_COLOR]
if color != self._color:
self._color = color
changed_props[_PROP_COLOR] = color
changed = True
if "current-activity" in properties.keys():
curact = properties["current-activity"]
if _PROP_CURACT in properties.keys():
curact = properties[_PROP_CURACT]
if curact != self._current_activity:
self._current_activity = curact
changed_props[_PROP_CURACT] = curact
changed = True
if not changed:
if not changed or not len(changed_props.keys()):
return
# Try emitting PropertyChanged before updating validity
# to avoid leaking a PropertyChanged signal before the buddy is
# actually valid the first time after creation
if self._valid:
self.PropertyChanged(properties)
self.emit('property-changed', properties)
self.PropertyChanged(changed_props)
self.emit('property-changed', changed_props)
self._update_validity()
@ -501,12 +519,12 @@ class ShellOwner(GenericOwner):
def _color_changed_cb(self, color):
"""Handle color change, set property to generate event"""
props = {'color': color}
props = {_PROP_COLOR: color}
self.set_properties(props)
def _nick_changed_cb(self, nick):
"""Handle nickname change, set property to generate event"""
props = {'nick': nick}
props = {_PROP_NICK: nick}
self.set_properties(props)
def _cur_activity_changed_cb(self, activity_id):
@ -519,7 +537,7 @@ class ShellOwner(GenericOwner):
if not self._activities.has_key(activity_id):
# This activity is local-only
activity_id = None
props = {'current-activity': activity_id}
props = {_PROP_CURACT: activity_id}
self.set_properties(props)
@ -633,10 +651,10 @@ class TestOwner(GenericOwner):
self.props.icon = _get_random_image()
elif it == 1:
from sugar.graphics import xocolor
props = {'color': xocolor.XoColor().to_string()}
props = {_PROP_COLOR: xocolor.XoColor().to_string()}
self.set_properties(props)
elif it == 2:
props = {'nick': _get_random_name()}
props = {_PROP_NICK: _get_random_name()}
self.set_properties(props)
elif it == 3:
actid = ""
@ -646,7 +664,7 @@ class TestOwner(GenericOwner):
if idx < len(self._test_activities):
activity = self._test_activities[idx]
actid = activity.props.id
props = {'current-activity': actid}
props = {_PROP_CURACT: actid}
self.set_properties(props)
return True

View File

@ -130,6 +130,8 @@ class BuddyModel(gobject.GObject):
if 'color' in keys:
self._set_color_from_string(self._buddy.props.color)
self.emit('color-changed', self.get_color())
if 'current-activity' in keys:
self.emit('current-activity-changed', buddy.props.current_activity)
def _buddy_disappeared_cb(self, buddy):
if buddy != self._buddy:
@ -144,8 +146,3 @@ class BuddyModel(gobject.GObject):
def _buddy_icon_changed_cb(self, buddy):
self.emit('icon-changed')
def _buddy_current_activity_changed_cb(self, buddy, activity=None):
if not self._buddy:
return
self.emit('current-activity-changed', activity)

View File

@ -160,19 +160,14 @@ class MeshModel(gobject.GObject):
def get_buddies(self):
return self._buddies.values()
def _buddy_activity_changed_cb(self, buddy, cur_activity):
if not self._buddies.has_key(buddy.props.key):
def _buddy_activity_changed_cb(self, model, cur_activity):
if not self._buddies.has_key(model.get_key()):
return
buddy_model = self._buddies[buddy.props.key]
if cur_activity == None:
self.emit('buddy-moved', buddy_model, None)
else:
self._notify_buddy_change(buddy_model, cur_activity)
def _notify_buddy_change(self, buddy_model, cur_activity):
if self._activities.has_key(cur_activity.get_id()):
if cur_activity and self._activities.has_key(cur_activity.get_id()):
activity_model = self._activities[cur_activity.get_id()]
self.emit('buddy-moved', buddy_model, activity_model)
self.emit('buddy-moved', model, activity_model)
else:
self.emit('buddy-moved', model, None)
def _buddy_appeared_cb(self, pservice, buddy):
if self._buddies.has_key(buddy.props.key):
@ -186,7 +181,7 @@ class MeshModel(gobject.GObject):
cur_activity = buddy.props.current_activity
if cur_activity:
self._notify_buddy_change(model, cur_activity)
self._buddy_activity_changed_cb(model, cur_activity)
def _buddy_disappeared_cb(self, pservice, buddy):
if not self._buddies.has_key(buddy.props.key):

View File

@ -17,6 +17,7 @@
import logging
import os
import urlparse
import gobject
@ -74,8 +75,13 @@ class ClipboardIcon(CanvasIcon):
self.props.background_color = color.TOOLBAR_BACKGROUND.get_int()
def get_popup(self):
cb_service = clipboardservice.get_instance()
obj = cb_service.get_object(self._object_id)
formats = obj['FORMATS']
self._menu = ClipboardMenu(self._name, self._percent, self._preview,
self._activity)
self._activity,
formats[0] == 'application/vnd.olpc-x-sugar')
self._menu.connect('action', self._popup_action_cb)
return self._menu
@ -83,15 +89,19 @@ class ClipboardIcon(CanvasIcon):
return self._popup_context
def set_state(self, name, percent, icon_name, preview, activity):
cb_service = clipboardservice.get_instance()
obj = cb_service.get_object(self._object_id)
installable = (obj['FORMATS'][0] == 'application/vnd.olpc-x-sugar')
self._name = name
self._percent = percent
self._preview = preview
self._activity = activity
self.set_property("icon_name", icon_name)
if self._menu:
self._menu.set_state(name, percent, preview, activity)
self._menu.set_state(name, percent, preview, activity, installable)
if activity and percent < 100:
if (activity or installable) and percent < 100:
self.props.xo_color = XoColor("#000000,#424242")
else:
self.props.xo_color = XoColor("#000000,#FFFFFF")
@ -107,15 +117,25 @@ class ClipboardIcon(CanvasIcon):
self._open_file()
def _open_file(self):
if self._percent < 100 or not self._activity:
if self._percent < 100:
return
# Get the file path
cb_service = clipboardservice.get_instance()
obj = cb_service.get_object(self._object_id)
formats = obj['FORMATS']
if len(formats) > 0:
path = cb_service.get_object_data(self._object_id, formats[0])
if len(formats) == 0:
return
if not self._activity and \
not formats[0] == 'application/vnd.olpc-x-sugar':
return
uri = cb_service.get_object_data(self._object_id, formats[0])
if not uri.startswith('file://'):
return
path = urlparse.urlparse(uri).path
# FIXME: would be better to check for format.onDisk
try:
@ -124,8 +144,10 @@ class ClipboardIcon(CanvasIcon):
path_exists = False
if path_exists:
uri = 'file://' + path
if self._activity:
activityfactory.create_with_uri(self._activity, uri)
else:
self._install_xo(path)
else:
logging.debug("Clipboard item file path %s didn't exist" % path)
@ -153,3 +175,9 @@ class ClipboardIcon(CanvasIcon):
self.props.background_color = color.DESKTOP_BACKGROUND.get_int()
else:
self.props.background_color = color.TOOLBAR_BACKGROUND.get_int()
def _install_xo(self, path):
logging.debug('mec')
if os.spawnlp(os.P_WAIT, 'sugar-install-bundle', 'sugar-install-bundle',
path):
raise RuntimeError, 'An error occurred while extracting the .xo contents.'

View File

@ -33,7 +33,7 @@ class ClipboardMenu(Menu):
ACTION_OPEN = 1
ACTION_STOP_DOWNLOAD = 2
def __init__(self, name, percent, preview, activity):
def __init__(self, name, percent, preview, activity, installable):
Menu.__init__(self, name)
self.props.border = 0
@ -54,10 +54,10 @@ class ClipboardMenu(Menu):
self._preview_text.props.font_desc = font.DEFAULT.get_pango_desc()
self.append(self._preview_text)
self._update_icons(percent, activity)
self._update_icons(percent, activity, installable)
def _update_icons(self, percent, activity):
if percent == 100 and activity:
def _update_icons(self, percent, activity, installable):
if percent == 100 and (activity or installable):
if not self._remove_item:
self._remove_item = MenuItem(ClipboardMenu.ACTION_DELETE,
_('Remove'),
@ -73,7 +73,7 @@ class ClipboardMenu(Menu):
if self._stop_item:
self.remove_item(self._stop_item)
self._stop_item = None
elif percent == 100 and not activity:
elif percent == 100 and (not activity and not installable):
if not self._remove_item:
self._remove_item = MenuItem(ClipboardMenu.ACTION_DELETE,
_('Remove'),
@ -102,8 +102,8 @@ class ClipboardMenu(Menu):
self.remove_item(self._open_item)
self._open_item = None
def set_state(self, name, percent, preview, activity):
def set_state(self, name, percent, preview, activity, installable):
self.set_title(name)
if self._progress_bar:
self._progress_bar.set_property('percent', percent)
self._update_icons(percent, activity)
self._update_icons(percent, activity, installable)