diff options
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | src/jarabe/desktop/activitieslist.py | 244 | ||||
-rw-r--r-- | src/jarabe/desktop/favoritesview.py | 4 | ||||
-rw-r--r-- | src/jarabe/view/palettes.py | 4 |
4 files changed, 218 insertions, 36 deletions
diff --git a/configure.ac b/configure.ac index 2987b6c..103533d 100644 --- a/configure.ac +++ b/configure.ac @@ -10,6 +10,8 @@ AC_SUBST(SUCROSE_VERSION) AM_INIT_AUTOMAKE([1.9 foreign dist-bzip2 no-dist-gzip]) +AM_MAINTAINER_MODE + AM_PATH_PYTHON PKG_CHECK_MODULES(SHELL, pygtk-2.0 gtk+-2.0 gconf-2.0) diff --git a/src/jarabe/desktop/activitieslist.py b/src/jarabe/desktop/activitieslist.py index 5d6f900..903f05c 100644 --- a/src/jarabe/desktop/activitieslist.py +++ b/src/jarabe/desktop/activitieslist.py @@ -1,4 +1,5 @@ # Copyright (C) 2008 One Laptop Per Child +# Copyright (C) 2009 Tomeu Vizoso # # 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 @@ -15,15 +16,18 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import logging +from gettext import gettext as _ import gobject +import pango +import gconf import gtk import hippo -import gconf from sugar import util from sugar.graphics import style -from sugar.graphics.icon import CanvasIcon +from sugar.graphics.icon import CanvasIcon, CellRendererIcon +from sugar.graphics.palette import Palette from sugar.graphics.xocolor import XoColor from sugar.activity import activityfactory from sugar.activity.activityhandle import ActivityHandle @@ -32,8 +36,8 @@ from jarabe.model import bundleregistry from jarabe.view.palettes import ActivityPalette from jarabe.view import launcher -class ActivitiesList(gtk.VBox): - __gtype_name__ = 'SugarActivitiesList' +class ActivitiesTreeView(gtk.TreeView): + __gtype_name__ = 'SugarActivitiesTreeView' __gsignals__ = { 'erase-activated' : (gobject.SIGNAL_RUN_FIRST, @@ -41,27 +45,103 @@ class ActivitiesList(gtk.VBox): } def __init__(self): - logging.debug('STARTUP: Loading the activities list') - gobject.GObject.__init__(self) - scrolled_window = gtk.ScrolledWindow() - scrolled_window.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) - scrolled_window.set_shadow_type(gtk.SHADOW_NONE) - scrolled_window.connect('key-press-event', self.__key_press_event_cb) - self.pack_start(scrolled_window) - scrolled_window.show() + self.set_model(ActivitiesModel()) + + cell_favorite = CellRendererFavorite(self) + cell_favorite.connect('activate', self.__favorite_activate_cb) + + column = gtk.TreeViewColumn('') + column.pack_start(cell_favorite) + column.set_cell_data_func(cell_favorite, self.__favorite_set_data_cb) + self.append_column(column) + + cell_icon = CellRendererActivityIcon(self) + cell_icon.connect('erase-activated', self.__erase_activated_cb) + + column = gtk.TreeViewColumn('') + column.pack_start(cell_icon) + column.add_attribute(cell_icon, 'file-name', ActivitiesModel.COLUMN_ICON) + self.append_column(column) + + cell_text = gtk.CellRendererText() + cell_text.props.ellipsize = pango.ELLIPSIZE_MIDDLE + cell_text.props.ellipsize_set = True + cell_text.props.font_desc = style.FONT_BOLD.get_pango_desc() + + column = gtk.TreeViewColumn(_('Title')) + column.props.sizing = gtk.TREE_VIEW_COLUMN_GROW_ONLY + column.props.expand = True + column.set_sort_column_id(ActivitiesModel.COLUMN_TITLE) + column.pack_start(cell_text) + column.add_attribute(cell_text, 'text', ActivitiesModel.COLUMN_TITLE) + self.append_column(column) + + cell_text = gtk.CellRendererText() + cell_text.props.xalign = 1 + + column = gtk.TreeViewColumn(_('Version')) + column.set_alignment(1) + column.props.sizing = gtk.TREE_VIEW_COLUMN_GROW_ONLY + column.props.resizable = True + column.props.reorderable = True + column.props.expand = True + column.set_sort_column_id(ActivitiesModel.COLUMN_VERSION) + column.pack_start(cell_text) + column.add_attribute(cell_text, 'text', ActivitiesModel.COLUMN_VERSION_TEXT) + self.append_column(column) + + cell_text = gtk.CellRendererText() + cell_text.props.xalign = 1 + + column = gtk.TreeViewColumn(_('Date')) + column.set_alignment(1) + column.props.sizing = gtk.TREE_VIEW_COLUMN_GROW_ONLY + column.props.resizable = True + column.props.reorderable = True + column.props.expand = True + column.set_sort_column_id(ActivitiesModel.COLUMN_DATE) + column.pack_start(cell_text) + column.add_attribute(cell_text, 'text', ActivitiesModel.COLUMN_DATE_TEXT) + self.append_column(column) + + self.set_search_column(ActivitiesModel.COLUMN_TITLE) + + def __erase_activated_cb(self, cell_renderer, bundle_id): + self.emit('erase-activated', bundle_id) - canvas = hippo.Canvas() - scrolled_window.add_with_viewport(canvas) - scrolled_window.child.set_shadow_type(gtk.SHADOW_NONE) - canvas.show() + def __favorite_set_data_cb(self, column, cell, model, tree_iter): + favorite = model[tree_iter][ActivitiesModel.COLUMN_FAVORITE] + if favorite: + client = gconf.client_get_default() + color = XoColor(client.get_string('/desktop/sugar/user/color')) + cell.props.xo_color = color + else: + cell.props.stroke_color = style.COLOR_BUTTON_GREY.get_svg() + cell.props.fill_color = style.COLOR_WHITE.get_svg() - self._alert = None - self._query = '' - self._box = hippo.CanvasBox() - self._box.props.background_color = style.COLOR_WHITE.get_int() - canvas.set_root(self._box) + def __favorite_activate_cb(self, cell, path): + row = self.get_model()[path] + registry = bundleregistry.get_registry() + registry.set_bundle_favorite(row[ActivitiesModel.COLUMN_BUNDLE_ID], + row[ActivitiesModel.COLUMN_VERSION], + not row[ActivitiesModel.COLUMN_FAVORITE]) + +class ActivitiesModel(gtk.ListStore): + __gtype_name__ = 'SugarActivitiesModel' + + COLUMN_BUNDLE_ID = 0 + COLUMN_FAVORITE = 1 + COLUMN_ICON = 2 + COLUMN_TITLE = 3 + COLUMN_VERSION = 4 + COLUMN_VERSION_TEXT = 5 + COLUMN_DATE = 6 + COLUMN_DATE_TEXT = 7 + + def __init__(self): + gtk.ListStore.__init__(self, str, bool, str, str, int, str, int, str) gobject.idle_add(self.__connect_to_bundle_registry_cb) @@ -70,32 +150,129 @@ class ActivitiesList(gtk.VBox): for info in registry: self._add_activity(info) registry.connect('bundle-added', self.__activity_added_cb) + registry.connect('bundle-changed', self.__activity_changed_cb) registry.connect('bundle-removed', self.__activity_removed_cb) def __activity_added_cb(self, activity_registry, activity_info): self._add_activity(activity_info) - def __activity_removed_cb(self, activity_registry, activity_info): - for entry in self._box.get_children(): - if entry.get_bundle_id() == activity_info.get_bundle_id() and \ - entry.get_version() == activity_info.get_activity_version(): - self._box.remove(entry) + def __activity_changed_cb(self, activity_registry, activity_info): + bundle_id = activity_info.get_bundle_id() + version = activity_info.get_activity_version() + favorite = activity_registry.is_bundle_favorite(bundle_id, version) + for row in self: + if row[ActivitiesModel.COLUMN_BUNDLE_ID] == bundle_id and \ + row[ActivitiesModel.COLUMN_VERSION] == version: + row[ActivitiesModel.COLUMN_FAVORITE] = favorite + row[ActivitiesModel.COLUMN_TITLE] = activity_info.get_name() return - def _compare_activities(self, entry_a, entry_b): - return entry_b.get_installation_time() - entry_a.get_installation_time() + def __activity_removed_cb(self, activity_registry, activity_info): + bundle_id = activity_info.get_bundle_id() + version = activity_info.get_activity_version() + favorite = activity_registry.is_bundle_favorite(bundle_id, version) + for row in self: + if row[ActivitiesModel.COLUMN_BUNDLE_ID] == bundle_id and \ + row[ActivitiesModel.COLUMN_VERSION] == version: + self.remove(row.iter) + return def _add_activity(self, activity_info): if activity_info.get_bundle_id() == 'org.laptop.JournalActivity': return - entry = ActivityEntry(activity_info) - entry.icon.connect('erase-activated', self.__erase_activated_cb) - self._box.insert_sorted(entry, 0, self._compare_activities) + + timestamp = activity_info.get_installation_time() + version = activity_info.get_activity_version() + + registry = bundleregistry.get_registry() + favorite = registry.is_bundle_favorite(activity_info.get_bundle_id(), + version) + + self.append([activity_info.get_bundle_id(), + favorite, + activity_info.get_icon(), + activity_info.get_name(), + version, + _('Version %s') % version, + timestamp, + util.timestamp_to_elapsed_string(timestamp)]) + + """ entry.set_visible(entry.matches(self._query)) + """ + +class CellRendererFavorite(CellRendererIcon): + __gtype_name__ = 'SugarCellRendererFavorite' + + def __init__(self, tree_view): + CellRendererIcon.__init__(self, tree_view) + + self.props.width = style.GRID_CELL_SIZE + self.props.height = style.GRID_CELL_SIZE + self.props.size = style.SMALL_ICON_SIZE + self.props.icon_name = 'emblem-favorite' + self.props.mode = gtk.CELL_RENDERER_MODE_ACTIVATABLE + +class CellRendererActivityIcon(CellRendererIcon): + __gtype_name__ = 'SugarCellRendererActivityIcon' + + __gsignals__ = { + 'erase-activated' : (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, ([str])) + } + + def __init__(self, tree_view): + CellRendererIcon.__init__(self, tree_view) + + self.props.width = style.GRID_CELL_SIZE + self.props.height = style.GRID_CELL_SIZE + self.props.stroke_color = style.COLOR_BUTTON_GREY.get_svg() + self.props.fill_color = style.COLOR_TRANSPARENT.get_svg() + self.props.size = style.STANDARD_ICON_SIZE + + self._tree_view = tree_view + + def create_palette(self): + model = self._tree_view.get_model() + row = model[self.props.palette_invoker.path] + bundle_id = row[ActivitiesModel.COLUMN_BUNDLE_ID] + + registry = bundleregistry.get_registry() + palette = ActivityPalette(registry.get_bundle(bundle_id)) + palette.connect('erase-activated', self.__erase_activated_cb) + return palette - def __erase_activated_cb(self, activity_icon, bundle_id): + def __erase_activated_cb(self, palette, bundle_id): self.emit('erase-activated', bundle_id) +class ActivitiesList(gtk.VBox): + __gtype_name__ = 'SugarActivitiesList' + + __gsignals__ = { + 'erase-activated' : (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, ([str])) + } + + def __init__(self): + logging.debug('STARTUP: Loading the activities list') + + gobject.GObject.__init__(self) + + scrolled_window = gtk.ScrolledWindow() + scrolled_window.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) + scrolled_window.set_shadow_type(gtk.SHADOW_NONE) + scrolled_window.connect('key-press-event', self.__key_press_event_cb) + self.pack_start(scrolled_window) + scrolled_window.show() + + self._tree_view = ActivitiesTreeView() + self._tree_view.connect('erase-activated', self.__erase_activated_cb) + scrolled_window.add(self._tree_view) + self._tree_view.show() + + self._alert = None + self._query = '' + def set_filter(self, query): self._query = query for entry in self._box.get_children(): @@ -130,6 +307,9 @@ class ActivitiesList(gtk.VBox): self.remove(self._alert) self._alert = None + def __erase_activated_cb(self, tree_view, bundle_id): + self.emit('erase-activated', bundle_id) + class ActivityIcon(CanvasIcon): __gtype_name__ = 'SugarListActivityIcon' diff --git a/src/jarabe/desktop/favoritesview.py b/src/jarabe/desktop/favoritesview.py index 03d9f16..411b579 100644 --- a/src/jarabe/desktop/favoritesview.py +++ b/src/jarabe/desktop/favoritesview.py @@ -472,8 +472,8 @@ class ActivityIcon(CanvasIcon): palette.connect('erase-activated', self.__erase_activated_cb) return palette - def __erase_activated_cb(self, palette): - self.emit('erase-activated', self._activity_info.get_bundle_id()) + def __erase_activated_cb(self, palette, bundle_id): + self.emit('erase-activated', bundle_id) def __palette_activate_cb(self, palette): self._activate() diff --git a/src/jarabe/view/palettes.py b/src/jarabe/view/palettes.py index b222fc7..9d45eb5 100644 --- a/src/jarabe/view/palettes.py +++ b/src/jarabe/view/palettes.py @@ -109,7 +109,7 @@ class ActivityPalette(Palette): __gsignals__ = { 'erase-activated' : (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([])) + gobject.TYPE_NONE, ([str])) } def __init__(self, activity_info): @@ -210,7 +210,7 @@ class ActivityPalette(Palette): self._update_favorite_item() def __erase_activate_cb(self, menu_item): - self.emit('erase-activated') + self.emit('erase-activated', self._bundle_id) class JournalPalette(BasePalette): def __init__(self, home_activity): |