[Sugar-devel] [sugar PATCH] sl#2818: Modifications in "favorite" status for activities in different workflows.
Ajay Garg
ajay at activitycentral.com
Fri Mar 2 14:57:07 EST 2012
==============================================================================
Following scenarios have been tested :
1. Addition of new activity, via Software-Update ==>
It should be shown as a favorite as default.
2. Addition of new activity, via Manual-Addition in "~/Activities"
directory ==>
It should be shown as a favorite as default.
3. Upgrade of an existing activity, via Software-Update ==>
The 'favorite-status' of the new-version activity, should be the same
as the 'favorite-status' of the old-version activity.
4. Removal of an activity, via Manual-Deletion of ".activity" directory
in "~/Activities" folder ==>
The activity should be removed, so should be its "favoriteness", if
at all.
5. An activity should maintain its "favoriteness" (or none of it) upon multiple reboots.
================================================================================
Another note ::
Before applying this patch, I saw that there were multiple entries for the same activity
(but different versions) in "~/.sugar/default/favorite_activities" (I however, did not
note down the exact workflow as to when it happened).
Anyway, AFTER the applying of this patch, there is should be a maximum of one entry per
activity in this file (and that happens, when the activity is designated as a favorite,
obviously !!)
=================================================================================
Signed-off-by: Ajay Garg <ajay at sugarlabs.org>
---
src/jarabe/controlpanel/gui.py | 1 +
src/jarabe/controlpanel/sectionview.py | 4 +
src/jarabe/desktop/activitieslist.py | 6 +-
src/jarabe/desktop/favoritesview.py | 16 ++-
src/jarabe/model/bundleregistry.py | 159 +++++++++++++++++++++++++++-----
5 files changed, 156 insertions(+), 30 deletions(-)
diff --git a/src/jarabe/controlpanel/gui.py b/src/jarabe/controlpanel/gui.py
index 0b70af6..9aeafe3 100644
--- a/src/jarabe/controlpanel/gui.py
+++ b/src/jarabe/controlpanel/gui.py
@@ -285,6 +285,7 @@ class ControlPanel(gtk.Window):
return options
def __cancel_clicked_cb(self, widget):
+ self._section_view.perform_cancel_actions()
self._section_view.undo()
self._options[self._current_option]['alerts'] = []
self._section_toolbar.accept_button.set_sensitive(True)
diff --git a/src/jarabe/controlpanel/sectionview.py b/src/jarabe/controlpanel/sectionview.py
index 836adf4..397784d 100644
--- a/src/jarabe/controlpanel/sectionview.py
+++ b/src/jarabe/controlpanel/sectionview.py
@@ -53,6 +53,10 @@ class SectionView(gtk.VBox):
"""Undo here the changes that have been made in this section."""
pass
+ def perform_cancel_actions(self):
+ """Perform additional actions, when the "Cancel" button is clicked."""
+ pass
+
def perform_accept_actions(self):
"""Perform additional actions, when the "Ok" button is clicked."""
pass
diff --git a/src/jarabe/desktop/activitieslist.py b/src/jarabe/desktop/activitieslist.py
index e34abd6..5f79090 100644
--- a/src/jarabe/desktop/activitieslist.py
+++ b/src/jarabe/desktop/activitieslist.py
@@ -135,7 +135,8 @@ class ActivitiesTreeView(gtk.TreeView):
registry = bundleregistry.get_registry()
registry.set_bundle_favorite(row[ListModel.COLUMN_BUNDLE_ID],
row[ListModel.COLUMN_VERSION],
- not row[ListModel.COLUMN_FAVORITE])
+ not row[ListModel.COLUMN_FAVORITE],
+ True)
def __icon_clicked_cb(self, cell, path):
row = self.get_model()[path]
@@ -447,7 +448,8 @@ class ActivityListPalette(ActivityPalette):
registry = bundleregistry.get_registry()
registry.set_bundle_favorite(self._bundle_id,
self._version,
- not self._favorite)
+ not self._favorite,
+ True)
def __activity_changed_cb(self, activity_registry, activity_info):
if activity_info.get_bundle_id() == self._bundle_id and \
diff --git a/src/jarabe/desktop/favoritesview.py b/src/jarabe/desktop/favoritesview.py
index e9c87ea..d91610b 100644
--- a/src/jarabe/desktop/favoritesview.py
+++ b/src/jarabe/desktop/favoritesview.py
@@ -142,11 +142,17 @@ class FavoritesView(hippo.Canvas):
def _add_activity(self, activity_info):
if activity_info.get_bundle_id() == 'org.laptop.JournalActivity':
return
- icon = ActivityIcon(activity_info)
- icon.props.size = style.STANDARD_ICON_SIZE
- icon.set_resume_mode(self._resume_mode)
- self._box.insert_sorted(icon, 0, self._layout.compare_activities)
- self._layout.append(icon)
+
+ # Add icon, if not already present (for the same combination of
+ # activity-id and activity-version)
+ icon = self._find_activity_icon(activity_info.get_bundle_id(),
+ activity_info.get_activity_version())
+ if icon is None:
+ icon = ActivityIcon(activity_info)
+ icon.props.size = style.STANDARD_ICON_SIZE
+ icon.set_resume_mode(self._resume_mode)
+ self._box.insert_sorted(icon, 0, self._layout.compare_activities)
+ self._layout.append(icon)
def __activity_added_cb(self, activity_registry, activity_info):
registry = bundleregistry.get_registry()
diff --git a/src/jarabe/model/bundleregistry.py b/src/jarabe/model/bundleregistry.py
index 26e719f..7594c01 100644
--- a/src/jarabe/model/bundleregistry.py
+++ b/src/jarabe/model/bundleregistry.py
@@ -59,14 +59,17 @@ class BundleRegistry(gobject.GObject):
self._bundles = []
# hold a reference to the monitors so they don't get disposed
self._gio_monitors = []
+ self._monitor = {}
+ self._handler_id = {}
+ self._allow_file_monitoring = True
user_path = env.get_user_activities_path()
for activity_dir in [user_path, config.activities_path]:
self._scan_directory(activity_dir)
directory = gio.File(activity_dir)
- monitor = directory.monitor_directory()
- monitor.connect('changed', self.__file_monitor_changed_cb)
- self._gio_monitors.append(monitor)
+ self._monitor = directory.monitor_directory()
+ self._handler_id = self._monitor.connect('changed', self.__file_monitor_changed_cb)
+ self._gio_monitors.append(self._monitor)
self._last_defaults_mtime = -1
self._favorite_bundles = {}
@@ -88,12 +91,31 @@ class BundleRegistry(gobject.GObject):
def __file_monitor_changed_cb(self, monitor, one_file, other_file,
event_type):
- if not one_file.get_path().endswith('.activity'):
- return
- if event_type == gio.FILE_MONITOR_EVENT_CREATED:
- self.add_bundle(one_file.get_path(), install_mime_type=True)
- elif event_type == gio.FILE_MONITOR_EVENT_DELETED:
- self.remove_bundle(one_file.get_path())
+ if self._allow_file_monitoring:
+ if not one_file.get_path().endswith('.activity'):
+ return
+ if event_type == gio.FILE_MONITOR_EVENT_CREATED:
+ if self.get_bundle_by_path(one_file.get_path()) is None:
+ self.add_bundle(one_file.get_path(),install_mime_type=True)
+ elif event_type == gio.FILE_MONITOR_EVENT_DELETED:
+ self.remove_bundle(one_file.get_path())
+
+ # I tried 2 hours, trying to make the following mechanisms for
+ # event-blocking, work ::
+ #
+ # a. disconnect
+ # b. handler_disconnect
+ # c. handler_block/handler_unblock
+ # d. handler_block_by_func/handler_unblock_by_func
+ #
+ # I could not.
+ #
+ # In the end, I had to revert to using the oldy-goldy boolean flag.
+ def disable_directory_monitoring(self):
+ self._allow_file_monitoring = False
+
+ def enable_directory_monitoring(self):
+ self._allow_file_monitoring = True
def _load_mime_defaults(self):
defaults = {}
@@ -180,6 +202,12 @@ class BundleRegistry(gobject.GObject):
return bundle
return None
+ def get_bundle_by_path(self, bundle_path):
+ for bundle in self._bundles:
+ if bundle.get_path() == bundle_path:
+ return bundle
+ return None
+
def __iter__(self):
return self._bundles.__iter__()
@@ -207,7 +235,13 @@ class BundleRegistry(gobject.GObject):
bundle_dirs.sort(lambda d1, d2: cmp(bundles[d1], bundles[d2]))
for folder in bundle_dirs:
try:
- self._add_bundle(folder)
+ # sl#2818
+ #
+ # Add meta-info, to indicate that this is a startup
+ # operation.
+ #
+ # See 'elif not startup' notes in 'self._add_bundle()'
+ self._add_bundle(folder, False, True)
except:
# pylint: disable=W0702
logging.exception('Error while processing installed activity'
@@ -216,15 +250,13 @@ class BundleRegistry(gobject.GObject):
def add_bundle(self, bundle_path, install_mime_type=False):
bundle = self._add_bundle(bundle_path, install_mime_type)
if bundle is not None:
- self._set_bundle_favorite(bundle.get_bundle_id(),
- bundle.get_activity_version(),
- True)
self.emit('bundle-added', bundle)
return True
else:
return False
- def _add_bundle(self, bundle_path, install_mime_type=False):
+ def _add_bundle(self, bundle_path, install_mime_type=False,
+ startup=False):
logging.debug('STARTUP: Adding bundle %r', bundle_path)
try:
bundle = ActivityBundle(bundle_path)
@@ -244,17 +276,92 @@ class BundleRegistry(gobject.GObject):
return None
else:
logging.debug('Upgrade %s', bundle_id)
+
+ # Query if the bundle is a favorite...
+ self._is_bundle_favorite = \
+ self.is_bundle_favorite(installed.get_bundle_id(),
+ installed.get_activity_version())
+
+ # ...and then, remove the old bundle (we have the new
+ # one !!)
self.remove_bundle(installed.get_path())
- self._bundles.append(bundle)
+ # Check, if this bundle-id is a favorite.
+ if self._is_bundle_favorite:
+
+ # Mark the (new) bundle with this bundle-id, as
+ # favorite.
+ self.set_bundle_favorite(bundle.get_bundle_id(),
+ bundle.get_activity_version(),
+ True,
+ True)
+
+ # This (new) bundle is new (!!), and is also a
+ # favorite. Add this to Favorites-View.
+ self.emit('bundle-added', bundle)
+
+ elif not startup:
+
+ # Ticket sl#2818
+
+ # Sub-case
+ # --------
+ # The bundle is newly added; so set it as favorite as
+ # default, so that it is promptly available to the
+ # user.
+ # Note that, any newly added bundles during system
+ # startup, are not new-bundles-as-such. They were
+ # new, when they were first added, and their
+ # favorite-status set at that time.
+ # However, from code point of view, control reaches
+ # here, only if the bundle IS newly added by
+ # user-discretion.
+ self.set_bundle_favorite(bundle.get_bundle_id(),
+ bundle.get_activity_version(),
+ True,
+ True)
+
+ # Emit 'bundle-added' (of course, this bundle is new !!),
+ # so that it is added in Favorites-View.
+ self.emit('bundle-added', bundle)
+
+
+ # In either case,
+ # a. Startup
+ # b. Upgrade of bundle
+ # c, Addition of new bundle, by user-discretion.
+ # add the bundle to bundles-list.
+ self.add_bundle_to_bundlelist(bundle)
return bundle
+ def add_bundle_to_bundlelist(self, bundle):
+ for bundle_in_list in self._bundles:
+ if bundle_in_list.get_path() == \
+ bundle.get_path():
+ return False
+
+ self._bundles.append(bundle)
+ return True
+
def remove_bundle(self, bundle_path):
for bundle in self._bundles:
if bundle.get_path() == bundle_path:
+
+ # This bundle is going.
+ # Remove it from bundles list...
self._bundles.remove(bundle)
+
+ # ... and remove it from Favorites-List...
+ self.set_bundle_favorite(bundle.get_bundle_id(),
+ bundle.get_activity_version(),
+ False,
+ True)
+
+ # ...and remove its trace from Favorites-View.
self.emit('bundle-removed', bundle)
+
return True
+
return False
def get_activities_for_type(self, mime_type):
@@ -287,14 +394,22 @@ class BundleRegistry(gobject.GObject):
if bundle.get_bundle_id() == bundle_id and \
bundle.get_activity_version() == version:
return bundle
- raise ValueError('No bundle %r with version %r exists.' % \
- (bundle_id, version))
+ return None
+
+ def set_bundle_favorite(self, bundle_id, version, favorite,
+ force=False):
+ # Return if file monitoring is not allowed, and the previous
+ # bundle is not a favorite.
+ if not force:
+ if not self._allow_file_monitoring:
+ if not self._is_bundle_favorite:
+ return
- def set_bundle_favorite(self, bundle_id, version, favorite):
changed = self._set_bundle_favorite(bundle_id, version, favorite)
if changed:
bundle = self._find_bundle(bundle_id, version)
- self.emit('bundle-changed', bundle)
+ if bundle is not None:
+ self.emit('bundle-changed', bundle)
def _set_bundle_favorite(self, bundle_id, version, favorite):
key = self._get_favorite_key(bundle_id, version)
@@ -331,7 +446,8 @@ class BundleRegistry(gobject.GObject):
self._write_favorites_file()
bundle = self._find_bundle(bundle_id, version)
- self.emit('bundle-changed', bundle)
+ if bundle is not None:
+ self.emit('bundle-changed', bundle)
def get_bundle_position(self, bundle_id, version):
"""Get the coordinates where the user wants the representation of this
@@ -420,9 +536,6 @@ class BundleRegistry(gobject.GObject):
bundle.uninstall(install_path, force, delete_profile)
- if not self.remove_bundle(install_path):
- raise RegistrationException
-
def upgrade(self, bundle):
act = self.get_bundle(bundle.get_bundle_id())
if act is None:
--
1.7.4.4
More information about the Sugar-devel
mailing list