Merge branch 'master' of git+ssh://dev.laptop.org/git/sugar
This commit is contained in:
		
						commit
						1eb9932ab3
					
				@ -1,8 +1,27 @@
 | 
			
		||||
# Copyright (C) 2007, One Laptop Per Child
 | 
			
		||||
#
 | 
			
		||||
# This library is free software; you can redistribute it and/or
 | 
			
		||||
# modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
# License as published by the Free Software Foundation; either
 | 
			
		||||
# version 2 of the License, or (at your option) any later version.
 | 
			
		||||
#
 | 
			
		||||
# This library 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
 | 
			
		||||
# Lesser General Public License for more details.
 | 
			
		||||
#
 | 
			
		||||
# You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
# License along with this library; if not, write to the
 | 
			
		||||
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 | 
			
		||||
# Boston, MA 02111-1307, USA.
 | 
			
		||||
 | 
			
		||||
from gettext import gettext as _
 | 
			
		||||
 | 
			
		||||
import gtk
 | 
			
		||||
import gobject
 | 
			
		||||
 | 
			
		||||
import hippo
 | 
			
		||||
import math
 | 
			
		||||
        
 | 
			
		||||
from sugar.graphics import style
 | 
			
		||||
from sugar.graphics.icon import Icon
 | 
			
		||||
 | 
			
		||||
@ -28,7 +47,7 @@ class Alert(gtk.EventBox, gobject.GObject):
 | 
			
		||||
 | 
			
		||||
    __gsignals__ = {
 | 
			
		||||
        'response': (gobject.SIGNAL_RUN_FIRST,
 | 
			
		||||
                        gobject.TYPE_NONE, ([int]))
 | 
			
		||||
                        gobject.TYPE_NONE, ([object]))
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    __gproperties__ = {
 | 
			
		||||
@ -69,7 +88,8 @@ class Alert(gtk.EventBox, gobject.GObject):
 | 
			
		||||
        self._hbox.pack_start(self._msg_box)
 | 
			
		||||
 | 
			
		||||
        self._buttons_box = gtk.HButtonBox()
 | 
			
		||||
        self._buttons_box.set_layout(gtk.BUTTONBOX_SPREAD)
 | 
			
		||||
        self._buttons_box.set_layout(gtk.BUTTONBOX_END)
 | 
			
		||||
        self._buttons_box.set_spacing(style.DEFAULT_SPACING)
 | 
			
		||||
        self._hbox.pack_start(self._buttons_box)
 | 
			
		||||
        self._buttons_box.show()
 | 
			
		||||
 | 
			
		||||
@ -99,17 +119,20 @@ class Alert(gtk.EventBox, gobject.GObject):
 | 
			
		||||
        elif pspec.name == 'msg':
 | 
			
		||||
            return self._msg
 | 
			
		||||
 | 
			
		||||
    def add_button(self, response_id, label, icon, position=-1):
 | 
			
		||||
    def add_button(self, response_id, label, icon=None, position=-1):
 | 
			
		||||
        """Add a button to the alert
 | 
			
		||||
 | 
			
		||||
        response_id: will be emitted with the response signal
 | 
			
		||||
                     a response ID should one of the pre-defined
 | 
			
		||||
                     GTK Response Type Constants or a positive number
 | 
			
		||||
        label: that will occure right to the buttom
 | 
			
		||||
        icon: this can be a SugarIcon or a gtk.Image
 | 
			
		||||
        position: the position of the button in the box (optional)
 | 
			
		||||
        """
 | 
			
		||||
        button = gtk.Button()
 | 
			
		||||
        self._buttons[response_id] = button
 | 
			
		||||
        button.set_image(icon)
 | 
			
		||||
        if icon is not None:
 | 
			
		||||
            button.set_image(icon)
 | 
			
		||||
        button.set_label(label)
 | 
			
		||||
        self._buttons_box.pack_start(button)
 | 
			
		||||
        button.show()
 | 
			
		||||
@ -142,11 +165,66 @@ class ConfirmationAlert(Alert):
 | 
			
		||||
        Alert.__init__(self, **kwargs)
 | 
			
		||||
 | 
			
		||||
        icon = Icon(icon_name='dialog-cancel')
 | 
			
		||||
        cancel_button = self.add_button(0, _('Cancel'), icon)
 | 
			
		||||
        cancel_button = self.add_button(gtk.RESPONSE_CANCEL, _('Cancel'), icon)
 | 
			
		||||
        icon.show()
 | 
			
		||||
 | 
			
		||||
        icon = Icon(icon_name='dialog-ok')
 | 
			
		||||
        ok_button = self.add_button(1, _('Ok'), icon)
 | 
			
		||||
        ok_button = self.add_button(gtk.RESPONSE_OK, _('Ok'), icon)
 | 
			
		||||
        icon.show()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class _TimeoutIcon(hippo.CanvasText, hippo.CanvasItem):
 | 
			
		||||
    __gtype_name__ = 'AlertTimeoutIcon'
 | 
			
		||||
 | 
			
		||||
    def __init__(self, **kwargs):
 | 
			
		||||
        hippo.CanvasText.__init__(self, **kwargs)
 | 
			
		||||
        
 | 
			
		||||
        self.props.orientation = hippo.ORIENTATION_HORIZONTAL
 | 
			
		||||
        self.props.border_left = style.DEFAULT_SPACING
 | 
			
		||||
        self.props.border_right = style.DEFAULT_SPACING
 | 
			
		||||
            
 | 
			
		||||
    def do_paint_background(self, cr, damaged_box):
 | 
			
		||||
        [width, height] = self.get_allocation()
 | 
			
		||||
        
 | 
			
		||||
        x = width * 0.5
 | 
			
		||||
        y = height * 0.5
 | 
			
		||||
        radius = min(width * 0.5, height * 0.5)         
 | 
			
		||||
        
 | 
			
		||||
        hippo.cairo_set_source_rgba32(cr, self.props.background_color)
 | 
			
		||||
        cr.arc(x, y, radius, 0, 2*math.pi)        
 | 
			
		||||
        cr.fill_preserve()    
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TimeoutAlert(Alert):
 | 
			
		||||
    """This is a ready-made two button (Cancel,Continue) alert
 | 
			
		||||
 | 
			
		||||
    It times out with a positive reponse after the given amount of seconds.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, timeout=5, **kwargs):
 | 
			
		||||
        Alert.__init__(self, **kwargs)
 | 
			
		||||
 | 
			
		||||
        self._timeout = timeout
 | 
			
		||||
        
 | 
			
		||||
        icon = Icon(icon_name='dialog-cancel')
 | 
			
		||||
        cancel_button = self.add_button(gtk.RESPONSE_CANCEL, _('Cancel'), icon)
 | 
			
		||||
        icon.show()
 | 
			
		||||
        
 | 
			
		||||
        self._timeout_text = _TimeoutIcon(
 | 
			
		||||
            text=self._timeout,
 | 
			
		||||
            color=style.COLOR_BUTTON_GREY.get_int(),
 | 
			
		||||
            background_color=style.COLOR_WHITE.get_int())    
 | 
			
		||||
        canvas = hippo.Canvas()
 | 
			
		||||
        canvas.set_root(self._timeout_text)
 | 
			
		||||
        canvas.show()                       
 | 
			
		||||
        self.add_button(gtk.RESPONSE_OK, _('Continue'), canvas)
 | 
			
		||||
 | 
			
		||||
        gobject.timeout_add(1000, self.__timeout)
 | 
			
		||||
        
 | 
			
		||||
    def __timeout(self):
 | 
			
		||||
        self._timeout -= 1
 | 
			
		||||
        self._timeout_text.props.text = self._timeout
 | 
			
		||||
        if self._timeout == 0:
 | 
			
		||||
            self._response(gtk.RESPONSE_OK)
 | 
			
		||||
            return False
 | 
			
		||||
        return True
 | 
			
		||||
 | 
			
		||||
@ -26,9 +26,8 @@ _logger = logging.getLogger('sugar.presence.activity')
 | 
			
		||||
class Activity(gobject.GObject):
 | 
			
		||||
    """UI interface for an Activity in the presence service
 | 
			
		||||
    
 | 
			
		||||
    Activities in the presence service represent other user's
 | 
			
		||||
    shared activities and your own activities (XXX shared or 
 | 
			
		||||
    otherwise?)
 | 
			
		||||
    Activities in the presence service represent your and other user's
 | 
			
		||||
    shared activities.
 | 
			
		||||
    
 | 
			
		||||
    Properties:
 | 
			
		||||
        id 
 | 
			
		||||
@ -69,8 +68,10 @@ class Activity(gobject.GObject):
 | 
			
		||||
        self._ps_del_object = del_obj_cb
 | 
			
		||||
        bobj = bus.get_object(self._PRESENCE_SERVICE, object_path)
 | 
			
		||||
        self._activity = dbus.Interface(bobj, self._ACTIVITY_DBUS_INTERFACE)
 | 
			
		||||
        self._activity.connect_to_signal('BuddyJoined', self._buddy_joined_cb)
 | 
			
		||||
        self._activity.connect_to_signal('BuddyLeft', self._buddy_left_cb)
 | 
			
		||||
        self._activity.connect_to_signal('BuddyHandleJoined', 
 | 
			
		||||
                                         self._buddy_handle_joined_cb)
 | 
			
		||||
        self._activity.connect_to_signal('BuddyLeft',
 | 
			
		||||
                                         self._buddy_left_cb)
 | 
			
		||||
        self._activity.connect_to_signal('NewChannel', self._new_channel_cb)
 | 
			
		||||
        self._activity.connect_to_signal('PropertiesChanged',
 | 
			
		||||
                                         self._properties_changed_cb,
 | 
			
		||||
@ -90,6 +91,9 @@ class Activity(gobject.GObject):
 | 
			
		||||
        self._tags = None
 | 
			
		||||
        self._private = True
 | 
			
		||||
        self._joined = False
 | 
			
		||||
        # Cache for get_buddy_by_handle, maps handles to buddy object paths
 | 
			
		||||
        self._handle_to_buddy_path = {}
 | 
			
		||||
        self._buddy_path_to_handle = {}
 | 
			
		||||
 | 
			
		||||
    def _get_properties_reply_cb(self, new_props):
 | 
			
		||||
        self._properties_changed_cb(new_props)
 | 
			
		||||
@ -178,8 +182,10 @@ class Activity(gobject.GObject):
 | 
			
		||||
        self.emit('buddy-joined', self._ps_new_object(object_path))
 | 
			
		||||
        return False
 | 
			
		||||
 | 
			
		||||
    def _buddy_joined_cb(self, object_path):
 | 
			
		||||
    def _buddy_handle_joined_cb(self, object_path, handle):
 | 
			
		||||
        gobject.idle_add(self._emit_buddy_joined_signal, object_path)
 | 
			
		||||
        self._handle_to_buddy_path[handle] = object_path
 | 
			
		||||
        self._buddy_path_to_handle[object_path] = handle
 | 
			
		||||
 | 
			
		||||
    def _emit_buddy_left_signal(self, object_path):
 | 
			
		||||
        """Generate buddy-left GObject signal with presence Buddy object
 | 
			
		||||
@ -191,6 +197,8 @@ class Activity(gobject.GObject):
 | 
			
		||||
 | 
			
		||||
    def _buddy_left_cb(self, object_path):
 | 
			
		||||
        gobject.idle_add(self._emit_buddy_left_signal, object_path)
 | 
			
		||||
        handle = self._buddy_path_to_handle.pop(object_path)
 | 
			
		||||
        self._handle_to_buddy_path.pop(handle, None)
 | 
			
		||||
 | 
			
		||||
    def _emit_new_channel_signal(self, object_path):
 | 
			
		||||
        """Generate new-channel GObject signal with channel object path 
 | 
			
		||||
@ -214,6 +222,18 @@ class Activity(gobject.GObject):
 | 
			
		||||
            buddies.append(self._ps_new_object(item))
 | 
			
		||||
        return buddies
 | 
			
		||||
 | 
			
		||||
    def get_buddy_by_handle(self, handle):
 | 
			
		||||
        """Retrieve the Buddy object given a telepathy handle.
 | 
			
		||||
        
 | 
			
		||||
        buddy object paths are cached in self._handle_to_buddy_path,
 | 
			
		||||
        so we can get the buddy without calling PS.
 | 
			
		||||
        """
 | 
			
		||||
        object_path = self._handle_to_buddy_path.get(handle, None)
 | 
			
		||||
        if object_path:
 | 
			
		||||
            buddy = self._ps_new_object(object_path)
 | 
			
		||||
            return buddy
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
    def invite(self, buddy, message, response_cb):
 | 
			
		||||
        """Invite the given buddy to join this activity.
 | 
			
		||||
 | 
			
		||||
@ -244,9 +264,13 @@ class Activity(gobject.GObject):
 | 
			
		||||
    def get_channels(self):
 | 
			
		||||
        """Retrieve communications channel descriptions for the activity 
 | 
			
		||||
        
 | 
			
		||||
        Returns (bus name, connection, channels) for the activity
 | 
			
		||||
        
 | 
			
		||||
        XXX what are those values?
 | 
			
		||||
        Returns a tuple containing:
 | 
			
		||||
            - the D-Bus well-known service name of the connection
 | 
			
		||||
              (FIXME: this is redundant; in Telepathy it can be derived
 | 
			
		||||
              from that of the connection)
 | 
			
		||||
            - the D-Bus object path of the connection
 | 
			
		||||
            - a list of D-Bus object paths representing the channels
 | 
			
		||||
              associated with this activity
 | 
			
		||||
        """
 | 
			
		||||
        (bus_name, connection, channels) = self._activity.GetChannels()
 | 
			
		||||
        return bus_name, connection, channels
 | 
			
		||||
@ -256,10 +280,8 @@ class Activity(gobject.GObject):
 | 
			
		||||
        self.emit("joined", False, "left activity")
 | 
			
		||||
 | 
			
		||||
    def _leave_error_cb(self, err):
 | 
			
		||||
        """Callback for error in async leaving of shared activity.
 | 
			
		||||
 | 
			
		||||
        XXX Add logging!"""
 | 
			
		||||
        pass
 | 
			
		||||
        """Callback for error in async leaving of shared activity."""
 | 
			
		||||
        _logger.debug('Failed to leave activity: %s', err)
 | 
			
		||||
 | 
			
		||||
    def leave(self):
 | 
			
		||||
        """Leave this shared activity"""
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user