Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMorgan Collett <morgan.collett@gmail.com>2007-07-11 08:42:27 (GMT)
committer Morgan Collett <morgan.collett@gmail.com>2007-07-11 08:42:27 (GMT)
commit8fab49b64ead8fa9104b7df1501cde2fe40bc8b4 (patch)
tree20aaff0c95262ca0a3c6d613014de1d950e59feb
parent66983f0d24b71a2798018873f5c509def40f0e0e (diff)
parente4bce9271a2db597adb50fce182afe765ac97fa6 (diff)
Merge branch 'master' of git+ssh://dev.laptop.org/git/sugar
-rw-r--r--NEWS23
-rwxr-xr-xbin/sugar-install-bundle3
-rwxr-xr-xmaint-helper.py4
-rw-r--r--po/POTFILES.in1
-rw-r--r--services/clipboard/clipboardobject.py2
-rw-r--r--services/clipboard/clipboardservice.py64
-rw-r--r--services/console/interface/xo/Makefile.am1
-rw-r--r--services/console/interface/xo/battery.py99
-rw-r--r--services/console/interface/xo/xo.py4
-rw-r--r--shell/model/BuddyModel.py5
-rw-r--r--shell/model/Friends.py2
-rw-r--r--shell/model/devices/battery.py35
-rw-r--r--shell/shellservice.py11
-rw-r--r--shell/view/frame/Makefile.am4
-rw-r--r--shell/view/frame/clipboardbox.py17
-rw-r--r--shell/view/frame/frame.py2
-rw-r--r--shell/view/frame/zoombox.py (renamed from shell/view/frame/ZoomBox.py)24
-rw-r--r--shell/view/home/FriendsBox.py11
-rw-r--r--sugar/activity/activity.py24
-rw-r--r--sugar/activity/bundlebuilder.py16
-rw-r--r--sugar/activity/registry.py28
-rw-r--r--sugar/graphics/style.py12
-rw-r--r--sugar/objects/objecttype.py23
23 files changed, 216 insertions, 199 deletions
diff --git a/NEWS b/NEWS
index c220664..beabf43 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,26 @@
+* #1984 Fix removing items from the clipboard. (tomeu)
+
+Snapshot b83a9ec27d
+
+* Fix font size on the XO. (marco)
+* Make developer console work again. (marco)
+* #2020 Use the new activity-stop icon. (marco)
+* #2002 Tooltips for the zoom levels. (marco)
+* #2018 Rename Save to Keep. (marco)
+* #2020 Rename Close to Stop. (marco)
+
+Snapshot 42f0bcc48d
+
+* Fix broken import which was preventing startup. (marco)
+
+Snapshot 757b2b8ce6
+
+* #2031: Do not die if battery properties are unavailable. (marco)
+* #1953: Retrieve friends' nicks from the profile. (tomeu)
+* #1720: Show the owner's buddy menu in the Groups view. (tomeu)
+
+Snapshot aa6a024368
+
* #1825: Fix tab label padding. (marco)
* #1823: Margin at the toolbar tabs bottom. (marco)
* #1872, #1934: Hide palettes when closing activities or switching views. (tomeu)
diff --git a/bin/sugar-install-bundle b/bin/sugar-install-bundle
index 883dbfb..3cce4cb 100755
--- a/bin/sugar-install-bundle
+++ b/bin/sugar-install-bundle
@@ -3,6 +3,9 @@ import sys
from sugar.activity.bundle import Bundle
+from dbus.mainloop.glib import DBusGMainLoop
+DBusGMainLoop(set_as_default=True)
+
bundle = Bundle(sys.argv[1])
bundle.install()
diff --git a/maint-helper.py b/maint-helper.py
index 9b76d51..8c64ca2 100755
--- a/maint-helper.py
+++ b/maint-helper.py
@@ -83,8 +83,8 @@ def cmd_build_snapshot():
sugar_news += '%s - %s - %s\n\n' % (name, version, alphatag)
f = open('NEWS', 'r')
- for line in f.readline():
- if len(line) > 0:
+ for line in f.readlines():
+ if len(line.strip()) > 0:
sugar_news += line
else:
break
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 2b6d5a0..2c034d8 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -7,4 +7,5 @@ shell/view/Shell.py
shell/view/clipboardicon.py
shell/view/home/HomeBox.py
shell/view/home/MeshBox.py
+shell/view/devices/battery.py
sugar/activity/activity.py
diff --git a/services/clipboard/clipboardobject.py b/services/clipboard/clipboardobject.py
index 133e667..c2ce339 100644
--- a/services/clipboard/clipboardobject.py
+++ b/services/clipboard/clipboardobject.py
@@ -141,7 +141,7 @@ class Format:
def get_data(self):
return self._data
- def _set_data(self, data):
+ def set_data(self, data):
self._data = data
def is_on_disk(self):
diff --git a/services/clipboard/clipboardservice.py b/services/clipboard/clipboardservice.py
index 73552c4..569ed6b 100644
--- a/services/clipboard/clipboardservice.py
+++ b/services/clipboard/clipboardservice.py
@@ -17,10 +17,16 @@
import logging
import os
import shutil
+import urlparse
+import tempfile
+
import dbus
import dbus.service
+
from sugar import env
from sugar import util
+from sugar.objects import mime
+
from clipboardobject import ClipboardObject, Format
NAME_KEY = 'NAME'
@@ -52,34 +58,6 @@ class ClipboardService(dbus.service.Object):
self._next_id += 1
return self._next_id
- def _handle_file_completed(self, cb_object):
- """If the object is an on-disk file, and it's at 100%, and we care about
- it's file type, copy that file to $HOME and upate the clipboard object's
- data to point to the new location"""
- formats = cb_object.get_formats()
- if not len(formats) or len(formats) > 1:
- return
-
- format = formats.values()[0]
- if not format.is_on_disk():
- return
-
- if not len(cb_object.get_activity()):
- # no activity to handle this, don't autosave it
- return
-
- # copy to homedir
- src = format.get_data()
- if not os.path.exists(src):
- logging.debug("File %s doesn't appear to exist" % src)
- return
- dst = os.path.join(os.path.expanduser("~"), os.path.basename(src))
- try:
- shutil.move(src, dst)
- format._set_data(dst)
- except IOError, e:
- logging.debug("Couldn't move file %s to %s: %s" % (src, dst, e))
-
# dbus methods
@dbus.service.method(_CLIPBOARD_DBUS_INTERFACE,
in_signature="s", out_signature="o")
@@ -96,11 +74,13 @@ class ClipboardService(dbus.service.Object):
def add_object_format(self, object_path, format_type, data, on_disk):
logging.debug('ClipboardService.add_object_format')
cb_object = self._objects[str(object_path)]
- cb_object.add_format(Format(format_type, data, on_disk))
-
- if on_disk:
- logging.debug('Added format of type ' + format_type + ' with path at ' + data)
+
+ if on_disk and cb_object.get_percent() == 100:
+ new_uri = self._copy_file(data)
+ cb_object.add_format(Format(format_type, new_uri, on_disk))
+ logging.debug('Added format of type ' + format_type + ' with path at ' + new_uri)
else:
+ cb_object.add_format(Format(format_type, data, on_disk))
logging.debug('Added in-memory format of type ' + format_type + '.')
self.object_state_changed(object_path, {NAME_KEY: cb_object.get_name(),
@@ -132,7 +112,10 @@ class ClipboardService(dbus.service.Object):
cb_object.set_percent(percent)
if percent == 100:
- self._handle_file_completed(cb_object)
+ for format_name, format in cb_object.get_formats().iteritems():
+ if format.is_on_disk():
+ new_uri = self._copy_file(format.get_data())
+ format.set_data(new_uri)
self.object_state_changed(object_path, {NAME_KEY: cb_object.get_name(),
PERCENT_KEY: percent,
@@ -183,6 +166,21 @@ class ClipboardService(dbus.service.Object):
def object_state_changed(self, object_path, values):
pass
+ def _copy_file(self, original_uri):
+ uri = urlparse.urlparse(original_uri)
+ path, file_name = os.path.split(uri.path)
+
+ root, ext = os.path.splitext(file_name)
+ if not ext or ext == '.':
+ mime_type = mime.get_for_file(uri.path)
+ ext = '.' + mime.get_primary_extension(mime_type)
+
+ f, new_file_path = tempfile.mkstemp(ext, root)
+ del f
+ shutil.copyfile(uri.path, new_file_path)
+
+ return 'file://' + new_file_path
+
_instance = None
def get_instance():
diff --git a/services/console/interface/xo/Makefile.am b/services/console/interface/xo/Makefile.am
index be9be79..dbc96c4 100644
--- a/services/console/interface/xo/Makefile.am
+++ b/services/console/interface/xo/Makefile.am
@@ -4,5 +4,4 @@ sugar_PYTHON = \
xo.py \
cpu.py \
system.py \
- battery.py \
nandflash.py
diff --git a/services/console/interface/xo/battery.py b/services/console/interface/xo/battery.py
deleted file mode 100644
index 8731d8b..0000000
--- a/services/console/interface/xo/battery.py
+++ /dev/null
@@ -1,99 +0,0 @@
-# Copyright (C) 2007, Eduardo Silva (edsiper@gmail.com).
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-import gtk
-import gobject
-
-from label import Label
-from graphics.box import BoxGraphic
-
-class XO_Battery(gtk.Fixed):
-
- def __init__(self):
- gtk.Fixed.__init__(self)
-
- self._frame_text = 'Battery Status'
- self.frame = gtk.Frame(self._frame_text)
- self.set_border_width(10)
-
- self._battery_charge = self._get_battery_status()
-
- self._battery_box = BoxGraphic()
- self._battery_box.set_size_request(70, 150)
- self._battery_box.set_capacity(self._battery_charge)
-
- fixed = gtk.Fixed();
- fixed.set_border_width(10)
- fixed.add(self._battery_box)
-
- hbox = gtk.HBox(False, 0)
- hbox.pack_start(fixed, False, False, 4)
-
- # Battery info
- table = gtk.Table(2, 2)
- table.set_border_width(5)
- table.set_col_spacings(7)
- table.set_row_spacings(7)
-
- label_charge = Label('Charge: ' , Label.DESCRIPTION)
- self.label_charge_value = Label(str(self._battery_charge) + '%', Label.DESCRIPTION)
-
- table.attach(label_charge, 0, 1, 0, 1)
- table.attach(self.label_charge_value, 1,2, 0,1)
-
- # Charging
- """
- hbox_charging = gtk.HBox(False, 2)
- l_charging = gtk.Label('Charging: ')
- l_charging.set_justify(gtk.JUSTIFY_LEFT)
- hbox_charging.pack_start(l_charging, False, False, 0)
-
- self._label_charging = gtk.Label('No')
- self._label_charging.set_justify(gtk.JUSTIFY_LEFT)
-
- hbox_charging.pack_start(self._label_charging, False, False, 0)
- """
-
- alignment = gtk.Alignment(0,0,0,0)
- alignment.add(table)
-
- hbox.pack_start(alignment, False, False, 0)
- self.frame.add(hbox)
- self.add(self.frame)
- self.show_all()
-
- def update_status(self):
-
- new_charge = self._get_battery_status()
- frame_label = str(self._battery_charge) + '%'
-
- if new_charge != self._battery_charge:
- self._battery_charge = self._get_battery_status()
- self.label_charge_value.set_text(frame_label)
- self._battery_box.set_capacity(self._battery_charge)
-
- def _get_battery_status(self):
- battery_class_path = '/sys/class/battery/psu_0/'
- capacity_path = battery_class_path + 'capacity_percentage'
- try:
- f = open(capacity_path, 'r')
- val = f.read().split('\n')
- capacity = int(val[0])
- f.close()
- except:
- capacity = 0
-
- return capacity
diff --git a/services/console/interface/xo/xo.py b/services/console/interface/xo/xo.py
index 981d2e5..d205605 100644
--- a/services/console/interface/xo/xo.py
+++ b/services/console/interface/xo/xo.py
@@ -23,7 +23,6 @@ import string
from cpu import XO_CPU
from system import XO_System
-from battery import XO_Battery
from nandflash import XO_NandFlash
class Interface:
@@ -40,11 +39,9 @@ class Interface:
self.vbox.pack_start(xo_cpu, False, False, 0)
# Graphics: Battery Status, NandFlash
- self._xo_battery = XO_Battery()
self._xo_nandflash = XO_NandFlash()
hbox = gtk.HBox(False, 2)
- hbox.pack_start(self._xo_battery, False, False, 0)
hbox.pack_start(self._xo_nandflash, False, False, 0)
self.vbox.pack_start(hbox, False, False, 0)
@@ -54,7 +51,6 @@ class Interface:
gobject.timeout_add(5000, self._update_components)
def _update_components(self):
- self._xo_battery.update_status()
self._xo_nandflash.update_status()
return True
diff --git a/shell/model/BuddyModel.py b/shell/model/BuddyModel.py
index 75c044a..9f86e57 100644
--- a/shell/model/BuddyModel.py
+++ b/shell/model/BuddyModel.py
@@ -36,7 +36,7 @@ class BuddyModel(gobject.GObject):
([gobject.TYPE_PYOBJECT]))
}
- def __init__(self, key=None, buddy=None):
+ def __init__(self, key=None, buddy=None, nick=None):
if (key and buddy) or (not key and not buddy):
raise RuntimeError("Must specify only _one_ of key or buddy.")
@@ -51,7 +51,6 @@ class BuddyModel(gobject.GObject):
self._pservice = presenceservice.get_instance()
self._buddy = None
- self._nick = None
# If given just a key, try to get the buddy from the PS first
if not buddy:
@@ -72,7 +71,7 @@ class BuddyModel(gobject.GObject):
self._key = key
# Set color to 'inactive'/'disconnected'
self._set_color_from_string(_NOT_PRESENT_COLOR)
- self._name = "Unknown buddy"
+ self._nick = nick
def _set_color_from_string(self, color_string):
self._color = XoColor(color_string)
diff --git a/shell/model/Friends.py b/shell/model/Friends.py
index 23ce94a..2b7d6bf 100644
--- a/shell/model/Friends.py
+++ b/shell/model/Friends.py
@@ -69,7 +69,7 @@ class Friends(gobject.GObject):
# HACK: don't screw up on old friends files
if len(key) < 20:
continue
- buddy = BuddyModel(key=key)
+ buddy = BuddyModel(key=key, nick=cp.get(key, 'nick'))
self.add_friend(buddy)
except Exception, exc:
logging.error("Error parsing friends file: %s" % exc)
diff --git a/shell/model/devices/battery.py b/shell/model/devices/battery.py
index cdb4994..853d00e 100644
--- a/shell/model/devices/battery.py
+++ b/shell/model/devices/battery.py
@@ -14,6 +14,8 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+import logging
+
import gobject
import dbus
@@ -45,9 +47,30 @@ class Device(device.Device):
'org.freedesktop.Hal',
udi)
- self._level = self._battery.GetProperty(_LEVEL_PROP)
- self._charging = self._battery.GetProperty(_CHARGING_PROP)
- self._discharging = self._battery.GetProperty(_DISCHARGING_PROP)
+ self._level = self._get_level()
+ self._charging = self._get_charging()
+ self._discharging = self._get_discharging()
+
+ def _get_level(self):
+ try:
+ return self._battery.GetProperty(_LEVEL_PROP)
+ except dbus.DBusException:
+ logging.error('Cannot access %s' % _LEVEL_PROP)
+ return 0
+
+ def _get_charging(self):
+ try:
+ return self._battery.GetProperty(_CHARGING_PROP)
+ except dbus.DBusException:
+ logging.error('Cannot access %s' % _CHARGING_PROP)
+ return False
+
+ def _get_discharging(self):
+ try:
+ return self._battery.GetProperty(_DISCHARGING_PROP)
+ except dbus.DBusException:
+ logging.error('Cannot access %s' % _DISCHARGING_PROP)
+ return False
def do_get_property(self, pspec):
if pspec.name == 'level':
@@ -63,11 +86,11 @@ class Device(device.Device):
def _battery_changed(self, num_changes, changes_list):
for change in changes_list:
if change[0] == _LEVEL_PROP:
- self._level = self._battery.GetProperty(_LEVEL_PROP)
+ self._level = self._get_level()
self.notify('level')
elif change[0] == _CHARGING_PROP:
- self._charging = self._battery.GetProperty(_CHARGING_PROP)
+ self._charging = self._get_charging()
self.notify('charging')
elif change[0] == _DISCHARGING_PROP:
- self._discharging = self._battery.GetProperty(_DISCHARGING_PROP)
+ self._discharging = self._get_discharging()
self.notify('discharging')
diff --git a/shell/shellservice.py b/shell/shellservice.py
index b4c96ff..c612d6e 100644
--- a/shell/shellservice.py
+++ b/shell/shellservice.py
@@ -56,6 +56,9 @@ class ShellService(dbus.service.Object):
self._home_model.connect('active-activity-changed',
self._cur_activity_changed_cb)
+ bundle_registry = bundleregistry.get_registry()
+ bundle_registry.connect('bundle-added', self._bundle_added_cb)
+
bus = dbus.SessionBus()
bus_name = dbus.service.BusName(_DBUS_SERVICE, bus=bus)
dbus.service.Object.__init__(self, bus_name, _DBUS_PATH)
@@ -121,6 +124,10 @@ class ShellService(dbus.service.Object):
return result
+ @dbus.service.signal(_DBUS_ACTIVITY_REGISTRY_IFACE, signature="a{sv}")
+ def ActivityAdded(self, activity_info):
+ pass
+
@dbus.service.signal(_DBUS_OWNER_IFACE, signature="s")
def ColorChanged(self, color):
pass
@@ -158,3 +165,7 @@ class ShellService(dbus.service.Object):
'icon': bundle.get_icon(),
'service_name': bundle.get_service_name(),
'path': bundle.get_path()}
+
+ def _bundle_added_cb(self, bundle_registry, bundle):
+ self.ActivityAdded(self._bundle_to_dict(bundle))
+
diff --git a/shell/view/frame/Makefile.am b/shell/view/frame/Makefile.am
index ff2bff3..4a7083b 100644
--- a/shell/view/frame/Makefile.am
+++ b/shell/view/frame/Makefile.am
@@ -8,6 +8,6 @@ sugar_PYTHON = \
FriendsBox.py \
eventarea.py \
frame.py \
- ZoomBox.py \
overlaybox.py \
- framewindow.py
+ framewindow.py \
+ zoombox.py
diff --git a/shell/view/frame/clipboardbox.py b/shell/view/frame/clipboardbox.py
index 7cb3698..60c154b 100644
--- a/shell/view/frame/clipboardbox.py
+++ b/shell/view/frame/clipboardbox.py
@@ -13,16 +13,14 @@
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-import shutil
+
import os
import logging
-import urlparse
import hippo
import gtk
from sugar import util
-from sugar.objects import mime
from view.clipboardicon import ClipboardIcon
from sugar.clipboard import clipboardservice
@@ -101,21 +99,10 @@ class ClipboardBox(hippo.CanvasBox):
uris = selection.data.split('\n')
if len(uris) > 1:
raise NotImplementedError('Multiple uris in text/uri-list still not supported.')
- uri = urlparse.urlparse(uris[0])
- path, file_name = os.path.split(uri.path)
-
- root, ext = os.path.splitext(file_name)
- if not ext or ext == '.':
- mime_type = mime.get_for_file(uri.path)
- file_name = root + '.' + mime.get_primary_extension(mime_type)
-
- # Copy the file, as it will be deleted when the dnd operation finishes.
- new_file_path = os.path.join(path, 'cb' + file_name)
- shutil.copyfile(uri.path, new_file_path)
cb_service.add_object_format(object_id,
selection.type,
- "file://" + new_file_path,
+ uris[0],
on_disk=True)
else:
cb_service.add_object_format(object_id,
diff --git a/shell/view/frame/frame.py b/shell/view/frame/frame.py
index 5210f57..2a94754 100644
--- a/shell/view/frame/frame.py
+++ b/shell/view/frame/frame.py
@@ -27,7 +27,7 @@ from sugar.clipboard import clipboardservice
from view.frame.eventarea import EventArea
from view.frame.ActivitiesBox import ActivitiesBox
-from view.frame.ZoomBox import ZoomBox
+from view.frame.zoombox import ZoomBox
from view.frame.overlaybox import OverlayBox
from view.frame.FriendsBox import FriendsBox
from view.frame.framewindow import FrameWindow
diff --git a/shell/view/frame/ZoomBox.py b/shell/view/frame/zoombox.py
index 5bfb0e7..f4b8535 100644
--- a/shell/view/frame/ZoomBox.py
+++ b/shell/view/frame/zoombox.py
@@ -14,10 +14,14 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+from gettext import gettext as _
+
import hippo
from sugar.graphics import color
+from sugar.graphics.palette import Palette
from sugar.graphics.iconbutton import IconButton
+from frameinvoker import FrameCanvasInvoker
from model.shellmodel import ShellModel
@@ -35,6 +39,11 @@ class ZoomBox(hippo.CanvasBox):
ShellModel.ZOOM_MESH)
self.append(icon)
+ palette = Palette(_('Neighborhood'))
+ palette.props.invoker = FrameCanvasInvoker(icon)
+ palette.set_group_id('frame')
+ icon.set_palette(palette)
+
icon = IconButton(icon_name='theme:stock-zoom-friends',
stroke_color=color.BLACK,
fill_color=color.WHITE)
@@ -43,6 +52,11 @@ class ZoomBox(hippo.CanvasBox):
ShellModel.ZOOM_FRIENDS)
self.append(icon)
+ palette = Palette(_('Group'))
+ palette.props.invoker = FrameCanvasInvoker(icon)
+ palette.set_group_id('frame')
+ icon.set_palette(palette)
+
icon = IconButton(icon_name='theme:stock-zoom-home',
stroke_color=color.BLACK,
fill_color=color.WHITE)
@@ -51,6 +65,11 @@ class ZoomBox(hippo.CanvasBox):
ShellModel.ZOOM_HOME)
self.append(icon)
+ palette = Palette(_('Home'))
+ palette.props.invoker = FrameCanvasInvoker(icon)
+ palette.set_group_id('frame')
+ icon.set_palette(palette)
+
icon = IconButton(icon_name='theme:stock-zoom-activity',
stroke_color=color.BLACK,
fill_color=color.WHITE)
@@ -59,5 +78,10 @@ class ZoomBox(hippo.CanvasBox):
ShellModel.ZOOM_ACTIVITY)
self.append(icon)
+ palette = Palette(_('Activity'))
+ palette.props.invoker = FrameCanvasInvoker(icon)
+ palette.set_group_id('frame')
+ icon.set_palette(palette)
+
def _level_clicked_cb(self, item, level):
self._shell.set_zoom_level(level)
diff --git a/shell/view/home/FriendsBox.py b/shell/view/home/FriendsBox.py
index 39afa0b..77218b0 100644
--- a/shell/view/home/FriendsBox.py
+++ b/shell/view/home/FriendsBox.py
@@ -19,9 +19,12 @@ import random
import hippo
import gobject
+from sugar import profile
from sugar.graphics.spreadlayout import SpreadLayout
from sugar.graphics import units
-from view.home.MyIcon import MyIcon
+
+from model.BuddyModel import BuddyModel
+from view.BuddyIcon import BuddyIcon
from view.home.FriendView import FriendView
class FriendsBox(hippo.CanvasBox):
@@ -35,8 +38,10 @@ class FriendsBox(hippo.CanvasBox):
self._layout = SpreadLayout()
self.set_layout(self._layout)
- self._my_icon = MyIcon(units.LARGE_ICON_SCALE)
- self._layout.add_center(self._my_icon)
+ buddy_model = BuddyModel(key=profile.get_pubkey())
+ self._owner_icon = BuddyIcon(shell, buddy_model)
+ self._owner_icon.props.scale = units.LARGE_ICON_SCALE
+ self._layout.add_center(self._owner_icon)
friends = self._shell.get_model().get_friends()
diff --git a/sugar/activity/activity.py b/sugar/activity/activity.py
index 8a97199..3202703 100644
--- a/sugar/activity/activity.py
+++ b/sugar/activity/activity.py
@@ -64,11 +64,11 @@ class ActivityToolbar(gtk.Toolbar):
self.insert(separator, -1)
separator.show()
- self.save = ToolButton('document-save')
- self.save.set_tooltip(_('Save'))
- self.save.connect('clicked', self._save_clicked_cb)
- self.insert(self.save, -1)
- self.save.show()
+ self.keep = ToolButton('document-save')
+ self.keep.set_tooltip(_('Keep'))
+ self.keep.connect('clicked', self._keep_clicked_cb)
+ self.insert(self.keep, -1)
+ self.keep.show()
self.share = ToolButton('stock-share-mesh')
self.share.set_tooltip(_('Share'))
@@ -83,21 +83,21 @@ class ActivityToolbar(gtk.Toolbar):
self.insert(separator, -1)
separator.show()
- self.close = ToolButton('window-close')
- self.close.set_tooltip(_('Close'))
- self.close.connect('clicked', self._close_clicked_cb)
- self.insert(self.close, -1)
- self.close.show()
+ self.stop = ToolButton('activity-stop')
+ self.stop.set_tooltip(_('Stop'))
+ self.stop.connect('clicked', self._stop_clicked_cb)
+ self.insert(self.stop, -1)
+ self.stop.show()
self._update_title_sid = None
def _share_clicked_cb(self, button):
self._activity.share()
- def _save_clicked_cb(self, button):
+ def _keep_clicked_cb(self, button):
self._activity.save()
- def _close_clicked_cb(self, button):
+ def _stop_clicked_cb(self, button):
self._activity.close()
self._activity.destroy()
diff --git a/sugar/activity/bundlebuilder.py b/sugar/activity/bundlebuilder.py
index a82d744..8e8c49d 100644
--- a/sugar/activity/bundlebuilder.py
+++ b/sugar/activity/bundlebuilder.py
@@ -50,26 +50,22 @@ class _DefaultFileList(list):
self.append(os.path.join('activity', name))
self.append('activity/activity.info')
- self.append('setup.py')
if os.path.isfile(_get_source_path('NEWS')):
self.append('NEWS')
-class _ManifestFileList(list):
- def __init__(self, manifest=None):
+class _ManifestFileList(_DefaultFileList):
+ def __init__(self, manifest):
+ _DefaultFileList.__init__(self)
self.append(manifest)
f = open(manifest,'r')
for line in f.readlines():
stripped_line = line.strip()
- if stripped_line:
+ if stripped_line and not stripped_line in self:
self.append(stripped_line)
f.close()
- defaults = _DefaultFileList()
- for path in defaults:
- self.append(path)
-
def _extract_bundle(source_file, dest_dir):
if not os.path.exists(dest_dir):
os.mkdir(dest_dir)
@@ -270,8 +266,8 @@ def cmd_release(bundle_name, manifest):
sugar_news += '%s - %d\n\n' % (bundle_name, version)
f = open(news_path,'r')
- for line in f.readline():
- if len(line) > 0:
+ for line in f.readlines():
+ if len(line.strip()) > 0:
sugar_news += line
else:
break
diff --git a/sugar/activity/registry.py b/sugar/activity/registry.py
index 171f740..b19abee 100644
--- a/sugar/activity/registry.py
+++ b/sugar/activity/registry.py
@@ -15,6 +15,8 @@
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
+import logging
+
import dbus
_SHELL_SERVICE = "org.laptop.Shell"
@@ -39,6 +41,11 @@ class ActivityRegistry(object):
bus = dbus.SessionBus()
bus_object = bus.get_object(_SHELL_SERVICE, _SHELL_PATH)
self._registry = dbus.Interface(bus_object, _REGISTRY_IFACE)
+ self._registry.connect_to_signal('ActivityAdded', self._activity_added_cb)
+
+ # Two caches fo saving some travel across dbus.
+ self._service_name_to_activity_info = {}
+ self._mime_type_to_activities = {}
def _convert_info_list(self, info_list):
result = []
@@ -49,16 +56,33 @@ class ActivityRegistry(object):
return result
def get_activity(self, service_name):
+ if self._service_name_to_activity_info.has_key(service_name):
+ return self._service_name_to_activity_info[service_name]
+
info_dict = self._registry.GetActivity(service_name)
- return _activity_info_from_dict(info_dict)
+ activity_info = _activity_info_from_dict(info_dict)
+
+ self._service_name_to_activity_info[service_name] = activity_info
+ return activity_info
def find_activity(self, name):
info_list = self._registry.FindActivity(name)
return self._convert_info_list(info_list)
def get_activities_for_type(self, mime_type):
+ if self._mime_type_to_activities.has_key(mime_type):
+ return self._mime_type_to_activities[mime_type]
+
info_list = self._registry.GetActivitiesForType(mime_type)
- return self._convert_info_list(info_list)
+ activities = self._convert_info_list(info_list)
+
+ self._mime_type_to_activities[mime_type] = activities
+ return activities
+
+ def _activity_added_cb(self, bundle):
+ logging.debug('ActivityRegistry._activity_added_cb: flushing caches')
+ self._service_name_to_activity_info.clear()
+ self._mime_type_to_activities.clear()
_registry = None
diff --git a/sugar/graphics/style.py b/sugar/graphics/style.py
index fedbc9e..1306caa 100644
--- a/sugar/graphics/style.py
+++ b/sugar/graphics/style.py
@@ -18,6 +18,10 @@
import gtk
import pango
+def _get_screen_dpi():
+ xft_dpi = gtk.settings_get_default().get_property('gtk-xft-dpi')
+ return float(xft_dpi / 1024)
+
def _compute_zoom_factor():
return gtk.gdk.screen_width() / 1200.0
@@ -43,17 +47,21 @@ class Font(object):
def get_pango_desc(self):
return pango.FontDescription(self._desc)
+_XO_DPI = 200.0
+
_FOCUS_LINE_WIDTH = 2
_TAB_CURVATURE = 1
ZOOM_FACTOR = _compute_zoom_factor()
-FONT_SIZE = _zoom(7 * 200 / 72.0)
+FONT_SIZE = _zoom(7 * _XO_DPI / _get_screen_dpi())
FONT_NORMAL = Font('Bitstream Vera Sans %d' % FONT_SIZE)
FONT_BOLD = Font('Bitstream Vera Sans bold %d' % FONT_SIZE)
+FONT_NORMAL_H = _compute_font_height(FONT_NORMAL)
+FONT_BOLD_H = _compute_font_height(FONT_BOLD)
TOOLBOX_SEPARATOR_HEIGHT = _zoom(9)
TOOLBOX_HORIZONTAL_PADDING = _zoom(75)
-TOOLBOX_TAB_VBORDER = int((_zoom(36) - FONT_SIZE - _FOCUS_LINE_WIDTH) / 2)
+TOOLBOX_TAB_VBORDER = int((_zoom(36) - FONT_NORMAL_H - _FOCUS_LINE_WIDTH) / 2)
TOOLBOX_TAB_HBORDER = _zoom(15) - _FOCUS_LINE_WIDTH - _TAB_CURVATURE
TOOLBOX_TAB_LABEL_WIDTH = _zoom(150 - 15 * 2)
diff --git a/sugar/objects/objecttype.py b/sugar/objects/objecttype.py
index dd2da54..a819216 100644
--- a/sugar/objects/objecttype.py
+++ b/sugar/objects/objecttype.py
@@ -36,20 +36,39 @@ class ObjectType(object):
self.name = name
self.icon = icon
self.mime_types = mime_types
+
+ self._type_id_to_type = {}
+ self._mime_type_to_type = {}
class ObjectTypeRegistry(object):
def __init__(self):
bus = dbus.SessionBus()
bus_object = bus.get_object(_SERVICE, _PATH)
self._registry = dbus.Interface(bus_object, _IFACE)
+
+ # Two caches fo saving some travel across dbus.
+ self._type_id_to_type = {}
+ self._mime_type_to_type = {}
def get_type(self, type_id):
+ if self._type_id_to_type.has_key(type_id):
+ return self._type_id_to_type[type_id]
+
type_dict = self._registry.GetType(type_id)
- return _object_type_from_dict(type_dict)
+ object_type = _object_type_from_dict(type_dict)
+
+ self._type_id_to_type[type_id] = object_type
+ return object_type
def get_type_for_mime(self, mime_type):
+ if self._mime_type_to_type.has_key(mime_type):
+ return self._mime_type_to_type[mime_type]
+
type_dict = self._registry.GetTypeForMIME(mime_type)
- return _object_type_from_dict(type_dict)
+ object_type = _object_type_from_dict(type_dict)
+
+ self._mime_type_to_type[mime_type] = object_type
+ return object_type
_registry = None