Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMarco 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)
commite53b1dc03a5bc0bf3a681789e3dc56687bb4a083 (patch)
treee1668cbbc60115c2ca502957e59c9675e3c3a3f9 /src
parent702cb0a538d0564e00bb481125c9bd734b243283 (diff)
Merge home model and shell model.
Diffstat (limited to 'src')
-rw-r--r--src/jarabe/desktop/favoritesview.py8
-rw-r--r--src/jarabe/desktop/homewindow.py6
-rw-r--r--src/jarabe/frame/activitiestray.py14
-rw-r--r--src/jarabe/frame/friendstray.py11
-rw-r--r--src/jarabe/frame/zoomtoolbar.py26
-rw-r--r--src/jarabe/model/Makefile.am4
-rw-r--r--src/jarabe/model/homeactivity.py245
-rw-r--r--src/jarabe/model/homemodel.py286
-rw-r--r--src/jarabe/model/shell.py556
-rw-r--r--src/jarabe/model/shellmodel.py80
-rw-r--r--src/jarabe/shellservice.py21
-rw-r--r--src/jarabe/view/buddymenu.py23
-rw-r--r--src/jarabe/view/keyhandler.py2
-rw-r--r--src/jarabe/view/launchwindow.py4
-rw-r--r--src/jarabe/view/shell.py38
-rw-r--r--src/jarabe/view/tabbinghandler.py39
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):