From 5ba227ff85d1c4ccd415c8aa4e1e2b0c743f346f Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Sun, 17 Aug 2008 18:47:00 +0200 Subject: [PATCH 1/9] #7533 ToolButton should accept activation via accelerators regardless of its state --- src/sugar/graphics/toolbutton.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/sugar/graphics/toolbutton.py b/src/sugar/graphics/toolbutton.py index bf392c86..715e7a92 100644 --- a/src/sugar/graphics/toolbutton.py +++ b/src/sugar/graphics/toolbutton.py @@ -65,6 +65,12 @@ class ToolButton(gtk.ToolButton): self.set_icon(icon_name) self.connect('clicked', self.__button_clicked_cb) + self.get_child().connect('can-activate-accel', + self.__button_can_activate_accel_cb) + + def __button_can_activate_accel_cb(self, button, signal_id): + # Accept activation via accelerators regardless of this widget's state + return True def set_tooltip(self, tooltip): """ Set a simple palette with just a single label. From 1bd1b6c81e6a8352f5552fb70da40d21768485be Mon Sep 17 00:00:00 2001 From: "C. Scott Ananian" Date: Thu, 14 Aug 2008 02:49:45 -0400 Subject: [PATCH 2/9] Trac #7733: fix severe performance regression when creating ActivityBundle. --- src/sugar/bundle/activitybundle.py | 8 +++---- src/sugar/bundle/bundle.py | 37 +++++++++++++++--------------- src/sugar/bundle/contentbundle.py | 4 ++-- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/sugar/bundle/activitybundle.py b/src/sugar/bundle/activitybundle.py index 5f29a698..be997cc5 100644 --- a/src/sugar/bundle/activitybundle.py +++ b/src/sugar/bundle/activitybundle.py @@ -205,13 +205,13 @@ class ActivityBundle(Bundle): def get_locale_path(self): """Get the locale path inside the (installed) activity bundle.""" - if not self._unpacked: + if self._zip_file is not None: raise NotInstalledException return os.path.join(self._path, 'locale') def get_icons_path(self): """Get the icons path inside the (installed) activity bundle.""" - if not self._unpacked: + if self._zip_file is not None: raise NotInstalledException return os.path.join(self._path, 'icons') @@ -237,7 +237,7 @@ class ActivityBundle(Bundle): def get_icon(self): """Get the activity icon name""" icon_path = os.path.join('activity', self._icon + '.svg') - if self._unpacked: + if self._zip_file is None: return os.path.join(self._path, icon_path) else: icon_data = self.get_file(icon_path).read() @@ -365,7 +365,7 @@ class ActivityBundle(Bundle): raise RegistrationException def uninstall(self, force=False): - if self._unpacked: + if self._zip_file is None: install_path = self._path else: if not self.is_installed(): diff --git a/src/sugar/bundle/bundle.py b/src/sugar/bundle/bundle.py index 3b12932a..0319b9ec 100644 --- a/src/sugar/bundle/bundle.py +++ b/src/sugar/bundle/bundle.py @@ -19,6 +19,7 @@ import os import logging +import shutil import StringIO import zipfile @@ -59,9 +60,9 @@ class Bundle: self._zip_root_dir = None if os.path.isdir(self._path): - self._unpacked = True + self._zip_file = None else: - self._unpacked = False + self._zip_file = zipfile.ZipFile(self._path) self._check_zip_bundle() # manifest = self._get_file(self._infodir + '/contents') @@ -72,9 +73,12 @@ class Bundle: # if signature is None: # raise MalformedBundleException('No signature file') + def __del__(self): + if self._zip_file is not None: + self._zip_file.close() + def _check_zip_bundle(self): - zip_file = zipfile.ZipFile(self._path) - file_names = zip_file.namelist() + file_names = self._zip_file.namelist() if len(file_names) == 0: raise MalformedBundleException('Empty zip file') @@ -99,48 +103,42 @@ class Bundle: def get_file(self, filename): f = None - if self._unpacked: + if self._zip_file is None: path = os.path.join(self._path, filename) try: f = open(path,"rb") except IOError: return None else: - zip_file = zipfile.ZipFile(self._path) path = os.path.join(self._zip_root_dir, filename) try: - data = zip_file.read(path) + data = self._zip_file.read(path) f = StringIO.StringIO(data) except KeyError: logging.debug('%s not found.' % filename) - zip_file.close() return f def is_file(self, filename): - if self._unpacked: + if self._zip_file is None: path = os.path.join(self._path, filename) return os.path.isfile(path) else: - zip_file = zipfile.ZipFile(self._path) path = os.path.join(self._zip_root_dir, filename) try: - zip_file.getinfo(path) + self._zip_file.getinfo(path) except KeyError: return False - finally: - zip_file.close() return True def is_dir(self, filename): - if self._unpacked: + if self._zip_file is None: path = os.path.join(self._path, filename) return os.path.isdir(path) else: - zip_file = zipfile.ZipFile(self._path) path = os.path.join(self._zip_root_dir, filename, "") - for f in zip_file.namelist(): + for f in self._zip_file.namelist(): if f.startswith(path): return True return False @@ -150,7 +148,7 @@ class Bundle: return self._path def _unzip(self, install_dir): - if self._unpacked: + if self._zip_file is None: raise AlreadyInstalledException if not os.path.isdir(install_dir): @@ -163,10 +161,13 @@ class Bundle: # FIXME: use manifest if os.spawnlp(os.P_WAIT, 'unzip', 'unzip', '-o', self._path, '-x', 'mimetype', '-d', install_dir): + # clean up install dir after failure + shutil.rmtree(install_dir, ignore_errors=True) + # indicate failure. raise ZipExtractException def _zip(self, bundle_path): - if not self._unpacked: + if self._zip_file is not None: raise NotInstalledException raise NotImplementedError diff --git a/src/sugar/bundle/contentbundle.py b/src/sugar/bundle/contentbundle.py index f99c13a1..389fd709 100644 --- a/src/sugar/bundle/contentbundle.py +++ b/src/sugar/bundle/contentbundle.py @@ -195,7 +195,7 @@ class ContentBundle(Bundle): return "file://" + urllib.pathname2url(self.get_start_path()) def is_installed(self): - if self._unpacked: + if self._zip_file is None: return True elif os.path.isdir(self.get_root_dir()): return True @@ -207,7 +207,7 @@ class ContentBundle(Bundle): self._run_indexer() def uninstall(self): - if self._unpacked: + if self._zip_file is None: if not self.is_installed(): raise NotInstalledException install_dir = self._path From 2160a80c976baf5dfe616ba1acbfdb77d0834de4 Mon Sep 17 00:00:00 2001 From: Pootle Translation Date: Thu, 21 Aug 2008 13:00:49 -0400 Subject: [PATCH 3/9] Commit from One Laptop Per Child: Translation System by user korakurider. 28 of 28 messages translated (0 fuzzy). --- po/ja.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/po/ja.po b/po/ja.po index 3b902e95..f929ca9d 100644 --- a/po/ja.po +++ b/po/ja.po @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2008-06-24 00:07+0530\n" -"PO-Revision-Date: 2008-07-27 09:55-0400\n" +"PO-Revision-Date: 2008-08-21 12:59-0400\n" "Last-Translator: korakurider \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -29,7 +29,7 @@ msgstr "私のお隣さん" #: ../src/sugar/activity/activity.py:130 msgid "Keep" -msgstr "残しておく" +msgstr "ジャーナルに保存" #: ../src/sugar/activity/activity.py:136 msgid "Stop" @@ -106,7 +106,7 @@ msgstr "ちょっと前" #: ../src/sugar/util.py:189 #, python-format msgid "%s ago" -msgstr "だけ前" +msgstr "%s前" #. TRANS: Relative dates (eg. 1 month and 5 days). #: ../src/sugar/util.py:202 From 1f6dae2360d290a35783dd20fde58ed6ce86488c Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Fri, 22 Aug 2008 14:33:38 +0200 Subject: [PATCH 4/9] #7959 cache translations in util.py (rlucchese) --- src/sugar/util.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/sugar/util.py b/src/sugar/util.py index 955f4c81..c365dce9 100644 --- a/src/sugar/util.py +++ b/src/sugar/util.py @@ -16,6 +16,7 @@ # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. +import os import time import sha import random @@ -23,7 +24,6 @@ import binascii import gettext _ = lambda msg: gettext.dgettext('sugar-toolkit', msg) -_ngettext = lambda m1, m2, n: gettext.dngettext('sugar-toolkit', m1, m2, n) def printable_hash(in_hash): """Convert binary hash data into printable characters.""" @@ -217,6 +217,9 @@ del ngettext # End of plurals hack +# gettext perfs hack (#7959) +_i18n_timestamps_cache = LRU(60) + def timestamp_to_elapsed_string(timestamp, max_levels=2): levels = 0 time_period = '' @@ -229,8 +232,17 @@ def timestamp_to_elapsed_string(timestamp, max_levels=2): if levels > 0: time_period += COMMA - time_period += _ngettext(name_singular, name_plural, - elapsed_units) % elapsed_units + key = ''.join((os.environ['LANG'], name_singular, + str(elapsed_units))) + if key in _i18n_timestamps_cache: + time_period += _i18n_timestamps_cache[key] + else: + translation = gettext.dngettext('sugar-toolkit', + name_singular, + name_plural, + elapsed_units) % elapsed_units + _i18n_timestamps_cache[key] = translation + time_period += translation elapsed_seconds -= elapsed_units * factor From 3bb9f47461f903f515cc279a126f61c4b5e45ab5 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Fri, 22 Aug 2008 14:50:32 +0200 Subject: [PATCH 5/9] #8000 Only repaint the area needed (rlucchese) --- src/sugar/graphics/icon.py | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/sugar/graphics/icon.py b/src/sugar/graphics/icon.py index 0dc82bba..d2aae087 100644 --- a/src/sugar/graphics/icon.py +++ b/src/sugar/graphics/icon.py @@ -417,10 +417,27 @@ class CanvasIcon(hippo.CanvasBox, hippo.CanvasItem): if self._palette_invoker is not None: self._palette_invoker.detach() + def _repaint_for_icon_change(self): + box_width, box_height = self.get_allocation() + + if self._buffer.width is None: + icon_width = 0 + else: + icon_width = self._buffer.width + + if self._buffer.height is None: + icon_height = 0 + else: + icon_height = self._buffer.height + + x = (box_width - icon_width) / 2 + y = (box_height - icon_height) / 2 + self.emit_paint_needed(x, y, icon_width, icon_height) + def set_file_name(self, value): if self._buffer.file_name != value: self._buffer.file_name = value - self.emit_paint_needed(0, 0, -1, -1) + self._repaint_for_icon_change() def get_file_name(self): return self._buffer.file_name @@ -431,7 +448,7 @@ class CanvasIcon(hippo.CanvasBox, hippo.CanvasItem): def set_icon_name(self, value): if self._buffer.icon_name != value: self._buffer.icon_name = value - self.emit_paint_needed(0, 0, -1, -1) + self._repaint_for_icon_change() def get_icon_name(self): return self._buffer.icon_name @@ -442,7 +459,7 @@ class CanvasIcon(hippo.CanvasBox, hippo.CanvasItem): def set_xo_color(self, value): if self._buffer.xo_color != value: self._buffer.xo_color = value - self.emit_paint_needed(0, 0, -1, -1) + self._repaint_for_icon_change() xo_color = gobject.property( type=object, getter=None, setter=set_xo_color) @@ -450,7 +467,7 @@ class CanvasIcon(hippo.CanvasBox, hippo.CanvasItem): def set_fill_color(self, value): if self._buffer.fill_color != value: self._buffer.fill_color = value - self.emit_paint_needed(0, 0, -1, -1) + self._repaint_for_icon_change() def get_fill_color(self): return self._buffer.fill_color @@ -461,7 +478,7 @@ class CanvasIcon(hippo.CanvasBox, hippo.CanvasItem): def set_stroke_color(self, value): if self._buffer.stroke_color != value: self._buffer.stroke_color = value - self.emit_paint_needed(0, 0, -1, -1) + self._repaint_for_icon_change() def get_stroke_color(self): return self._buffer.stroke_color @@ -506,7 +523,7 @@ class CanvasIcon(hippo.CanvasBox, hippo.CanvasItem): def set_badge_name(self, value): if self._buffer.badge_name != value: self._buffer.badge_name = value - self.emit_paint_needed(0, 0, -1, -1) + self._repaint_for_icon_change() def get_badge_name(self): return self._buffer.badge_name From f55e531f422c2960c4f27933a8e68dfa1112694f Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Fri, 22 Aug 2008 15:03:01 +0200 Subject: [PATCH 6/9] Warn about files missing from the MANIFEST. --- src/sugar/activity/bundlebuilder.py | 49 +++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/src/sugar/activity/bundlebuilder.py b/src/sugar/activity/bundlebuilder.py index b8f87a79..0ee78c9f 100644 --- a/src/sugar/activity/bundlebuilder.py +++ b/src/sugar/activity/bundlebuilder.py @@ -118,6 +118,12 @@ class Packager(object): if not os.path.exists(self.config.dist_dir): os.mkdir(self.config.dist_dir) + def _list_files(self): + ignore_dirs = ['dist', '.git'] + ignore_files = ['.gitignore', 'MANIFEST', '*.pyc', '*~', '*.bak'] + + return list_files(self.config.source_dir, ignore_dirs, ignore_files) + class BuildPackager(Packager): def get_files(self): files = self.config.bundle.get_files() @@ -128,20 +134,22 @@ class BuildPackager(Packager): files = self.config.bundle.get_files() return files - - def _list_useful_files(self): - ignore_dirs = ['dist', '.git'] - ignore_files = ['.gitignore', 'MANIFEST', '*.pyc', '*~', '*.bak'] - - return list_files(self.config.source_dir, ignore_dirs, ignore_files) + + def _check_manifest(self): + missing_files = [] + + allfiles = self._list_files() + for path in allfiles: + if path not in self.config.bundle.manifest: + missing_files.append(path) + + return missing_files def fix_manifest(self): manifest = self.config.bundle.manifest - allfiles = self._list_useful_files() - for path in allfiles: - if path not in manifest: - manifest.append(path) + for path in self._check_manifest(): + manifest.append(path) f = open(os.path.join(self.config.source_dir, "MANIFEST"), "wb") for line in manifest: @@ -157,15 +165,22 @@ class XOPackager(BuildPackager): bundle_zip = zipfile.ZipFile(self.package_path, 'w', zipfile.ZIP_DEFLATED) + missing_files = self._check_manifest() + if missing_files: + logging.warn('These files are not included in the manifest ' \ + 'and will not be present in the bundle:\n\n' + + '\n'.join(missing_files) + + '\n\nUse fix_manifest if you want to add them.') + for f in self.get_files(): bundle_zip.write(os.path.join(self.config.source_dir, f), os.path.join(self.config.bundle_root_dir, f)) bundle_zip.close() -class SourcePackager(BuildPackager): +class SourcePackager(Packager): def __init__(self, config): - BuildPackager.__init__(self, config) + Packager.__init__(self, config) self.package_path = os.path.join(self.config.dist_dir, self.config.tar_name) @@ -174,7 +189,7 @@ class SourcePackager(BuildPackager): cwd=self.config.source_dir) if git_ls.wait(): # Fall back to filtered list - return self._list_useful_files() + return self._list_files() return [path.strip() for path in git_ls.stdout.readlines()] @@ -191,6 +206,7 @@ setup.py build - build generated files \n\ setup.py dev - setup for development \n\ setup.py dist_xo - create a xo bundle package \n\ setup.py dist_source - create a tar source package \n\ +setup.py fix_manifest - add missing files to the manifest \n\ setup.py install [dirname] - install the bundle \n\ setup.py uninstall [dirname] - uninstall the bundle \n\ setup.py genpot - generate the gettext pot file \n\ @@ -218,6 +234,13 @@ def cmd_dist_xo(config, options, args): packager = XOPackager(config) packager.package() +def cmd_fix_manifest(config, options, args): + builder = Builder(config) + builder.build() + + packager = XOPackager(config) + packager.fix_manifest() + def cmd_dist(config, options, args): logging.warn("dist deprecated, use dist_xo.") cmd_dist_xo(config, options, args) From f29b67b0325526974146916567e56d61403cba31 Mon Sep 17 00:00:00 2001 From: Simon Schampijer Date: Fri, 22 Aug 2008 15:16:30 +0200 Subject: [PATCH 7/9] Add update functionality to Config in bundlebuilder #7270 (marco) This is needed by the release command to update the bundle number --- src/sugar/activity/bundlebuilder.py | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/sugar/activity/bundlebuilder.py b/src/sugar/activity/bundlebuilder.py index 0ee78c9f..75d6d89c 100644 --- a/src/sugar/activity/bundlebuilder.py +++ b/src/sugar/activity/bundlebuilder.py @@ -51,7 +51,21 @@ def list_files(base_dir, ignore_dirs=None, ignore_files=None): class Config(object): def __init__(self, source_dir=None, dist_dir = None, dist_name = None): self.source_dir = source_dir or os.getcwd() - + self.dist_dir = dist_dir or os.path.join(self.source_dir, 'dist') + self.dist_name = dist_name + self.bundle = None + self.version = None + self.activity_name = None + self.bundle_id = None + self.bundle_name = None + self.bundle_root_dir = None + self.tar_root_dir = None + self.xo_name = None + self.tar_name = None + + self.update() + + def update(self): self.bundle = bundle = ActivityBundle(self.source_dir) self.version = bundle.get_activity_version() self.activity_name = bundle.get_name() @@ -59,14 +73,9 @@ class Config(object): self.bundle_name = reduce(lambda x, y:x+y, self.activity_name.split()) self.bundle_root_dir = self.bundle_name + '.activity' self.tar_root_dir = '%s-%d' % (self.bundle_name, self.version) - - if dist_dir: - self.dist_dir = dist_dir - else: - self.dist_dir = os.path.join(self.source_dir, 'dist') - if dist_name: - self.xo_name = self.tar_name = dist_name + if self.dist_name: + self.xo_name = self.tar_name = self.dist_name else: self.xo_name = '%s-%d.xo' % (self.bundle_name, self.version) self.tar_name = '%s-%d.tar.bz2' % (self.bundle_name, self.version) @@ -332,6 +341,8 @@ def cmd_release(config, options, args): f.write(info) f.close() + config.update() + news_path = os.path.join(config.source_dir, 'NEWS') if os.environ.has_key('SUGAR_NEWS'): From 7090e73c09473fd63ecf3a252354af6e0f5df11e Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Fri, 22 Aug 2008 19:07:34 +0200 Subject: [PATCH 8/9] Revert "#8000 Only repaint the area needed (rlucchese)" The bounds calculation won't be always correct. This reverts commit 3bb9f47461f903f515cc279a126f61c4b5e45ab5. --- src/sugar/graphics/icon.py | 29 ++++++----------------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/src/sugar/graphics/icon.py b/src/sugar/graphics/icon.py index d2aae087..0dc82bba 100644 --- a/src/sugar/graphics/icon.py +++ b/src/sugar/graphics/icon.py @@ -417,27 +417,10 @@ class CanvasIcon(hippo.CanvasBox, hippo.CanvasItem): if self._palette_invoker is not None: self._palette_invoker.detach() - def _repaint_for_icon_change(self): - box_width, box_height = self.get_allocation() - - if self._buffer.width is None: - icon_width = 0 - else: - icon_width = self._buffer.width - - if self._buffer.height is None: - icon_height = 0 - else: - icon_height = self._buffer.height - - x = (box_width - icon_width) / 2 - y = (box_height - icon_height) / 2 - self.emit_paint_needed(x, y, icon_width, icon_height) - def set_file_name(self, value): if self._buffer.file_name != value: self._buffer.file_name = value - self._repaint_for_icon_change() + self.emit_paint_needed(0, 0, -1, -1) def get_file_name(self): return self._buffer.file_name @@ -448,7 +431,7 @@ class CanvasIcon(hippo.CanvasBox, hippo.CanvasItem): def set_icon_name(self, value): if self._buffer.icon_name != value: self._buffer.icon_name = value - self._repaint_for_icon_change() + self.emit_paint_needed(0, 0, -1, -1) def get_icon_name(self): return self._buffer.icon_name @@ -459,7 +442,7 @@ class CanvasIcon(hippo.CanvasBox, hippo.CanvasItem): def set_xo_color(self, value): if self._buffer.xo_color != value: self._buffer.xo_color = value - self._repaint_for_icon_change() + self.emit_paint_needed(0, 0, -1, -1) xo_color = gobject.property( type=object, getter=None, setter=set_xo_color) @@ -467,7 +450,7 @@ class CanvasIcon(hippo.CanvasBox, hippo.CanvasItem): def set_fill_color(self, value): if self._buffer.fill_color != value: self._buffer.fill_color = value - self._repaint_for_icon_change() + self.emit_paint_needed(0, 0, -1, -1) def get_fill_color(self): return self._buffer.fill_color @@ -478,7 +461,7 @@ class CanvasIcon(hippo.CanvasBox, hippo.CanvasItem): def set_stroke_color(self, value): if self._buffer.stroke_color != value: self._buffer.stroke_color = value - self._repaint_for_icon_change() + self.emit_paint_needed(0, 0, -1, -1) def get_stroke_color(self): return self._buffer.stroke_color @@ -523,7 +506,7 @@ class CanvasIcon(hippo.CanvasBox, hippo.CanvasItem): def set_badge_name(self, value): if self._buffer.badge_name != value: self._buffer.badge_name = value - self._repaint_for_icon_change() + self.emit_paint_needed(0, 0, -1, -1) def get_badge_name(self): return self._buffer.badge_name From c3873bfdcb78bf5e50568b591b3d9deec4d3d9db Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Fri, 22 Aug 2008 20:48:59 +0200 Subject: [PATCH 9/9] Bump to 0.82.1, marco forgot to commit the configure change when releasing --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 1f2c8972..32aedff6 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([sugar-toolkit],[0.82.0],[],[sugar-toolkit]) +AC_INIT([sugar-toolkit],[0.82.1],[],[sugar-toolkit]) AC_PREREQ([2.59])