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

This commit is contained in:
Marco Pesenti Gritti 2007-10-15 23:48:17 +02:00
commit 1eb9932ab3
3 changed files with 122 additions and 20 deletions

2
NEWS
View File

@ -1,3 +1,5 @@
Added TimeoutAlert (erikos)
Snapshot 68ff71a0cb
Snapshot 29bc0a8a20

View File

@ -1,7 +1,26 @@
# 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

View File

@ -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"""