Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src/sugar/tutorius/bundler.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/sugar/tutorius/bundler.py')
-rw-r--r--src/sugar/tutorius/bundler.py223
1 files changed, 131 insertions, 92 deletions
diff --git a/src/sugar/tutorius/bundler.py b/src/sugar/tutorius/bundler.py
index 34b3a12..f9a3911 100644
--- a/src/sugar/tutorius/bundler.py
+++ b/src/sugar/tutorius/bundler.py
@@ -27,9 +27,8 @@ import xml.dom.minidom
from sugar.tutorius import gtkutils, overlayer
from sugar.tutorius.core import Tutorial, State, FiniteStateMachine
+from sugar.tutorius.filters import *
from sugar.tutorius.actions import *
-import sugar.tutorius.filters
-#from sugar.tutorius.filters import EventFilter, TimerEvent, GtkWidgetEventFilter, GtkWidgetTypeFilter
from ConfigParser import SafeConfigParser
def _get_store_root():
@@ -132,47 +131,73 @@ class XMLSerializer(Serializer):
eventfiltersList = stateNode.appendChild(self._create_event_filters_node(state.get_event_filter_list(), doc))
return statesList
+ def _create_action_node(self, action, doc):
+ """
+ Takes a single action and transforms it into a xml node.
+
+ @param action A single action
+ @param doc The XML document root (used to create nodes only
+ @return A XML Node object with the Action tag name
+ """
+ actionNode = doc.createElement("Action")
+
+ # Write down just the name of the Action class as the Class
+ # property --
+ # Using .__class__ since type() doesn't have the same behavior
+ # with class derivating from object and class that don't
+ actionNode.setAttribute("Class", str(action.__class__))
+
+ if type(action) is DialogMessage:
+ actionNode.setAttribute("Message", action.message.value)
+ actionNode.setAttribute("PositionX", str(action.position.value[0]))
+ actionNode.setAttribute("PositionY", str(action.position.value[1]))
+ elif type(action) is BubbleMessage:
+ actionNode.setAttribute("Message", action.message.value)
+ actionNode.setAttribute("PositionX", str(action.position.value[0]))
+ actionNode.setAttribute("PositionY", str(action.position.value[1]))
+ actionNode.setAttribute("Tail_posX", str(action.tail_pos.value[0]))
+ actionNode.setAttribute("Tail_posY", str(action.tail_pos.value[1]))
+ # TO ADD : elif for each type of action
+ elif type(action) is WidgetIdentifyAction:
+ # Nothing else to save
+ pass
+ elif type(action) is ChainAction:
+ # Recusively write the contained actions - in the correct order
+ subActionsNode = self._create_action_list_node(action._actions, doc)
+ actionNode.appendChild(subActionsNode)
+ elif type(action) is DisableWidgetAction:
+ # Remember the target
+ actionNode.setAttribute("Target", action._target)
+ elif type(action) is TypeTextAction:
+ # Save the text and the widget
+ actionNode.setAttribute("Widget", action._widget)
+ actionNode.setAttribute("Text", action._text)
+ elif type(action) is ClickAction:
+ # Save the widget to click
+ actionNode.setAttribute("Widget", action._widget)
+ elif type(action) is OnceWrapper:
+ # Encapsulate the action in a OnceWrapper
+ subActionNode = self._create_action_node(action._action, doc)
+ actionNode.appendChild(subActionNode)
+
+ return actionNode
+
def _create_action_list_node(self, action_list, doc):
"""
Create and return a xml Node from a Action list.
+
+ @param action_list A list of actions
+ @param doc The XML document root (used to create new nodes only)
+ @return A XML Node object with the Actions tag name and a serie of
+ Action children
"""
actionsList = doc.createElement("Actions")
for action in action_list:
- actionNode = doc.createElement("Action")
+ # Create the action node
+ actionNode = self._create_action_node(action, doc)
+ # Append it to the list
actionsList.appendChild(actionNode)
- # Using .__class__ since type() doesn't have the same behavior
- # with class derivating from object and class that don't
- actionNode.setAttribute("Class", str(action.__class__))
-
- if type(action) is DialogMessage:
- actionNode.setAttribute("Message", action.message.value)
- actionNode.setAttribute("PositionX", action.position.value[0])
- actionNode.setAttribute("PositionY", str(action.position.value[1]))
- elif type(action) is BubbleMessage:
- actionNode.setAttribute("Message", action.message.value)
- actionNode.setAttribute("PositionX", str(action.position.value[0]))
- actionNode.setAttribute("PositionY", str(action.position.value[1]))
- actionNode.setAttribute("Tail_posX", str(action.tail_pos.value[0]))
- actionNode.setAttribute("Tail_posY", str(action.tail_pos.value[1]))
- # TODO : elif for each type of action
- elif type(action) is WidgetIdentifyAction:
- # Nothing else to save
- pass
- elif type(action) is ChainAction:
- # Recusively write the contained actions - in the correct order
- subActionsNode = self._create_actions_node(action._actions, doc)
- actionNode.appendChild(subActionsNode)
- elif type(action) is DisableWidgetAction:
- # Remember the target
- actionNode.setAttribute("Target", action._target)
- elif type(action) is TypeTextAction:
- # Save the text and the widget
- actionNode.setAttribute("Widget", action._widget)
- actionNode.setAttribute("Text", action._text)
- elif type(action) is ClickAction:
- # Save the widget to click
- actionNode.setAttribute("Widget", action._widget)
-
+
return actionsList
def _create_event_filters_node(self, event_filters, doc):
@@ -181,23 +206,26 @@ class XMLSerializer(Serializer):
"""
eventFiltersList = doc.createElement("EventFiltersList")
for event_f in event_filters:
- eventFilterNode = eventFiltersList.appendChild("EventFilter")
+ eventFilterNode = doc.createElement("EventFilter")
+ eventFiltersList.appendChild(eventFilterNode)
- # Using .__class__ since type() doesn't have the same behavior
+ # Write down just the name of the Action class as the Class
+ # property --
+ # using .__class__ since type() doesn't have the same behavior
# with class derivating from object and class that don't
eventFilterNode.setAttribute("Class", str(event_f.__class__))
# Write the name of the next state
eventFilterNode.setAttribute("NextState", event_f.next_state)
- if type(event_f) is sugar.tutorius.filters.TimerEvent:
+ if type(event_f) is TimerEvent:
eventFilterNode.setAttribute("Timeout_s", str(event_f._timeout))
- elif type(event_f) is sugar.tutorius.filters.GtkWidgetEventFilter:
+ elif type(event_f) is GtkWidgetEventFilter:
eventFilterNode.setAttribute("EventName", event_f._event_name)
eventFilterNode.setAttribute("ObjectId", event_f._object_id)
- elif type(event_f) is sugar.tutorius.filters.GtkWidgetTypeFilter:
+ elif type(event_f) is GtkWidgetTypeFilter:
eventFilterNode.setAttribute("ObjectId", event_f._object_id)
if event_f._strokes is not None:
eventFilterNode.setAttribute("Strokes", event_f._strokes)
@@ -295,26 +323,24 @@ class XMLSerializer(Serializer):
@param filters_elem An XML Element representing a list of event filters
"""
reformed_event_filters_list = []
- # item(0) because there is always only one <EventFilterList> tag in the xml file
- # so states_elem should always contain only one element
- event_filter_element_list = filters_elem.item(0).getElementsByTagName("EventFilter")
+ event_filter_element_list = filters_elem.getElementsByTagName("EventFilter")
new_event_filter = None
for event_filter in event_filter_element_list:
# Load the name of the next state for this filter
next_state = event_filter.getAttribute("NextState")
- if event_filter.getAttribute("Class") == str(sugar.tutorius.filters.TimerEvent):
+ if event_filter.getAttribute("Class") == str(TimerEvent):
timeout = int(event_filter.getAttribute("Timeout_s"))
new_event_filter = TimerEvent(next_state, timeout)
- elif event_filter.getAttribute("Class") == str(sugar.tutorius.filters.GtkWidgetEventFilter):
+ elif event_filter.getAttribute("Class") == str(GtkWidgetEventFilter):
# Get the event name and the object's ID
event_name = event_filter.getAttribute("EventName")
object_id = event_filter.getAttribute("ObjectId")
new_event_filter = GtkWidgetEventFilter(next_state, object_id, event_name)
- elif event_filter.getAttribute("Class") == str(sugar.tutorius.filters.GtkWidgetTypeFilter):
+ elif event_filter.getAttribute("Class") == str(GtkWidgetTypeFilter):
# Get the widget to write in and the text
object_id = event_filter.getAttribute("ObjectId")
if event_filter.hasAttribute("Text"):
@@ -325,10 +351,57 @@ class XMLSerializer(Serializer):
new_event_filter = GtkWidgetTypeFilter(next_state, object_id, strokes=strokes)
if new_event_filter is not None:
- reformed_event_filter.append(new_event_filter)
+ reformed_event_filters_list.append(new_event_filter)
return reformed_event_filters_list
+ def _load_xml_action(self, action):
+ """
+ Loads a single action from an Xml Action node.
+
+ @param action The Action XML Node to transform
+ object
+ @return The Action object of the correct type according to the XML
+ description
+ """
+ # TO ADD: an elif for each type of action
+ if action.getAttribute("Class") == str(DialogMessage):
+ message = action.getAttribute("Message")
+ positionX = int(action.getAttribute("PositionX"))
+ positionY = int(action.getAttribute("PositionY"))
+ position = [positionX, positionY]
+ return DialogMessage(message,position)
+ elif action.getAttribute("Class") == str(BubbleMessage):
+ message = action.getAttribute("Message")
+ positionX = int(action.getAttribute("PositionX"))
+ positionY = int(action.getAttribute("PositionY"))
+ position = [positionX, positionY]
+ tail_posX = action.getAttribute("Tail_posX")
+ tail_posY = action.getAttribute("Tail_posY")
+ tail_pos = [tail_posX, tail_posY]
+ return BubbleMessage(message,position,None,tail_pos)
+ elif action.getAttribute("Class") == str(WidgetIdentifyAction):
+ return WidgetIdentifyAction()
+ elif action.getAttribute("Class") == str(ChainAction):
+ # Load the subactions
+ subActionsList = self._load_xml_actions(action.getElementsByTagName("Actions")[0])
+ return ChainAction(subActionsList)
+ elif action.getAttribute("Class") == str(DisableWidgetAction):
+ # Get the target
+ targetName = action.getAttribute("Target")
+ return DisableWidgetAction(targetName)
+ elif action.getAttribute("Class") == str(TypeTextAction):
+ # Get the widget and the text to type
+ widget = action.getAttribute("Widget")
+ text = action.getAttribute("Text")
+
+ return TypeTextAction(widget, text)
+ elif action.getAttribute("Class") == str(ClickAction):
+ # Load the widget to click
+ widget = action.getAttribute("Widget")
+
+ return ClickAction(widget)
+
def _load_xml_actions(self, actions_elem):
"""
Transforms an Actions element into a list of instanciated Action.
@@ -336,48 +409,12 @@ class XMLSerializer(Serializer):
@param actions_elem An XML Element representing a list of Actions
"""
reformed_actions_list = []
- # item(0) because there is always only one <Actions> tag in the xml file
- # so states_elem should always contain only one element
- actions_element_list = actions_elem.item(0).getElementsByTagName("Action")
+ actions_element_list = actions_elem.getElementsByTagName("Action")
for action in actions_element_list:
- # TODO : elif for each type of action
- if action.getAttribute("Class") == str(DialogMessage):
- message = action.getAttribute("Message")
- positionX = int(action.getAttribute("PositionX"))
- positionY = int(action.getAttribute("PositionY"))
- position = [positionX, positionY]
- reformed_actions_list.append(DialogMessage(message,position))
- elif action.getAttribute("Class") == str(BubbleMessage):
- message = action.getAttribute("Message")
- positionX = int(action.getAttribute("PositionX"))
- positionY = int(action.getAttribute("PositionY"))
- position = [positionX, positionY]
- tail_posX = action.getAttribute("Tail_posX")
- tail_posY = action.getAttribute("Tail_posY")
- tail_pos = [tail_posX, tail_posY]
- reformed_actions_list.append(BubbleMessage(message,position,None,tail_pos))
- elif action.getAttribute("Class") == str(WidgetIdentifyAction):
- reformed_actions_list.append(WidgetIdentifyAction())
- elif action.getAttribute("Class") == str(ChainAction):
- # Load the subactions
- subActionsList = _load_xml_actions(action.getElementsByTagName("Actions"))
- reformed_actions_list.append(ChainAction(subActionsList))
- elif action.getAttribute("Class") == str(DisableWidgetAction):
- # Get the target
- targetName = action.getAttribute("Target")
- reformed_actions_list.append(DisableWidgetAction(targetName))
- elif action.getAttribute("Class") == str(TypeTextAction):
- # Get the widget and the text to type
- widget = action.getAttribute("Widget")
- text = action.getAttribute("Text")
-
- reformed_actions_list.append(TypeTextAction(widget, text))
- elif action.getAttribute("Class") == str(ClickAction):
- # Load the widget to click
- widget = action.getAttribute("Widget")
-
- reformed_actions_list.append(ClickAction(widget))
+ new_action = self._load_xml_action(action)
+
+ reformed_actions_list.append(new_action)
return reformed_actions_list
@@ -395,8 +432,10 @@ class XMLSerializer(Serializer):
for state in states_element_list:
stateName = state.getAttribute("Name")
- actions_list = self._load_xml_actions(state.getElementsByTagName("Actions"))
- event_filters_list = self._load_xml_event_filters(state.getElementsByTagName("EventFiltersList"))
+ # Using item 0 in the list because there is always only one
+ # Actions and EventFilterList element per State node.
+ actions_list = self._load_xml_actions(state.getElementsByTagName("Actions")[0])
+ event_filters_list = self._load_xml_event_filters(state.getElementsByTagName("EventFiltersList")[0])
reformed_state_list.append(State(stateName, actions_list, event_filters_list))
return reformed_state_list
@@ -425,12 +464,12 @@ class XMLSerializer(Serializer):
fsm.add_state(state)
# Load the actions on this FSM
- actions = self._load_xml_actions(fsm_elem.getElementsByTagName("FSMActions"))
+ actions = self._load_xml_actions(fsm_elem.getElementsByTagName("FSMActions")[0])
for action in actions:
fsm.add_action(action)
# Load the event filters
- events = self._load_xml_event_filters(fsm_elem.getElementsByTagName("EventFiltersList"))
+ events = self._load_xml_event_filters(fsm_elem.getElementsByTagName("EventFiltersList")[0])
for event in events:
fsm.add_event_filter(event)