From 764cd49bfb0596c780554078d9c3b2e121a9aa30 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Mon, 9 Jul 2007 19:30:03 +0200 Subject: [PATCH 01/26] Snapshot aa6a024368. --- NEWS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS b/NEWS index c2206648..721fd914 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,5 @@ +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) From f65c507e10e0d56a313768af26afa8ff78743d63 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Mon, 9 Jul 2007 19:37:30 +0200 Subject: [PATCH 02/26] Fix parsing --- maint-helper.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/maint-helper.py b/maint-helper.py index 9b76d519..8c64ca2d 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 From 1ae7a908eab97bd3a8475feec20ce490c725a1b7 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Mon, 9 Jul 2007 19:55:06 +0200 Subject: [PATCH 03/26] Fix parsing bug --- sugar/activity/bundlebuilder.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sugar/activity/bundlebuilder.py b/sugar/activity/bundlebuilder.py index a82d744b..11fae53e 100644 --- a/sugar/activity/bundlebuilder.py +++ b/sugar/activity/bundlebuilder.py @@ -270,8 +270,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 From ecca1dca0011df7d40f424e89a75f0cc9193b874 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Mon, 9 Jul 2007 20:14:24 +0200 Subject: [PATCH 04/26] Add caching to the activity and object type registries. --- bin/sugar-install-bundle | 3 +++ shell/shellservice.py | 11 +++++++++++ sugar/activity/registry.py | 28 ++++++++++++++++++++++++++-- sugar/objects/objecttype.py | 23 +++++++++++++++++++++-- 4 files changed, 61 insertions(+), 4 deletions(-) diff --git a/bin/sugar-install-bundle b/bin/sugar-install-bundle index 883dbfb6..3cce4cb1 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/shell/shellservice.py b/shell/shellservice.py index b4c96ffc..c612d6e2 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/sugar/activity/registry.py b/sugar/activity/registry.py index 171f740e..b19abee6 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/objects/objecttype.py b/sugar/objects/objecttype.py index dd2da548..a8192168 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 From f0c8fe19feda8b06747e3b9aa11c4ac84aead723 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Mon, 9 Jul 2007 21:34:28 +0200 Subject: [PATCH 05/26] #1953: Retrieve friends' nicks from the profile. --- NEWS | 2 ++ shell/model/BuddyModel.py | 5 ++--- shell/model/Friends.py | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 721fd914..1bc9431e 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,5 @@ +* #1953: Retrieve friends' nicks from the profile. (tomeu) + Snapshot aa6a024368 * #1825: Fix tab label padding. (marco) diff --git a/shell/model/BuddyModel.py b/shell/model/BuddyModel.py index 75c044ac..9f86e57e 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 23ce94a8..2b7d6bfd 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) From 7900e6c486938692f8ed2ba61fd73d8f5b488246 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Mon, 9 Jul 2007 22:22:41 +0200 Subject: [PATCH 06/26] #1720: Show the owner's buddy menu in the Groups view. --- NEWS | 1 + shell/view/home/FriendsBox.py | 11 ++++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 1bc9431e..e49e0e9e 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,5 @@ * #1953: Retrieve friends' nicks from the profile. (tomeu) +* #1720: Show the owner's buddy menu in the Groups view. (tomeu) Snapshot aa6a024368 diff --git a/shell/view/home/FriendsBox.py b/shell/view/home/FriendsBox.py index 39afa0bc..6e890252 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 shell.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() From dae54f34ae9b230a695c502f811667f82f7e2fc5 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Tue, 10 Jul 2007 12:35:00 +0200 Subject: [PATCH 07/26] Do not fail if cannot access the HAL battery properties. --- shell/model/devices/battery.py | 35 ++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/shell/model/devices/battery.py b/shell/model/devices/battery.py index cdb49948..853d00ec 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') From 757b2b8ce6c27a91b8f6a1cb01291cdc2291e8bc Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Tue, 10 Jul 2007 12:36:24 +0200 Subject: [PATCH 08/26] Update NEWS --- NEWS | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS b/NEWS index e49e0e9e..8a3634b5 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,4 @@ +* #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) From 978c3a0785e024dd7c83252b39ac6119c64aa655 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Tue, 10 Jul 2007 12:40:34 +0200 Subject: [PATCH 09/26] Snapshot 757b2b8ce6. --- NEWS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS b/NEWS index 8a3634b5..b2b39f02 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,5 @@ +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) From 412ec8c78f0ed6014d00ebab4169b50ace670af2 Mon Sep 17 00:00:00 2001 From: Eduardo Silva Date: Tue, 10 Jul 2007 07:17:52 -0400 Subject: [PATCH 10/26] Console: drop battery viewer --- services/console/interface/xo/battery.py | 99 ------------------------ services/console/interface/xo/xo.py | 2 - 2 files changed, 101 deletions(-) delete mode 100644 services/console/interface/xo/battery.py diff --git a/services/console/interface/xo/battery.py b/services/console/interface/xo/battery.py deleted file mode 100644 index 8731d8b9..00000000 --- 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 981d2e52..63bba0b4 100644 --- a/services/console/interface/xo/xo.py +++ b/services/console/interface/xo/xo.py @@ -40,11 +40,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) From 6a49f11d5e336f8198a7eb49e2420fd12c1cf3c8 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Tue, 10 Jul 2007 13:31:58 +0200 Subject: [PATCH 11/26] Fix broken import --- shell/view/home/FriendsBox.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/view/home/FriendsBox.py b/shell/view/home/FriendsBox.py index 6e890252..77218b04 100644 --- a/shell/view/home/FriendsBox.py +++ b/shell/view/home/FriendsBox.py @@ -23,7 +23,7 @@ from sugar import profile from sugar.graphics.spreadlayout import SpreadLayout from sugar.graphics import units -from shell.model.BuddyModel import BuddyModel +from model.BuddyModel import BuddyModel from view.BuddyIcon import BuddyIcon from view.home.FriendView import FriendView From 131d4830f69c800bc57cd49fe5d98a8b98181946 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Tue, 10 Jul 2007 13:34:35 +0200 Subject: [PATCH 12/26] Remove battery.py --- services/console/interface/xo/Makefile.am | 1 - 1 file changed, 1 deletion(-) diff --git a/services/console/interface/xo/Makefile.am b/services/console/interface/xo/Makefile.am index be9be793..dbc96c40 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 From 42f0bcc48dfc39afe6ec8b890394902304be3778 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Tue, 10 Jul 2007 13:35:56 +0200 Subject: [PATCH 13/26] Fix NEWS --- NEWS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS b/NEWS index b2b39f02..1b6eef9e 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,5 @@ +* Fix broken import which was preventing startup. (marco) + Snapshot 757b2b8ce6 * #2031: Do not die if battery properties are unavailable. (marco) From 4685e2f8dde23d2bea1d0b503ec943244deea968 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Tue, 10 Jul 2007 13:38:36 +0200 Subject: [PATCH 14/26] Snapshot 42f0bcc48d. --- NEWS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS b/NEWS index 1b6eef9e..c2e554ac 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,5 @@ +Snapshot 42f0bcc48d + * Fix broken import which was preventing startup. (marco) Snapshot 757b2b8ce6 From e14288abb352cc4a611d03b8174b26102563237b Mon Sep 17 00:00:00 2001 From: Bert Freudenberg Date: Tue, 10 Jul 2007 13:59:34 +0200 Subject: [PATCH 15/26] do not include setup.py in .xo bundle --- sugar/activity/bundlebuilder.py | 1 - 1 file changed, 1 deletion(-) diff --git a/sugar/activity/bundlebuilder.py b/sugar/activity/bundlebuilder.py index 11fae53e..a5f0f1a2 100644 --- a/sugar/activity/bundlebuilder.py +++ b/sugar/activity/bundlebuilder.py @@ -50,7 +50,6 @@ 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') From d16a2fb44a949363d8b24f153dc701768306b32f Mon Sep 17 00:00:00 2001 From: Bert Freudenberg Date: Tue, 10 Jul 2007 14:43:56 +0200 Subject: [PATCH 16/26] bundlebuilder: include files only once if both default and in MANIFEST --- sugar/activity/bundlebuilder.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sugar/activity/bundlebuilder.py b/sugar/activity/bundlebuilder.py index a5f0f1a2..16e47f78 100644 --- a/sugar/activity/bundlebuilder.py +++ b/sugar/activity/bundlebuilder.py @@ -55,7 +55,7 @@ class _DefaultFileList(list): self.append('NEWS') class _ManifestFileList(list): - def __init__(self, manifest=None): + def __init__(self, manifest): self.append(manifest) f = open(manifest,'r') @@ -67,7 +67,8 @@ class _ManifestFileList(list): defaults = _DefaultFileList() for path in defaults: - self.append(path) + if not path in self: + self.append(path) def _extract_bundle(source_file, dest_dir): if not os.path.exists(dest_dir): From 071cc596c598ee7668b33b16a6485839ac25a60e Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Tue, 10 Jul 2007 15:18:08 +0200 Subject: [PATCH 17/26] Rename close to stop and save to keep --- NEWS | 3 +++ sugar/activity/activity.py | 24 ++++++++++++------------ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/NEWS b/NEWS index c2e554ac..0b510eda 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,6 @@ +* #2018 Rename Save to Keep. (marco) +* #2020 Rename Close to Stop. (marco) + Snapshot 42f0bcc48d * Fix broken import which was preventing startup. (marco) diff --git a/sugar/activity/activity.py b/sugar/activity/activity.py index 8a971997..87eb4fc5 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('window-close') + 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() From c3c0810def66526653608a0b7c381e4c902cadb5 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Tue, 10 Jul 2007 15:37:04 +0200 Subject: [PATCH 18/26] Implement tooltips for the zoom levels. --- po/POTFILES.in | 1 + shell/view/frame/Makefile.am | 4 ++-- shell/view/frame/frame.py | 2 +- shell/view/frame/{ZoomBox.py => zoombox.py} | 24 +++++++++++++++++++++ 4 files changed, 28 insertions(+), 3 deletions(-) rename shell/view/frame/{ZoomBox.py => zoombox.py} (75%) diff --git a/po/POTFILES.in b/po/POTFILES.in index 2b6d5a09..2c034d81 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/shell/view/frame/Makefile.am b/shell/view/frame/Makefile.am index ff2bff35..4a7083b2 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/frame.py b/shell/view/frame/frame.py index 5210f57a..2a94754c 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 similarity index 75% rename from shell/view/frame/ZoomBox.py rename to shell/view/frame/zoombox.py index 5bfb0e76..f4b8535d 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) From f14dc0985e0987ad523b18d588826e2eeea875f4 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Tue, 10 Jul 2007 15:37:46 +0200 Subject: [PATCH 19/26] Update news --- NEWS | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS b/NEWS index 0b510eda..5f28b408 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,4 @@ +* #2002 Tooltips for the zoom levels. (marco) * #2018 Rename Save to Keep. (marco) * #2020 Rename Close to Stop. (marco) From ac082511a247d4b475eaf942ad47429eec4d8751 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Tue, 10 Jul 2007 16:09:21 +0200 Subject: [PATCH 20/26] Use the new activity-stop icon. --- NEWS | 1 + sugar/activity/activity.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 5f28b408..88df96e7 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,4 @@ +* #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) diff --git a/sugar/activity/activity.py b/sugar/activity/activity.py index 87eb4fc5..32027035 100644 --- a/sugar/activity/activity.py +++ b/sugar/activity/activity.py @@ -83,7 +83,7 @@ class ActivityToolbar(gtk.Toolbar): self.insert(separator, -1) separator.show() - self.stop = ToolButton('window-close') + self.stop = ToolButton('activity-stop') self.stop.set_tooltip(_('Stop')) self.stop.connect('clicked', self._stop_clicked_cb) self.insert(self.stop, -1) From c1fa54c0c0ad04ed2f917f8a3ee34bc5b3e09cfd Mon Sep 17 00:00:00 2001 From: Bert Freudenberg Date: Tue, 10 Jul 2007 17:06:03 +0200 Subject: [PATCH 21/26] bundlebuilder: MANIFEST was still included twice ... fix for real now --- sugar/activity/bundlebuilder.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/sugar/activity/bundlebuilder.py b/sugar/activity/bundlebuilder.py index 16e47f78..8e8c49d6 100644 --- a/sugar/activity/bundlebuilder.py +++ b/sugar/activity/bundlebuilder.py @@ -54,22 +54,18 @@ class _DefaultFileList(list): if os.path.isfile(_get_source_path('NEWS')): self.append('NEWS') -class _ManifestFileList(list): +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: - if not path in self: - self.append(path) - def _extract_bundle(source_file, dest_dir): if not os.path.exists(dest_dir): os.mkdir(dest_dir) From 61a080a6938ff6098e1bca1aa4e48cab9f17de51 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Tue, 10 Jul 2007 19:17:02 +0200 Subject: [PATCH 22/26] Make developer console work again. --- NEWS | 1 + services/console/interface/xo/xo.py | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 88df96e7..32ed8dfe 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,4 @@ +* 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) diff --git a/services/console/interface/xo/xo.py b/services/console/interface/xo/xo.py index 63bba0b4..d2056058 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: @@ -52,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 From 1daa532625b2b553d98adeb195208b572e0eeab3 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Tue, 10 Jul 2007 19:35:18 +0200 Subject: [PATCH 23/26] Fix font size on the XO --- sugar/graphics/style.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/sugar/graphics/style.py b/sugar/graphics/style.py index fedbc9ec..1306caad 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) From b83a9ec27dd67927136aabea9fe1b114efecd658 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Tue, 10 Jul 2007 19:36:03 +0200 Subject: [PATCH 24/26] Update NEWS --- NEWS | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS b/NEWS index 32ed8dfe..46a89b5e 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,4 @@ +* 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) From f182201b3491365e7ebe19284fb92b07ed90ef7a Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Tue, 10 Jul 2007 19:37:37 +0200 Subject: [PATCH 25/26] Snapshot b83a9ec27d. --- NEWS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS b/NEWS index 46a89b5e..6673bf77 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,5 @@ +Snapshot b83a9ec27d + * Fix font size on the XO. (marco) * Make developer console work again. (marco) * #2020 Use the new activity-stop icon. (marco) From e4bce9271a2db597adb50fce182afe765ac97fa6 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Tue, 10 Jul 2007 20:35:51 +0200 Subject: [PATCH 26/26] #1984 Fix removing items from the clipboard. --- NEWS | 2 + services/clipboard/clipboardobject.py | 2 +- services/clipboard/clipboardservice.py | 64 +++++++++++++------------- shell/view/frame/clipboardbox.py | 17 +------ 4 files changed, 36 insertions(+), 49 deletions(-) diff --git a/NEWS b/NEWS index 6673bf77..beabf43e 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,5 @@ +* #1984 Fix removing items from the clipboard. (tomeu) + Snapshot b83a9ec27d * Fix font size on the XO. (marco) diff --git a/services/clipboard/clipboardobject.py b/services/clipboard/clipboardobject.py index 133e667d..c2ce339d 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 73552c4f..569ed6b4 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/shell/view/frame/clipboardbox.py b/shell/view/frame/clipboardbox.py index 7cb3698f..60c154ba 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,