Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xsrc/extensions/tutoriusremote.py80
-rw-r--r--tutorius/TProbe.py3
-rw-r--r--tutorius/properties.py19
3 files changed, 92 insertions, 10 deletions
diff --git a/src/extensions/tutoriusremote.py b/src/extensions/tutoriusremote.py
index 9bb4bfb..dfe6f37 100755
--- a/src/extensions/tutoriusremote.py
+++ b/src/extensions/tutoriusremote.py
@@ -21,20 +21,29 @@ creator from the Sugar frame.
"""
import gtk
+
from gettext import gettext as _
import gconf
import dbus
+import logging
+
from sugar.graphics.tray import TrayIcon
from sugar.graphics.palette import Palette
from sugar.graphics.xocolor import XoColor
+from sugar.graphics.combobox import ComboBox
from jarabe.frame.frameinvoker import FrameWidgetInvoker
+from jarabe.model.shell import get_model
from sugar.tutorius.creator import default_creator
+from sugar.tutorius.vault import Vault
+
_ICON_NAME = 'tutortool'
+LOGGER = logging.getLogger('remote')
+
class TutoriusRemote(TrayIcon):
FRAME_POSITION_RELATIVE = 102
@@ -61,14 +70,81 @@ class TPalette(Palette):
self._creator_item = gtk.MenuItem(_('Create a tutorial'))
self._creator_item.connect('activate', self._start_creator)
self._creator_item.show()
+
+ self._stop_creator_item = gtk.MenuItem(_('Stop creating tutorial'))
+ self._stop_creator_item.connect('activate', self._stop_creator)
+
+ self._tut_list_item = gtk.MenuItem(_('Show tutorials'))
+ self._tut_list_item.connect('activate', self._list_tutorials)
+ self._tut_list_item.show()
+
self.menu.append(self._creator_item)
+ self.menu.append(self._stop_creator_item)
+ self.menu.append(self._tut_list_item)
self.set_content(None)
def _start_creator(self, widget):
- default_creator().start_authoring(tutorial=None)
-
+ 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.hide()
+ self._stop_creator_item.show()
+ creator.start_authoring(tutorial=None)
+
+ def _stop_creator(self, widget):
+ # Close the creator but let the confirmation dialog appear
+ # if the user hasn't saved his tutorial
+ creator = default_creator()
+
+ if creator.is_authoring == False:
+ return
+
+ creator._cleanup_cb()
+
+ # If the creator was not actually closed
+ if creator.is_authoring == True:
+ return
+ # Switch back to start creator entry
+ self._stop_creator_item.hide()
+ self._creator_item.show()
+ def _list_tutorials(self, widget):
+ dlg = gtk.Dialog('Run a tutorial',
+ None,
+ gtk.DIALOG_MODAL,
+ (gtk.STOCK_OK, gtk.RESPONSE_ACCEPT,
+ gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT))
+ dlg.vbox.pack_start(gtk.Label(_('Which tutorial do you want to run?\n')))
+
+ activity = get_model().get_active_activity()
+
+ act_name = activity.get_activity_name()
+ tutorial_dict = Vault.list_available_tutorials(act_name)
+
+ # Build the combo box
+ combo = ComboBox()
+ for (tuto_name, tuto_guid) in tutorial_dict.items():
+ combo.append_item(tuto_name, tuto_guid)
+ dlg.vbox.pack_end(combo)
+ dlg.show_all()
+
+ result = dlg.run()
+ dlg.destroy()
+
+ if result == gtk.RESPONSE_ACCEPT:
+ row = combo.get_active_item()
+ if row:
+ guid = row[0]
+ name = row[1]
+ LOGGER.debug("TPalette :: Got message to launch tutorial %s with guid %s"%(str(name), str(guid)))
+
+ from sugar.tutorius.service import ServiceProxy
+ service = ServiceProxy()
+
+ service.launch(guid)
def setup(tray):
tray.add_device(TutoriusRemote(default_creator()))
diff --git a/tutorius/TProbe.py b/tutorius/TProbe.py
index 5b5cf8d..7021f80 100644
--- a/tutorius/TProbe.py
+++ b/tutorius/TProbe.py
@@ -25,9 +25,10 @@ import cPickle as pickle
from . import addon
+from . import properties
from .services import ObjectStore
-from .dbustools import save_args, ignore, logError
+from .dbustools import remote_call, save_args
import copy
"""
diff --git a/tutorius/properties.py b/tutorius/properties.py
index a462782..cc76748 100644
--- a/tutorius/properties.py
+++ b/tutorius/properties.py
@@ -19,6 +19,7 @@ TutoriusProperties have the same behaviour as python properties (assuming you
also use the TPropContainer), with the added benefit of having builtin dialog
prompts and constraint validation.
"""
+import uuid
from copy import copy, deepcopy
from .constraints import Constraint, \
@@ -60,6 +61,8 @@ class TPropContainer(object):
self._props[attr_name] = propinstance.validate(
copy(propinstance.default))
+ self.__id = hash(uuid.uuid4())
+
def __getattribute__(self, name):
"""
Process the 'fake' read of properties in the appropriate instance
@@ -128,21 +131,23 @@ class TPropContainer(object):
# Providing the hash methods necessary to use TPropContainers
# in a dictionary, according to their properties
def __hash__(self):
- #Return a hash of properties (key, value) sorted by key
- #We need to transform the list of property key, value lists into
- # a tuple of key, value tuples
- return hash(tuple(map(tuple,sorted(self._props.items(), cmp=lambda x, y: cmp(x[0], y[0])))))
+ # 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 isinstance(e2, type(self)) and self._props == e2._props
+ 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 self._props.copy()
+ return dict(id=self.__id, props=self._props.copy())
def __setstate__(self, dict):
- self._props.update(dict)
+ self.__id = dict['id']
+ self._props.update(dict['props'])
class TutoriusProperty(object):
"""