diff options
author | Marco Pesenti Gritti <mpgritti@gmail.com> | 2008-10-05 11:49:01 (GMT) |
---|---|---|
committer | Marco Pesenti Gritti <mpgritti@gmail.com> | 2008-10-05 11:49:01 (GMT) |
commit | e53b1dc03a5bc0bf3a681789e3dc56687bb4a083 (patch) | |
tree | e1668cbbc60115c2ca502957e59c9675e3c3a3f9 /src | |
parent | 702cb0a538d0564e00bb481125c9bd734b243283 (diff) |
Merge home model and shell model.
Diffstat (limited to 'src')
-rw-r--r-- | src/jarabe/desktop/favoritesview.py | 8 | ||||
-rw-r--r-- | src/jarabe/desktop/homewindow.py | 6 | ||||
-rw-r--r-- | src/jarabe/frame/activitiestray.py | 14 | ||||
-rw-r--r-- | src/jarabe/frame/friendstray.py | 11 | ||||
-rw-r--r-- | src/jarabe/frame/zoomtoolbar.py | 26 | ||||
-rw-r--r-- | src/jarabe/model/Makefile.am | 4 | ||||
-rw-r--r-- | src/jarabe/model/homeactivity.py | 245 | ||||
-rw-r--r-- | src/jarabe/model/homemodel.py | 286 | ||||
-rw-r--r-- | src/jarabe/model/shell.py | 556 | ||||
-rw-r--r-- | src/jarabe/model/shellmodel.py | 80 | ||||
-rw-r--r-- | src/jarabe/shellservice.py | 21 | ||||
-rw-r--r-- | src/jarabe/view/buddymenu.py | 23 | ||||
-rw-r--r-- | src/jarabe/view/keyhandler.py | 2 | ||||
-rw-r--r-- | src/jarabe/view/launchwindow.py | 4 | ||||
-rw-r--r-- | src/jarabe/view/shell.py | 38 | ||||
-rw-r--r-- | src/jarabe/view/tabbinghandler.py | 39 |
16 files changed, 644 insertions, 719 deletions
diff --git a/src/jarabe/desktop/favoritesview.py b/src/jarabe/desktop/favoritesview.py index 8f98f9b..d0284ba 100644 --- a/src/jarabe/desktop/favoritesview.py +++ b/src/jarabe/desktop/favoritesview.py @@ -30,10 +30,10 @@ from sugar.graphics.alert import Alert from sugar.profile import get_profile from sugar import activity -from jarabe.view import shell +from jarabe.view import shell as shellview from jarabe.view.palettes import JournalPalette from jarabe.view.palettes import CurrentActivityPalette, ActivityPalette -from jarabe.model import shellmodel +from jarabe.model import shell from jarabe.controlpanel.gui import ControlPanel from jarabe.session import get_session_manager @@ -350,7 +350,7 @@ class ActivityIcon(CanvasIcon): def __button_release_event_cb(self, icon, event): self.palette.popdown(immediate=True) self._uncolor() - shell.get_instance().start_activity(self._activity_info.bundle_id) + shellview.get_instance().start_activity(self._activity_info.bundle_id) def get_bundle_id(self): return self._activity_info.bundle_id @@ -371,7 +371,7 @@ class ActivityIcon(CanvasIcon): class CurrentActivityIcon(CanvasIcon, hippo.CanvasItem): def __init__(self): CanvasIcon.__init__(self, cache=True) - self._home_model = shellmodel.get_instance().get_home() + self._home_model = shell.get_model() if self._home_model.get_active_activity() is not None: self._update(self._home_model.get_active_activity()) diff --git a/src/jarabe/desktop/homewindow.py b/src/jarabe/desktop/homewindow.py index 204cc6f..295eb27 100644 --- a/src/jarabe/desktop/homewindow.py +++ b/src/jarabe/desktop/homewindow.py @@ -23,8 +23,8 @@ from jarabe.desktop.meshbox import MeshBox from jarabe.desktop.homebox import HomeBox from jarabe.desktop.friendsbox import FriendsBox from jarabe.desktop.transitionbox import TransitionBox -from jarabe.model.shellmodel import ShellModel -from jarabe.model import shellmodel +from jarabe.model.shell import ShellModel +from jarabe.model import shell _HOME_PAGE = 0 _FRIENDS_PAGE = 1 @@ -69,7 +69,7 @@ class HomeWindow(gtk.Window): self._transition_box.connect('completed', self._transition_completed_cb) - model = shellmodel.get_instance() + model = shell.get_model() model.connect('notify::zoom-level', self.__zoom_level_changed_cb) def _enter_notify_event_cb(self, window, event): diff --git a/src/jarabe/frame/activitiestray.py b/src/jarabe/frame/activitiestray.py index 1a66f53..8211265 100644 --- a/src/jarabe/frame/activitiestray.py +++ b/src/jarabe/frame/activitiestray.py @@ -30,14 +30,14 @@ from sugar.graphics.menuitem import MenuItem from sugar import activity from sugar import profile -from jarabe.model import shellmodel +from jarabe.model import shell from jarabe.model import neighborhood from jarabe.model import owner from jarabe.view.palettes import JournalPalette, CurrentActivityPalette from jarabe.view.pulsingicon import PulsingIcon from jarabe.frame.frameinvoker import FrameWidgetInvoker from jarabe.frame.notification import NotificationIcon -from jarabe.view import shell +from jarabe.view import shell as shellview import jarabe.frame.frame class ActivityButton(RadioToolButton): @@ -150,7 +150,7 @@ class ActivityInviteButton(BaseInviteButton): def _launch(self): """Join the activity in the invite.""" - shell_inst = shell.get_instance() + shell_inst = shellview.get_instance() shell_inst.join_activity(self._activity_model.get_bundle_id(), self._activity_model.get_id()) @@ -196,7 +196,7 @@ class PrivateInviteButton(BaseInviteButton): def _launch(self): """Start the activity with private channel.""" - shell_inst = shell.get_instance() + shell_inst = shellview.get_instance() shell_inst.start_activity_with_uri(self._bundle_id, self._private_channel) @@ -248,7 +248,7 @@ class ActivityInvitePalette(BaseInvitePalette): self.set_primary_text(self._bundle_id) def _join(self): - shell_inst = shell.get_instance() + shell_inst = shellview.get_instance() shell_inst.join_activity(self._activity_model.get_bundle_id(), self._activity_model.get_id()) @@ -275,7 +275,7 @@ class PrivateInvitePalette(BaseInvitePalette): self.set_primary_text(self._bundle_id) def _join(self): - shell_inst = shell.get_instance() + shell_inst = shellview.get_instance() shell_inst.start_activity_with_uri(self._bundle_id, self._private_channel) invites = owner.get_model().get_invites() @@ -294,7 +294,7 @@ class ActivitiesTray(HTray): self._invite_to_item = {} self._freeze_button_clicks = False - self._home_model = shellmodel.get_instance().get_home() + self._home_model = shell.get_model() self._home_model.connect('activity-added', self.__activity_added_cb) self._home_model.connect('activity-removed', self.__activity_removed_cb) self._home_model.connect('active-activity-changed', diff --git a/src/jarabe/frame/friendstray.py b/src/jarabe/frame/friendstray.py index b796a1e..cc00a6c 100644 --- a/src/jarabe/frame/friendstray.py +++ b/src/jarabe/frame/friendstray.py @@ -17,10 +17,10 @@ from sugar.presence import presenceservice from sugar.graphics.tray import VTray, TrayIcon -from jarabe.view import shell +from jarabe.view import shell as shellview from jarabe.view.buddymenu import BuddyMenu from jarabe.frame.frameinvoker import FrameWidgetInvoker -from jarabe.model import shellmodel +from jarabe.model import shell from jarabe.model import owner from jarabe.model.buddy import BuddyModel @@ -52,9 +52,8 @@ class FriendsTray(VTray): self._pservice.get_activities_async( \ reply_handler=self._get_activities_cb) - home_model = shellmodel.get_instance().get_home() - home_model.connect('active-activity-changed', - self._active_activity_changed_cb) + shell.get_model().connect('active-activity-changed', + self._active_activity_changed_cb) def _get_activities_cb(self, activities_list): for act in activities_list: @@ -86,7 +85,7 @@ class FriendsTray(VTray): self._buddies = {} def __activity_appeared_cb(self, pservice, activity_ps): - activity = shell.get_instance().get_current_activity() + activity = shellview.get_instance().get_current_activity() if activity and activity_ps.props.id == activity.get_id(): self._set_activity_ps(activity_ps, True) diff --git a/src/jarabe/frame/zoomtoolbar.py b/src/jarabe/frame/zoomtoolbar.py index cfc1863..cf30447 100644 --- a/src/jarabe/frame/zoomtoolbar.py +++ b/src/jarabe/frame/zoomtoolbar.py @@ -22,9 +22,9 @@ import gtk from sugar.graphics.palette import Palette from sugar.graphics.radiotoolbutton import RadioToolButton -from jarabe.view import shell +from jarabe.view import shell as shellview from jarabe.frame.frameinvoker import FrameWidgetInvoker -from jarabe.model import shellmodel +from jarabe.model import shell class ZoomToolbar(gtk.Toolbar): def __init__(self): @@ -34,15 +34,15 @@ class ZoomToolbar(gtk.Toolbar): self.set_direction(gtk.TEXT_DIR_LTR) self._mesh_button = self._add_button('zoom-neighborhood', - _('Neighborhood'), shellmodel.ShellModel.ZOOM_MESH) + _('Neighborhood'), shell.ShellModel.ZOOM_MESH) self._groups_button = self._add_button('zoom-groups', - _('Group'), shellmodel.ShellModel.ZOOM_FRIENDS) + _('Group'), shell.ShellModel.ZOOM_FRIENDS) self._home_button = self._add_button('zoom-home', - _('Home'), shellmodel.ShellModel.ZOOM_HOME) + _('Home'), shell.ShellModel.ZOOM_HOME) self._activity_button = self._add_button('zoom-activity', - _('Activity'), shellmodel.ShellModel.ZOOM_ACTIVITY) + _('Activity'), shell.ShellModel.ZOOM_ACTIVITY) - shell_model = shellmodel.get_instance() + shell_model = shell.get_model() self._set_zoom_level(shell_model.props.zoom_level) shell_model.connect('notify::zoom-level', self.__notify_zoom_level_cb) @@ -67,21 +67,21 @@ class ZoomToolbar(gtk.Toolbar): def __level_clicked_cb(self, button, level): if not button.get_active(): return - if shellmodel.get_instance().props.zoom_level != level: - shell.get_instance().set_zoom_level(level) + if shell.get_model().props.zoom_level != level: + shellview.get_instance().set_zoom_level(level) def __notify_zoom_level_cb(self, model, pspec): self._set_zoom_level(model.props.zoom_level) def _set_zoom_level(self, new_level): logging.debug('new zoom level: %r' % new_level) - if new_level == shellmodel.ShellModel.ZOOM_MESH: + if new_level == shell.ShellModel.ZOOM_MESH: self._mesh_button.props.active = True - elif new_level == shellmodel.ShellModel.ZOOM_FRIENDS: + elif new_level == shell.ShellModel.ZOOM_FRIENDS: self._groups_button.props.active = True - elif new_level == shellmodel.ShellModel.ZOOM_HOME: + elif new_level == shell.ShellModel.ZOOM_HOME: self._home_button.props.active = True - elif new_level == shellmodel.ShellModel.ZOOM_ACTIVITY: + elif new_level == shell.ShellModel.ZOOM_ACTIVITY: self._activity_button.props.active = True else: raise ValueError('Invalid zoom level: %r' % (new_level)) diff --git a/src/jarabe/model/Makefile.am b/src/jarabe/model/Makefile.am index e920003..ad5b3ff 100644 --- a/src/jarabe/model/Makefile.am +++ b/src/jarabe/model/Makefile.am @@ -4,12 +4,10 @@ sugar_PYTHON = \ accesspoint.py \ buddy.py \ friends.py \ - homeactivity.py \ - homemodel.py \ invites.py \ owner.py \ neighborhood.py \ network.py \ - shellmodel.py \ + shell.py \ screen.py \ sound.py diff --git a/src/jarabe/model/homeactivity.py b/src/jarabe/model/homeactivity.py deleted file mode 100644 index 6c90692..0000000 --- a/src/jarabe/model/homeactivity.py +++ /dev/null @@ -1,245 +0,0 @@ -# Copyright (C) 2006-2007 Owen Williams. -# -# 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 time -import logging -import os - -import gobject -import dbus - -from sugar.graphics.xocolor import XoColor -from sugar.presence import presenceservice -from sugar import profile -from sugar import wm - -from jarabe import config - -_SERVICE_NAME = "org.laptop.Activity" -_SERVICE_PATH = "/org/laptop/Activity" -_SERVICE_INTERFACE = "org.laptop.Activity" - -class HomeActivity(gobject.GObject): - """Activity which appears in the "Home View" of the Sugar shell - - This class stores the Sugar Shell's metadata regarding a - given activity/application in the system. It interacts with - the sugar.activity.* modules extensively in order to - accomplish its tasks. - """ - - __gtype_name__ = 'SugarHomeActivity' - - __gproperties__ = { - 'launching' : (bool, None, None, False, - gobject.PARAM_READWRITE), - } - - def __init__(self, activity_info, activity_id, window=None): - """Initialise the HomeActivity - - activity_info -- sugar.activity.registry.ActivityInfo instance, - provides the information required to actually - create the new instance. This is, in effect, - the "type" of activity being created. - activity_id -- unique identifier for this instance - of the activity type - window -- Main WnckWindow of the activity - """ - gobject.GObject.__init__(self) - - self._window = None - self._service = None - self._activity_id = activity_id - self._activity_info = activity_info - self._launch_time = time.time() - self._launching = False - - if window is not None: - self.set_window(window) - - self._retrieve_service() - - self._name_owner_changed_handler = None - if not self._service: - bus = dbus.SessionBus() - self._name_owner_changed_handler = bus.add_signal_receiver( - self._name_owner_changed_cb, - signal_name="NameOwnerChanged", - dbus_interface="org.freedesktop.DBus") - - def set_window(self, window): - """Set the window for the activity - - We allow resetting the window for an activity so that we - can replace the launcher once we get its real window. - """ - if not window: - raise ValueError("window must be valid") - self._window = window - - def get_service(self): - """Get the activity service - - Note that non-native Sugar applications will not have - such a service, so the return value will be None in - those cases. - """ - - return self._service - - def get_title(self): - """Retrieve the application's root window's suggested title""" - if self._window: - return self._window.get_name() - else: - return '' - - def get_icon_path(self): - """Retrieve the activity's icon (file) name""" - if self.is_journal(): - return os.path.join(config.data_path, 'icons/activity-journal.svg') - elif self._activity_info: - return self._activity_info.icon - else: - return None - - def get_icon_color(self): - """Retrieve the appropriate icon colour for this activity - - Uses activity_id to index into the PresenceService's - set of activity colours, if the PresenceService does not - have an entry (implying that this is not a Sugar-shared application) - uses the local user's profile.get_color() to determine the - colour for the icon. - """ - pservice = presenceservice.get_instance() - - # HACK to suppress warning in logs when activity isn't found - # (if it's locally launched and not shared yet) - activity = None - for act in pservice.get_activities(): - if self._activity_id == act.props.id: - activity = act - break - - if activity != None: - return XoColor(activity.props.color) - else: - return profile.get_color() - - def get_activity_id(self): - """Retrieve the "activity_id" passed in to our constructor - - This is a "globally likely unique" identifier generated by - sugar.util.unique_id - """ - return self._activity_id - - def get_xid(self): - """Retrieve the X-windows ID of our root window""" - return self._window.get_xid() - - def get_window(self): - """Retrieve the X-windows root window of this application - - This was stored by the set_window method, which was - called by HomeModel._add_activity, which was called - via a callback that looks for all 'window-opened' - events. - - HomeModel currently uses a dbus service query on the - activity to determine to which HomeActivity the newly - launched window belongs. - """ - return self._window - - def get_type(self): - """Retrieve the activity bundle id for future reference""" - if self._window is None: - return None - else: - return wm.get_bundle_id(self._window) - - def is_journal(self): - """Returns boolean if the activity is of type JournalActivity""" - return self.get_type() == 'org.laptop.JournalActivity' - - def get_launch_time(self): - """Return the time at which the activity was first launched - - Format is floating-point time.time() value - (seconds since the epoch) - """ - return self._launch_time - - def get_pid(self): - """Returns the activity's PID""" - return self._window.get_pid() - - def equals(self, activity): - if self._activity_id and activity.get_activity_id(): - return self._activity_id == activity.get_activity_id() - if self._window.get_xid() and activity.get_xid(): - return self._window.get_xid() == activity.get_xid() - return False - - def do_set_property(self, pspec, value): - if pspec.name == 'launching': - self._launching = value - - def do_get_property(self, pspec): - if pspec.name == 'launching': - return self._launching - - def _get_service_name(self): - if self._activity_id: - return _SERVICE_NAME + self._activity_id - else: - return None - - def _retrieve_service(self): - if not self._activity_id: - return - - try: - bus = dbus.SessionBus() - proxy = bus.get_object(self._get_service_name(), - _SERVICE_PATH + "/" + self._activity_id) - self._service = dbus.Interface(proxy, _SERVICE_INTERFACE) - except dbus.DBusException: - self._service = None - - def _name_owner_changed_cb(self, name, old, new): - if name == self._get_service_name(): - self._retrieve_service() - self.set_active(True) - self._name_owner_changed_handler.remove() - self._name_owner_changed_handler = None - - def set_active(self, state): - """Propagate the current state to the activity object""" - if self._service is not None: - self._service.SetActive(state, - reply_handler=self._set_active_success, - error_handler=self._set_active_error) - - def _set_active_success(self): - pass - - def _set_active_error(self, err): - logging.error("set_active() failed: %s" % err) - diff --git a/src/jarabe/model/homemodel.py b/src/jarabe/model/homemodel.py deleted file mode 100644 index 3f116bf..0000000 --- a/src/jarabe/model/homemodel.py +++ /dev/null @@ -1,286 +0,0 @@ -# Copyright (C) 2006-2007 Owen Williams. -# -# 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 logging - -import gobject -import wnck -import gtk - -from sugar import wm -from sugar.activity import get_registry - -from jarabe.model.homeactivity import HomeActivity - -def get_sugar_window_type(wnck_window): - window = gtk.gdk.window_foreign_new(wnck_window.get_xid()) - prop_info = window.property_get('_SUGAR_WINDOW_TYPE', 'STRING') - if prop_info is None: - return None - else: - return prop_info[2] - -class HomeModel(gobject.GObject): - """Model of the "Home" view (activity management) - - The HomeModel is basically the point of registration - for all running activities within Sugar. It traps - events that tell the system there is a new activity - being created (generated by the activity factories), - or removed, as well as those which tell us that the - currently focussed activity has changed. - - The HomeModel tracks a set of HomeActivity instances, - which are tracking the window to activity mappings - the activity factories have set up. - """ - __gsignals__ = { - 'activity-added': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])), - 'activity-removed': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])), - 'active-activity-changed': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])), - 'tabbing-activity-changed': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])), - 'launch-started': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])), - 'launch-completed': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])), - 'launch-failed': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])) - } - - def __init__(self): - gobject.GObject.__init__(self) - - self._activities = [] - self._active_activity = None - self._tabbing_activity = None - - screen = wnck.screen_get_default() - screen.connect('window-opened', self._window_opened_cb) - screen.connect('window-closed', self._window_closed_cb) - screen.connect('active-window-changed', - self._active_window_changed_cb) - - def _get_activities_with_window(self): - ret = [] - for i in self._activities: - if i.get_window() is not None: - ret.append(i) - return ret - - def get_previous_activity(self, current=None): - if not current: - current = self._active_activity - - activities = self._get_activities_with_window() - i = activities.index(current) - if len(activities) == 0: - return None - elif i - 1 >= 0: - return activities[i - 1] - else: - return activities[len(activities) - 1] - - def get_next_activity(self, current=None): - if not current: - current = self._active_activity - - activities = self._get_activities_with_window() - i = activities.index(current) - if len(activities) == 0: - return None - elif i + 1 < len(activities): - return activities[i + 1] - else: - return activities[0] - - def get_active_activity(self): - """Returns the activity that the user is currently working in""" - return self._active_activity - - def get_tabbing_activity(self): - """Returns the activity that is currently highlighted during tabbing""" - return self._tabbing_activity - - def set_tabbing_activity(self, activity): - """Sets the activity that is currently highlighted during tabbing""" - self._tabbing_activity = activity - self.emit("tabbing-activity-changed", self._tabbing_activity) - - def _set_active_activity(self, home_activity): - if self._active_activity == home_activity: - return - - if home_activity: - home_activity.set_active(True) - - if self._active_activity: - self._active_activity.set_active(False) - - self._active_activity = home_activity - self.emit('active-activity-changed', self._active_activity) - - def __iter__(self): - return iter(self._activities) - - def __len__(self): - return len(self._activities) - - def __getitem__(self, i): - return self._activities[i] - - def index(self, obj): - return self._activities.index(obj) - - def _window_opened_cb(self, screen, window): - if window.get_window_type() == wnck.WINDOW_NORMAL: - home_activity = None - - activity_id = wm.get_activity_id(window) - - service_name = wm.get_bundle_id(window) - if service_name: - registry = get_registry() - activity_info = registry.get_activity(service_name) - else: - activity_info = None - - if activity_id: - home_activity = self._get_activity_by_id(activity_id) - - if not home_activity: - home_activity = HomeActivity(activity_info, activity_id, window) - self._add_activity(home_activity) - else: - home_activity.set_window(window) - - if get_sugar_window_type(window) != 'launcher': - home_activity.props.launching = False - self.emit('launch-completed', home_activity) - - if self._active_activity is None: - self._set_active_activity(home_activity) - - def _window_closed_cb(self, screen, window): - if window.get_window_type() == wnck.WINDOW_NORMAL: - self._remove_activity_by_xid(window.get_xid()) - - def _get_activity_by_xid(self, xid): - for home_activity in self._activities: - if home_activity.get_xid() == xid: - return home_activity - return None - - def _get_activity_by_id(self, activity_id): - for home_activity in self._activities: - if home_activity.get_activity_id() == activity_id: - return home_activity - return None - - def _active_window_changed_cb(self, screen, previous_window=None): - window = screen.get_active_window() - if window is None: - return - - if window.get_window_type() != wnck.WINDOW_DIALOG: - while window.get_transient() is not None: - window = window.get_transient() - - act = self._get_activity_by_xid(window.get_xid()) - if act is not None: - self._set_active_activity(act) - - def _add_activity(self, home_activity): - self._activities.append(home_activity) - self.emit('activity-added', home_activity) - - def _remove_activity(self, home_activity): - if home_activity == self._active_activity: - windows = wnck.screen_get_default().get_windows_stacked() - windows.reverse() - for window in windows: - new_activity = self._get_activity_by_xid(window.get_xid()) - if new_activity is not None: - self._set_active_activity(new_activity) - break - else: - logging.error('No activities are running') - self._set_active_activity(None) - - self.emit('activity-removed', home_activity) - self._activities.remove(home_activity) - - def _remove_activity_by_xid(self, xid): - home_activity = self._get_activity_by_xid(xid) - if home_activity: - self._remove_activity(home_activity) - else: - logging.error('Model for window %d does not exist.' % xid) - - def notify_launch(self, activity_id, service_name): - registry = get_registry() - activity_info = registry.get_activity(service_name) - if not activity_info: - raise ValueError("Activity service name '%s'" \ - " was not found in the bundle registry." - % service_name) - home_activity = HomeActivity(activity_info, activity_id) - home_activity.props.launching = True - self._add_activity(home_activity) - - self._set_active_activity(home_activity) - - self.emit('launch-started', home_activity) - - # FIXME: better learn about finishing processes by receiving a signal. - # Now just check whether an activity has a window after ~90sec - gobject.timeout_add(90000, self._check_activity_launched, activity_id) - - def notify_launch_failed(self, activity_id): - home_activity = self._get_activity_by_id(activity_id) - if home_activity: - logging.debug("Activity %s (%s) launch failed" % \ - (activity_id, home_activity.get_type())) - home_activity.props.launching = False - self._remove_activity(home_activity) - else: - logging.error('Model for activity id %s does not exist.' - % activity_id) - - self.emit('launch-failed', home_activity) - - def _check_activity_launched(self, activity_id): - home_activity = self._get_activity_by_id(activity_id) - - if not home_activity: - logging.debug('Activity %s has been closed already.' % activity_id) - return False - - if home_activity.props.launching: - logging.debug('Activity %s still launching, assuming it failed...' - % activity_id) - self.notify_launch_failed(activity_id) - return False diff --git a/src/jarabe/model/shell.py b/src/jarabe/model/shell.py new file mode 100644 index 0000000..5515189 --- /dev/null +++ b/src/jarabe/model/shell.py @@ -0,0 +1,556 @@ +# Copyright (C) 2006-2007 Owen Williams. +# Copyright (C) 2006-2008 Red Hat, Inc. +# +# 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 logging +import time +import os + +import wnck +import gobject +import gtk +import dbus + +from sugar import wm +from sugar.activity import get_registry +from sugar.graphics.xocolor import XoColor +from sugar.presence import presenceservice +from sugar import profile + +from jarabe import config + +_SERVICE_NAME = "org.laptop.Activity" +_SERVICE_PATH = "/org/laptop/Activity" +_SERVICE_INTERFACE = "org.laptop.Activity" + +def get_sugar_window_type(wnck_window): + window = gtk.gdk.window_foreign_new(wnck_window.get_xid()) + prop_info = window.property_get('_SUGAR_WINDOW_TYPE', 'STRING') + if prop_info is None: + return None + else: + return prop_info[2] + +class Activity(gobject.GObject): + """Activity which appears in the "Home View" of the Sugar shell + + This class stores the Sugar Shell's metadata regarding a + given activity/application in the system. It interacts with + the sugar.activity.* modules extensively in order to + accomplish its tasks. + """ + + __gtype_name__ = 'SugarHomeActivity' + + __gproperties__ = { + 'launching' : (bool, None, None, False, + gobject.PARAM_READWRITE), + } + + def __init__(self, activity_info, activity_id, window=None): + """Initialise the HomeActivity + + activity_info -- sugar.activity.registry.ActivityInfo instance, + provides the information required to actually + create the new instance. This is, in effect, + the "type" of activity being created. + activity_id -- unique identifier for this instance + of the activity type + window -- Main WnckWindow of the activity + """ + gobject.GObject.__init__(self) + + self._window = None + self._service = None + self._activity_id = activity_id + self._activity_info = activity_info + self._launch_time = time.time() + self._launching = False + + if window is not None: + self.set_window(window) + + self._retrieve_service() + + self._name_owner_changed_handler = None + if not self._service: + bus = dbus.SessionBus() + self._name_owner_changed_handler = bus.add_signal_receiver( + self._name_owner_changed_cb, + signal_name="NameOwnerChanged", + dbus_interface="org.freedesktop.DBus") + + def set_window(self, window): + """Set the window for the activity + + We allow resetting the window for an activity so that we + can replace the launcher once we get its real window. + """ + if not window: + raise ValueError("window must be valid") + self._window = window + + def get_service(self): + """Get the activity service + + Note that non-native Sugar applications will not have + such a service, so the return value will be None in + those cases. + """ + + return self._service + + def get_title(self): + """Retrieve the application's root window's suggested title""" + if self._window: + return self._window.get_name() + else: + return '' + + def get_icon_path(self): + """Retrieve the activity's icon (file) name""" + if self.is_journal(): + return os.path.join(config.data_path, 'icons/activity-journal.svg') + elif self._activity_info: + return self._activity_info.icon + else: + return None + + def get_icon_color(self): + """Retrieve the appropriate icon colour for this activity + + Uses activity_id to index into the PresenceService's + set of activity colours, if the PresenceService does not + have an entry (implying that this is not a Sugar-shared application) + uses the local user's profile.get_color() to determine the + colour for the icon. + """ + pservice = presenceservice.get_instance() + + # HACK to suppress warning in logs when activity isn't found + # (if it's locally launched and not shared yet) + activity = None + for act in pservice.get_activities(): + if self._activity_id == act.props.id: + activity = act + break + + if activity != None: + return XoColor(activity.props.color) + else: + return profile.get_color() + + def get_activity_id(self): + """Retrieve the "activity_id" passed in to our constructor + + This is a "globally likely unique" identifier generated by + sugar.util.unique_id + """ + return self._activity_id + + def get_xid(self): + """Retrieve the X-windows ID of our root window""" + return self._window.get_xid() + + def get_window(self): + """Retrieve the X-windows root window of this application + + This was stored by the set_window method, which was + called by HomeModel._add_activity, which was called + via a callback that looks for all 'window-opened' + events. + + HomeModel currently uses a dbus service query on the + activity to determine to which HomeActivity the newly + launched window belongs. + """ + return self._window + + def get_type(self): + """Retrieve the activity bundle id for future reference""" + if self._window is None: + return None + else: + return wm.get_bundle_id(self._window) + + def is_journal(self): + """Returns boolean if the activity is of type JournalActivity""" + return self.get_type() == 'org.laptop.JournalActivity' + + def get_launch_time(self): + """Return the time at which the activity was first launched + + Format is floating-point time.time() value + (seconds since the epoch) + """ + return self._launch_time + + def get_pid(self): + """Returns the activity's PID""" + return self._window.get_pid() + + def equals(self, activity): + if self._activity_id and activity.get_activity_id(): + return self._activity_id == activity.get_activity_id() + if self._window.get_xid() and activity.get_xid(): + return self._window.get_xid() == activity.get_xid() + return False + + def do_set_property(self, pspec, value): + if pspec.name == 'launching': + self._launching = value + + def do_get_property(self, pspec): + if pspec.name == 'launching': + return self._launching + + def _get_service_name(self): + if self._activity_id: + return _SERVICE_NAME + self._activity_id + else: + return None + + def _retrieve_service(self): + if not self._activity_id: + return + + try: + bus = dbus.SessionBus() + proxy = bus.get_object(self._get_service_name(), + _SERVICE_PATH + "/" + self._activity_id) + self._service = dbus.Interface(proxy, _SERVICE_INTERFACE) + except dbus.DBusException: + self._service = None + + def _name_owner_changed_cb(self, name, old, new): + if name == self._get_service_name(): + self._retrieve_service() + self.set_active(True) + self._name_owner_changed_handler.remove() + self._name_owner_changed_handler = None + + def set_active(self, state): + """Propagate the current state to the activity object""" + if self._service is not None: + self._service.SetActive(state, + reply_handler=self._set_active_success, + error_handler=self._set_active_error) + + def _set_active_success(self): + pass + + def _set_active_error(self, err): + logging.error("set_active() failed: %s" % err) + +class ShellModel(gobject.GObject): + """Model of the shell (activity management) + + The ShellModel is basically the point of registration + for all running activities within Sugar. It traps + events that tell the system there is a new activity + being created (generated by the activity factories), + or removed, as well as those which tell us that the + currently focussed activity has changed. + + The HomeModel tracks a set of HomeActivity instances, + which are tracking the window to activity mappings + the activity factories have set up. + """ + + __gsignals__ = { + 'activity-added': (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, + ([gobject.TYPE_PYOBJECT])), + 'activity-removed': (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, + ([gobject.TYPE_PYOBJECT])), + 'active-activity-changed': (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, + ([gobject.TYPE_PYOBJECT])), + 'tabbing-activity-changed': (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, + ([gobject.TYPE_PYOBJECT])), + 'launch-started': (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, + ([gobject.TYPE_PYOBJECT])), + 'launch-completed': (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, + ([gobject.TYPE_PYOBJECT])), + 'launch-failed': (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, + ([gobject.TYPE_PYOBJECT])) + } + + ZOOM_MESH = 0 + ZOOM_FRIENDS = 1 + ZOOM_HOME = 2 + ZOOM_ACTIVITY = 3 + + __gproperties__ = { + 'zoom-level' : (int, None, None, + 0, 3, ZOOM_HOME, + gobject.PARAM_READABLE) + } + + def __init__(self): + gobject.GObject.__init__(self) + + self._current_activity = None + self._zoom_level = self.ZOOM_HOME + self._showing_desktop = True + self._activities = [] + self._active_activity = None + self._tabbing_activity = None + self._pservice = presenceservice.get_instance() + + self._screen = wnck.screen_get_default() + self._screen.connect('window-opened', self._window_opened_cb) + self._screen.connect('window-closed', self._window_closed_cb) + self._screen.connect('showing-desktop-changed', + self._showing_desktop_changed_cb) + self._screen.connect('active-window-changed', + self._active_window_changed_cb) + + + def set_zoom_level(self, level): + self._zoom_level = level + self.notify('zoom-level') + + def get_zoom_level(self): + if self._screen.get_showing_desktop(): + return self._zoom_level + else: + return self.ZOOM_ACTIVITY + + def do_get_property(self, pspec): + if pspec.name == 'zoom-level': + return self.get_zoom_level() + + def _showing_desktop_changed_cb(self, screen): + showing_desktop = self._screen.get_showing_desktop() + if self._showing_desktop != showing_desktop: + self._showing_desktop = showing_desktop + self.notify('zoom-level') + + def _get_activities_with_window(self): + ret = [] + for i in self._activities: + if i.get_window() is not None: + ret.append(i) + return ret + + def get_previous_activity(self, current=None): + if not current: + current = self._active_activity + + activities = self._get_activities_with_window() + i = activities.index(current) + if len(activities) == 0: + return None + elif i - 1 >= 0: + return activities[i - 1] + else: + return activities[len(activities) - 1] + + def get_next_activity(self, current=None): + if not current: + current = self._active_activity + + activities = self._get_activities_with_window() + i = activities.index(current) + if len(activities) == 0: + return None + elif i + 1 < len(activities): + return activities[i + 1] + else: + return activities[0] + + def get_active_activity(self): + """Returns the activity that the user is currently working in""" + return self._active_activity + + def get_tabbing_activity(self): + """Returns the activity that is currently highlighted during tabbing""" + return self._tabbing_activity + + def set_tabbing_activity(self, activity): + """Sets the activity that is currently highlighted during tabbing""" + self._tabbing_activity = activity + self.emit("tabbing-activity-changed", self._tabbing_activity) + + def _set_active_activity(self, home_activity): + if self._active_activity == home_activity: + return + + if home_activity: + home_activity.set_active(True) + + if self._active_activity: + self._active_activity.set_active(False) + + self._active_activity = home_activity + self.emit('active-activity-changed', self._active_activity) + + def __iter__(self): + return iter(self._activities) + + def __len__(self): + return len(self._activities) + + def __getitem__(self, i): + return self._activities[i] + + def index(self, obj): + return self._activities.index(obj) + + def _window_opened_cb(self, screen, window): + if window.get_window_type() == wnck.WINDOW_NORMAL: + home_activity = None + + activity_id = wm.get_activity_id(window) + + service_name = wm.get_bundle_id(window) + if service_name: + registry = get_registry() + activity_info = registry.get_activity(service_name) + else: + activity_info = None + + if activity_id: + home_activity = self._get_activity_by_id(activity_id) + + if not home_activity: + home_activity = Activity(activity_info, activity_id, window) + self._add_activity(home_activity) + else: + home_activity.set_window(window) + + if get_sugar_window_type(window) != 'launcher': + home_activity.props.launching = False + self.emit('launch-completed', home_activity) + + if self._active_activity is None: + self._set_active_activity(home_activity) + + def _window_closed_cb(self, screen, window): + if window.get_window_type() == wnck.WINDOW_NORMAL: + self._remove_activity_by_xid(window.get_xid()) + + def _get_activity_by_xid(self, xid): + for home_activity in self._activities: + if home_activity.get_xid() == xid: + return home_activity + return None + + def _get_activity_by_id(self, activity_id): + for home_activity in self._activities: + if home_activity.get_activity_id() == activity_id: + return home_activity + return None + + def _active_window_changed_cb(self, screen, previous_window=None): + window = screen.get_active_window() + if window is None: + return + + if window.get_window_type() != wnck.WINDOW_DIALOG: + while window.get_transient() is not None: + window = window.get_transient() + + act = self._get_activity_by_xid(window.get_xid()) + if act is not None: + self._set_active_activity(act) + + def _add_activity(self, home_activity): + self._activities.append(home_activity) + self.emit('activity-added', home_activity) + + def _remove_activity(self, home_activity): + if home_activity == self._active_activity: + windows = wnck.screen_get_default().get_windows_stacked() + windows.reverse() + for window in windows: + new_activity = self._get_activity_by_xid(window.get_xid()) + if new_activity is not None: + self._set_active_activity(new_activity) + break + else: + logging.error('No activities are running') + self._set_active_activity(None) + + self.emit('activity-removed', home_activity) + self._activities.remove(home_activity) + + def _remove_activity_by_xid(self, xid): + home_activity = self._get_activity_by_xid(xid) + if home_activity: + self._remove_activity(home_activity) + else: + logging.error('Model for window %d does not exist.' % xid) + + def notify_launch(self, activity_id, service_name): + registry = get_registry() + activity_info = registry.get_activity(service_name) + if not activity_info: + raise ValueError("Activity service name '%s'" \ + " was not found in the bundle registry." + % service_name) + home_activity = Activity(activity_info, activity_id) + home_activity.props.launching = True + self._add_activity(home_activity) + + self._set_active_activity(home_activity) + + self.emit('launch-started', home_activity) + + # FIXME: better learn about finishing processes by receiving a signal. + # Now just check whether an activity has a window after ~90sec + gobject.timeout_add(90000, self._check_activity_launched, activity_id) + + def notify_launch_failed(self, activity_id): + home_activity = self._get_activity_by_id(activity_id) + if home_activity: + logging.debug("Activity %s (%s) launch failed" % \ + (activity_id, home_activity.get_type())) + home_activity.props.launching = False + self._remove_activity(home_activity) + else: + logging.error('Model for activity id %s does not exist.' + % activity_id) + + self.emit('launch-failed', home_activity) + + def _check_activity_launched(self, activity_id): + home_activity = self._get_activity_by_id(activity_id) + + if not home_activity: + logging.debug('Activity %s has been closed already.' % activity_id) + return False + + if home_activity.props.launching: + logging.debug('Activity %s still launching, assuming it failed...' + % activity_id) + self.notify_launch_failed(activity_id) + return False + +_model = None + +def get_model(): + global _model + if not _model: + _model = ShellModel() + return _model + diff --git a/src/jarabe/model/shellmodel.py b/src/jarabe/model/shellmodel.py deleted file mode 100644 index b7bf7bf..0000000 --- a/src/jarabe/model/shellmodel.py +++ /dev/null @@ -1,80 +0,0 @@ -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 wnck -import gobject - -from sugar.presence import presenceservice -from jarabe.model.homemodel import HomeModel - -class ShellModel(gobject.GObject): - ZOOM_MESH = 0 - ZOOM_FRIENDS = 1 - ZOOM_HOME = 2 - ZOOM_ACTIVITY = 3 - - __gproperties__ = { - 'zoom-level' : (int, None, None, - 0, 3, ZOOM_HOME, - gobject.PARAM_READABLE) - } - - def __init__(self): - gobject.GObject.__init__(self) - - self._current_activity = None - self._zoom_level = self.ZOOM_HOME - self._showing_desktop = True - - self._pservice = presenceservice.get_instance() - - self._home = HomeModel() - - self._screen = wnck.screen_get_default() - self._screen.connect('showing-desktop-changed', - self._showing_desktop_changed_cb) - - def set_zoom_level(self, level): - self._zoom_level = level - self.notify('zoom-level') - - def get_zoom_level(self): - if self._screen.get_showing_desktop(): - return self._zoom_level - else: - return self.ZOOM_ACTIVITY - - def do_get_property(self, pspec): - if pspec.name == 'zoom-level': - return self.get_zoom_level() - - def get_home(self): - return self._home - - def _showing_desktop_changed_cb(self, screen): - showing_desktop = self._screen.get_showing_desktop() - if self._showing_desktop != showing_desktop: - self._showing_desktop = showing_desktop - self.notify('zoom-level') - -_instance = None - -def get_instance(): - global _instance - if not _instance: - _instance = ShellModel() - return _instance - diff --git a/src/jarabe/shellservice.py b/src/jarabe/shellservice.py index 074f545..3c9fbb4 100644 --- a/src/jarabe/shellservice.py +++ b/src/jarabe/shellservice.py @@ -18,8 +18,8 @@ import dbus import os -from jarabe.view import shell -from jarabe.model import shellmodel +from jarabe.view import shell as shellview +from jarabe.model import shell from jarabe.model import owner _DBUS_SERVICE = "org.laptop.Shell" @@ -51,17 +51,16 @@ class ShellService(dbus.service.Object): _rainbow = None def __init__(self): - self._shell = shell.get_instance() - self._shell_model = shellmodel.get_instance() + self._shell = shellview.get_instance() + self._shell_model = shell.get_model() owner_model = owner.get_model() owner_model.connect('nick-changed', self._owner_nick_changed_cb) owner_model.connect('icon-changed', self._owner_icon_changed_cb) owner_model.connect('color-changed', self._owner_color_changed_cb) - self._home_model = self._shell_model.get_home() - self._home_model.connect('active-activity-changed', - self._cur_activity_changed_cb) + self._shell_model.connect('active-activity-changed', + self._cur_activity_changed_cb) bus = dbus.SessionBus() bus_name = dbus.service.BusName(_DBUS_SERVICE, bus=bus) @@ -80,14 +79,12 @@ class ShellService(dbus.service.Object): @dbus.service.method(_DBUS_SHELL_IFACE, in_signature="ss", out_signature="") def NotifyLaunch(self, bundle_id, activity_id): - home = self._shell.get_model().get_home() - home.notify_launch(activity_id, bundle_id) + shell.get_model().notify_launch(activity_id, bundle_id) @dbus.service.method(_DBUS_SHELL_IFACE, in_signature="s", out_signature="") def NotifyLaunchFailure(self, activity_id): - home = self._shell.get_model().get_home() - home.notify_launch_failed(activity_id) + shell.get_model().notify_launch_failed(activity_id) @dbus.service.signal(_DBUS_OWNER_IFACE, signature="s") def ColorChanged(self, color): @@ -127,7 +124,7 @@ class ShellService(dbus.service.Object): activity_id, dbus_interface=_DBUS_RAINBOW_IFACE) - def _cur_activity_changed_cb(self, home_model, new_activity): + def _cur_activity_changed_cb(self, shell_model, new_activity): new_id = "" if new_activity: new_id = new_activity.get_activity_id() diff --git a/src/jarabe/view/buddymenu.py b/src/jarabe/view/buddymenu.py index f4b2b3d..3ce0c50 100644 --- a/src/jarabe/view/buddymenu.py +++ b/src/jarabe/view/buddymenu.py @@ -22,8 +22,9 @@ from sugar.graphics.palette import Palette from sugar.graphics.menuitem import MenuItem from sugar.graphics.icon import Icon -from jarabe.model import shellmodel -from jarabe.view import shell +from jarabe.model import shell +from jarabe.model import friends +from jarabe.view import shell as shellview class BuddyMenu(Palette): def __init__(self, buddy): @@ -44,19 +45,15 @@ class BuddyMenu(Palette): if not buddy.is_owner(): self._add_items() - def _get_home_model(self): - return shellmodel.get_instance().get_home() - def __destroy_cb(self, menu): if self._active_activity_changed_hid is not None: - home_model = self._get_home_model() + home_model = shell.get_model() home_model.disconnect(self._active_activity_changed_hid) self._buddy.disconnect_by_func(self._buddy_icon_changed_cb) self._buddy.disconnect_by_func(self._buddy_nick_changed_cb) def _add_items(self): - friends = shellmodel.get_instance().get_friends() - if friends.has_buddy(self._buddy): + if friends.get_model().has_buddy(self._buddy): menu_item = MenuItem(_('Remove friend'), 'list-remove') menu_item.connect('activate', self._remove_friend_cb) else: @@ -70,7 +67,7 @@ class BuddyMenu(Palette): self._invite_menu.connect('activate', self._invite_friend_cb) self.menu.append(self._invite_menu) - home_model = self._get_home_model() + home_model = shell.get_model() self._active_activity_changed_hid = home_model.connect( 'active-activity-changed', self._cur_activity_changed_cb) activity = home_model.get_active_activity() @@ -108,14 +105,12 @@ class BuddyMenu(Palette): self.set_primary_text(nick) def _make_friend_cb(self, menuitem): - friends = shellmodel.get_instance().get_friends() - friends.make_friend(self._buddy) + friends.get_model().make_friend(self._buddy) def _remove_friend_cb(self, menuitem): - friends = shellmodel.get_instance().get_friends() - friends.remove(self._buddy) + friends.get_model().remove(self._buddy) def _invite_friend_cb(self, menuitem): - activity = shell.get_instance().get_current_activity() + activity = shellview.get_instance().get_current_activity() activity.invite(self._buddy) diff --git a/src/jarabe/view/keyhandler.py b/src/jarabe/view/keyhandler.py index 9a3a47b..17a8243 100644 --- a/src/jarabe/view/keyhandler.py +++ b/src/jarabe/view/keyhandler.py @@ -29,7 +29,7 @@ from jarabe.model import screen from jarabe.model import sound from jarabe.view import shell from jarabe.view.tabbinghandler import TabbingHandler -from jarabe.model.shellmodel import ShellModel +from jarabe.model.shell import ShellModel _BRIGHTNESS_STEP = 2 _VOLUME_STEP = sound.VOLUME_STEP diff --git a/src/jarabe/view/launchwindow.py b/src/jarabe/view/launchwindow.py index 384e6ec..480d2f0 100644 --- a/src/jarabe/view/launchwindow.py +++ b/src/jarabe/view/launchwindow.py @@ -23,7 +23,7 @@ from sugar.graphics import style from sugar.graphics import animator from sugar.graphics.xocolor import XoColor -from jarabe.model import shellmodel +from jarabe.model import shell from jarabe.view.pulsingicon import CanvasPulsingIcon class LaunchWindow(hippo.CanvasWindow): @@ -75,7 +75,7 @@ class LaunchBox(hippo.CanvasBox): self._animator = animator.Animator(1.0) - self._home = shellmodel.get_instance().get_home() + self._home = shell.get_model() self._home.connect('active-activity-changed', self.__active_activity_changed_cb) diff --git a/src/jarabe/view/shell.py b/src/jarabe/view/shell.py index d0608e5..d37783a 100644 --- a/src/jarabe/view/shell.py +++ b/src/jarabe/view/shell.py @@ -35,14 +35,14 @@ from sugar import env from jarabe.view.activityhost import ActivityHost from jarabe.view.launchwindow import LaunchWindow -from jarabe.model import shellmodel +from jarabe.model import shell from jarabe.journal import journalactivity class Shell(gobject.GObject): def __init__(self): gobject.GObject.__init__(self) - self._model = shellmodel.get_instance() + self._model = shell.get_model() self._hosts = {} self._launchers = {} self._screen = wnck.screen_get_default() @@ -58,11 +58,10 @@ class Shell(gobject.GObject): self.home_window = HomeWindow() self.home_window.show() - home_model = self._model.get_home() - home_model.connect('launch-started', self.__launch_started_cb) - home_model.connect('launch-failed', self.__launch_failed_cb) - home_model.connect('launch-completed', self.__launch_completed_cb) - home_model.connect('activity-removed', self._activity_removed_cb) + self._model.connect('launch-started', self.__launch_started_cb) + self._model.connect('launch-failed', self.__launch_failed_cb) + self._model.connect('launch-completed', self.__launch_completed_cb) + self._model.connect('activity-removed', self._activity_removed_cb) gobject.idle_add(self._start_journal_idle) @@ -88,7 +87,7 @@ class Shell(gobject.GObject): launch_window.show() self._launchers[home_activity.get_activity_id()] = launch_window - self._model.set_zoom_level(shellmodel.ShellModel.ZOOM_ACTIVITY) + self._model.set_zoom_level(shell.ShellModel.ZOOM_ACTIVITY) def __launch_failed_cb(self, home_model, home_activity): if not home_activity.is_journal(): @@ -156,13 +155,12 @@ class Shell(gobject.GObject): activityfactory.create_with_uri(activity_type, uri) def take_activity_screenshot(self): - if self._model.get_zoom_level() != shellmodel.ShellModel.ZOOM_ACTIVITY: + if self._model.get_zoom_level() != shell.ShellModel.ZOOM_ACTIVITY: return if self.get_frame().visible: return - home_model = self._model.get_home() - active_activity = home_model.get_active_activity() + active_activity = self._model.get_active_activity() if active_activity is not None: service = active_activity.get_service() if service is not None: @@ -176,7 +174,7 @@ class Shell(gobject.GObject): logging.debug('Already in the level %r' % level) return - if level == shellmodel.ShellModel.ZOOM_ACTIVITY: + if level == shell.ShellModel.ZOOM_ACTIVITY: host = self.get_current_activity() if host is None: raise ValueError('No current activity') @@ -186,36 +184,32 @@ class Shell(gobject.GObject): self._screen.toggle_showing_desktop(True) def toggle_activity_fullscreen(self): - if self._model.get_zoom_level() == shellmodel.ShellModel.ZOOM_ACTIVITY: + if self._model.get_zoom_level() == shell.ShellModel.ZOOM_ACTIVITY: self.get_current_activity().toggle_fullscreen() def activate_previous_activity(self): - home_model = self._model.get_home() - previous_activity = home_model.get_previous_activity() + previous_activity = self._model.get_previous_activity() if previous_activity: previous_activity.get_window().activate( gtk.get_current_event_time()) def activate_next_activity(self): - home_model = self._model.get_home() - next_activity = home_model.get_next_activity() + next_activity = self._model.get_next_activity() if next_activity: next_activity.get_window().activate(gtk.get_current_event_time()) def close_current_activity(self): - if self._model.get_zoom_level() != shellmodel.ShellModel.ZOOM_ACTIVITY: + if self._model.get_zoom_level() != shell.ShellModel.ZOOM_ACTIVITY: return - home_model = self._model.get_home() - active_activity = home_model.get_active_activity() + active_activity = self._model.get_active_activity() if active_activity.is_journal(): return self.get_current_activity().close() def get_current_activity(self): - home_model = self._model.get_home() - active_activity = home_model.get_active_activity() + active_activity = self._model.get_active_activity() return self._get_host_from_activity_model(active_activity) def get_activity(self, activity_id): diff --git a/src/jarabe/view/tabbinghandler.py b/src/jarabe/view/tabbinghandler.py index e8e8911..3c33e78 100644 --- a/src/jarabe/view/tabbinghandler.py +++ b/src/jarabe/view/tabbinghandler.py @@ -18,9 +18,9 @@ import logging import gtk import gobject -from jarabe.view import shell +from jarabe.view import shell as shellview from jarabe.frame import frame -from jarabe.model import shellmodel +from jarabe.model import shell _RAISE_DELAY = 250 @@ -74,8 +74,7 @@ class TabbingHandler(object): self._timeout = None def _activate_current(self): - shell_model = shellmodel.get_instance() - home_model = shell_model.get_home() + home_model = shell.get_model() activity = home_model.get_tabbing_activity() if activity and activity.get_window(): activity.get_window().activate(1) @@ -88,21 +87,20 @@ class TabbingHandler(object): first_switch = False if self._tabbing: - shell_model = shellmodel.get_instance() - home_model = shell_model.get_home() + shell_model = shell.get_model() zoom_level = shell_model.get_zoom_level() - zoom_activity = (zoom_level == shellmodel.ShellModel.ZOOM_ACTIVITY) + zoom_activity = (zoom_level == shell.ShellModel.ZOOM_ACTIVITY) if not zoom_activity and first_switch: - activity = home_model.get_active_activity() + activity = shell_model.get_active_activity() else: - activity = home_model.get_tabbing_activity() - activity = home_model.get_next_activity(current=activity) + activity = shell_model.get_tabbing_activity() + activity = shell_model.get_next_activity(current=activity) - home_model.set_tabbing_activity(activity) + shell_model.set_tabbing_activity(activity) self._start_timeout() else: - shell.get_instance().activate_next_activity() + shellview.get_instance().activate_next_activity() def previous_activity(self): if not self._tabbing: @@ -112,21 +110,20 @@ class TabbingHandler(object): first_switch = False if self._tabbing: - shell_model = shellmodel.get_instance() - home_model = shell_model.get_home() + shell_model = shell.get_model() zoom_level = shell_model.get_zoom_level() - zoom_activity = (zoom_level == shellmodel.ShellModel.ZOOM_ACTIVITY) + zoom_activity = (zoom_level == shell.ShellModel.ZOOM_ACTIVITY) if not zoom_activity and first_switch: - activity = home_model.get_active_activity() + activity = shell_model.get_active_activity() else: - activity = home_model.get_tabbing_activity() - activity = home_model.get_previous_activity(current=activity) + activity = shell_model.get_tabbing_activity() + activity = shell_model.get_previous_activity(current=activity) - home_model.set_tabbing_activity(activity) + shell_model.set_tabbing_activity(activity) self._start_timeout() else: - shell.get_instance().activate_next_activity() + shellview.get_instance().activate_next_activity() def stop(self): gtk.gdk.keyboard_ungrab() @@ -138,7 +135,7 @@ class TabbingHandler(object): self._cancel_timeout() self._activate_current() - home_model = shellmodel.get_instance().get_home() + home_model = shell.get_model() home_model.set_tabbing_activity(None) def is_tabbing(self): |