From 860a0fd8d76f049dd0a13f6ac3dea6b8bb7416a0 Mon Sep 17 00:00:00 2001 From: Ajay Garg Date: Fri, 02 Mar 2012 13:52:18 +0000 Subject: sl#2818, au#589: Modifications in "favorite" status for activities in different workflows. ============================================================================== 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 --- 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: -- cgit v0.9.1