From 9a44da4488a0ff00150eb5cb114f74ba560b96a6 Mon Sep 17 00:00:00 2001 From: mike Date: Fri, 04 Dec 2009 05:58:29 +0000 Subject: Creator, Remote : Dual code review power! --- diff --git a/src/extensions/tutoriusremote.py b/src/extensions/tutoriusremote.py index fc93659..d795141 100755 --- a/src/extensions/tutoriusremote.py +++ b/src/extensions/tutoriusremote.py @@ -79,15 +79,14 @@ class TPalette(Palette): creator = default_creator() if creator.is_authoring == False: - # Replace the start creator button by the stop creator - # Allocate a white color for the text - self._creator_item.props.label = _("Stop this tutorial") + # Replace the start creator label by stop creator + self._creator_item.props.label = _("Stop authoring") creator.start_authoring(tutorial=None) else: # Attempt to close the creator - this will popup a confirmation # dialog if the user has unsaved changes - creator._cleanup_cb() + creator.cleanup_cb() # If the creator was not actually closed - (in case cancel # is implemented one day) diff --git a/tutorius/TProbe.py b/tutorius/TProbe.py index c0eedee..e2fe556 100644 --- a/tutorius/TProbe.py +++ b/tutorius/TProbe.py @@ -25,11 +25,14 @@ import cPickle as pickle from functools import partial +from jarabe.model.shell import get_model +from sugar.bundle.activitybundle import ActivityBundle + from . import addon from . import properties from .services import ObjectStore -from .dbustools import remote_call, save_args, ignore, logError +from .dbustools import save_args, ignore, logError import copy """ @@ -510,7 +513,6 @@ class ProbeProxy: """ Unregister an event listener @param address identifier given by subscribe() - @param block Force a synchroneous dbus call if True @return None """ LOGGER.debug("ProbeProxy :: Unregister adress %s issued", str(address)) @@ -522,7 +524,7 @@ class ProbeProxy: else: LOGGER.debug("ProbeProxy :: unsubscribe address %s failed : not registered", address) - def detach(self, block=False): + def detach(self): """ Detach the ProbeProxy from it's TProbe. All installed actions and subscribed events should be removed. @@ -544,8 +546,6 @@ class ProbeManager(object): """ _LOGGER = logging.getLogger("sugar.tutorius.ProbeManager") - default_instance = None - def __init__(self, proxy_class=ProbeProxy): """Constructor @param proxy_class Class to use for creating Proxies to activities. @@ -560,14 +560,18 @@ class ProbeManager(object): ProbeManager._LOGGER.debug("__init__()") - ProbeManager.default_instance = self - def setCurrentActivity(self, activity_id): if not activity_id in self._probes: raise RuntimeError("Activity not attached, id : %s"%activity_id) self._current_activity = activity_id def getCurrentActivity(self): + # TODO : Insert the correct call to remember the current activity, + # taking the views and frame into account + current_act = get_model().get_active_activity() + current_act_bundle = ActivityBundle(current_act.get_bundle_path()) + current_act_id = current_act_bundle.get_bundle_id() + self._current_activity = current_act_id return self._current_activity currentActivity = property(fget=getCurrentActivity, fset=setCurrentActivity) diff --git a/tutorius/actions.py b/tutorius/actions.py index a32138f..8cc5f08 100644 --- a/tutorius/actions.py +++ b/tutorius/actions.py @@ -150,12 +150,9 @@ class Action(TPropContainer): TPropContainer.__init__(self) self.position = (0,0) self._drag = None - # The differences dictionary. This is a structure that holds all the - # modifications that were made to the properties since the action - # was last installed or the last moment the notification was executed. - # Every property change will be logged inside it and it will be sent - # to the creator to update its action edition dialog. - self._property_update_cb = None + # The callback that will be triggered when the action is requested + # to notify all its changes + self._properties_updated_cb = None def do(self, **kwargs): """ @@ -172,17 +169,15 @@ class Action(TPropContainer): def set_notification_cb(self, notif_cb): LOGGER.debug("Action :: Setting notification callback for creator...") - self._property_update_cb = notif_cb + self._properties_updated_cb = notif_cb def update_property(self, name, value): """ Callback used in the wrapper to send a new value to an action. """ LOGGER.debug("Action :: update_property on %s with value '%s'"%(name, str(value))) - #property = getattr(self, name) - #property = value - - #self._props[name] = value + # Set the property itself - this will modify the diff dict and we will + # be able to notify the owner with the new value self.__setattr__(name, value) # Send the notification to the creator @@ -197,7 +192,7 @@ class Action(TPropContainer): # Empty the diff dict as we just synchronized with the creator self._diff_dict.clear() - def enter_editmode(self, *args, **kwargs): + def enter_editmode(self, **kwargs): """ Enters edit mode. The action should display itself in some way, without affecting the currently running application. The default is diff --git a/tutorius/creator.py b/tutorius/creator.py index 0d3ac3c..50017dc 100644 --- a/tutorius/creator.py +++ b/tutorius/creator.py @@ -58,7 +58,6 @@ def default_creator(): at a time. This method returns a new instance only if none already exists. Else, the existing instance is returned. """ - Creator._instance = Creator._instance or Creator() return Creator._instance def get_creator_proxy(): @@ -76,14 +75,22 @@ class Creator(Object): _instance = None - def __init__(self): + def __init__(self, probe_manager): + """ + Creates the instance of the creator. It is assumed this will be called + only once, by the Service. + + @param probe_manager The Probe Manager + """ bus_name = BusName(BUS_NAME, bus=SessionBus()) Object.__init__(self, bus_name, BUS_PATH) self.tuto = None self.is_authoring = False + if Creator._instance: + raise RuntimeError("Creator was already instanciated") Creator._instance = self - self._probe_mgr = TProbe.ProbeManager.default_instance + self._probe_mgr = probe_manager self._installed_actions = list() def start_authoring(self, tutorial=None): @@ -129,7 +136,7 @@ class Creator(Object): self._propedit = ToolBox(None) self._propedit.tree.signal_autoconnect({ - 'on_quit_clicked': self._cleanup_cb, + 'on_quit_clicked': self.cleanup_cb, 'on_save_clicked': self.save, 'on_action_activate': self._add_action_cb, 'on_event_activate': self._add_event_cb, @@ -156,18 +163,6 @@ class Creator(Object): self._transitions = dict() - # FIXME : remove when probemgr completed - #self._probe_mgr.attach('org.laptop.Calculate') - self._probe_mgr._current_activity = 'org.laptop.Calculate' - - def _tool_enter_notify_cb(self, window, event): - frame = jarabe.frame.get_view() - frame._bottom_panel.hover = True - - def _tool_leave_notify_cb(self, window, event): - frame = jarabe.frame.get_view() - frame._bottom_panel.hover = False - def _update_next_state(self, state, event, next_state): self._transitions[event] = next_state @@ -223,8 +218,8 @@ class Creator(Object): """ Set the tutorial modification point to the specified state. Actions of the state will enter the edit mode. - New actions will be inserted to that state and new transisions will - shift the current transision to the next state. + New actions will be inserted to that state and new transitions will + shift the current transition to the next state. @param state_name: the name of the state to use as insertion point """ @@ -324,21 +319,19 @@ class Creator(Object): self.set_insertion_point(new_state) - def properties_changed(self, action, properties): - LOGGER.debug("Creator :: properties_changed for action at address %s to %s"%(action.address, str(properties))) + def properties_changed(self, action): + LOGGER.debug("Creator :: properties_changed for action at address %s to %s"%(action.address)) address = action.address self._probe_mgr.update(address, action, is_editing=True) - def _update_error(self, exception): - pass - def _action_refresh_cb(self, widget, evt, action): """ Callback for refreshing properties values and notifying the property dialog of the new values. """ + # TODO : replace with update self._probe_mgr.uninstall(action.address, is_editing=True) return_cb = partial(self._action_installed_cb, action) @@ -351,7 +344,7 @@ class Creator(Object): self._overview.win.queue_draw() - def _cleanup_cb(self, *args, **kwargs): + def cleanup_cb(self, *args, **kwargs): """ Quit editing and cleanup interface artifacts. @@ -364,7 +357,8 @@ class Creator(Object): # TODO : Support quit cancellation - right now,every time we execute this, # we will forcibly end edition afterwards. It would be nice to keep creating - if kwargs.get('force', False): + if not kwargs.get('force', False): + # TODO : Move the dialog in the middle of the screen dialog = gtk.MessageDialog( parent=self._overview.win, flags=gtk.DIALOG_MODAL, @@ -579,8 +573,7 @@ class ToolBox(object): def _refresh_action_cb(self): if self._action is not None: - default_creator().properties_changed(self._action, self._action._props) - #self.__parent._creator._action_refresh_cb(None, None, self._action) + default_creator().properties_changed(self._action) # The purpose of this function is to reformat text, as current IconView # implentation does not insert carriage returns on long lines. diff --git a/tutorius/properties.py b/tutorius/properties.py index 85e8aa5..f273569 100644 --- a/tutorius/properties.py +++ b/tutorius/properties.py @@ -140,26 +140,8 @@ class TPropContainer(object): """ return deepcopy(self._props) - # Providing the hash methods necessary to use TPropContainers - # in a dictionary, according to their properties - def __hash__(self): - # many places we use containers as keys to store additional data. - # Since containers are mutable, there is a need for a hash function - # where the result is constant, so we can still lookup old instances. - return self.__id - def __eq__(self, e2): - return self.__id == e2.__id or \ - (isinstance(e2, type(self)) and self._props == e2._props) - - # Adding methods for pickling and unpickling an object with - # properties - def __getstate__(self): - return dict(id=self.__id, props=self._props.copy()) - - def __setstate__(self, dict): - self.__id = dict['id'] - self._props.update(dict['props']) + return (isinstance(e2, type(self)) and self._props == e2._props) class TutoriusProperty(object): """ diff --git a/tutorius/service.py b/tutorius/service.py index 11a94a5..1564339 100644 --- a/tutorius/service.py +++ b/tutorius/service.py @@ -3,6 +3,7 @@ import dbus from .engine import Engine from .dbustools import remote_call from .TProbe import ProbeManager +from .creator import Creator import logging LOGGER = logging.getLogger("sugar.tutorius.service") @@ -24,6 +25,8 @@ class Service(dbus.service.Object): self._probeMgr = ProbeManager() + Creator(self._probeMgr) + def start(self): """ Start the service itself """ -- cgit v0.9.1