Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorC Neves <cn@goat.(none)>2007-06-12 13:31:22 (GMT)
committer C Neves <cn@goat.(none)>2007-06-12 13:31:22 (GMT)
commit030d7599b95d52dbf735de61b7dc7cd79c34d896 (patch)
tree77ed26268daa149c4f835a2be88d603b375cc8be
parent1c91b0f442d3e8b9804d4a8944307f38db549c22 (diff)
Updated to V1.1 second try:
Changed category names, added lesson plans on the game area, removed toolbar. Initial support for Journal resume. Some UI changes and tweaks. My Own Pictures is also a category now, which automagically keeps the images opened with 'My Own Picture' button. These user images are kept as links.
-rw-r--r--MANIFEST140
-rw-r--r--SliderPuzzleActivity.py126
-rw-r--r--SliderPuzzleUI.py317
-rw-r--r--SliderPuzzleWidget.py22
-rw-r--r--i18n.py17
-rw-r--r--i18n_misc_strings.py13
-rw-r--r--images/Animals/image_chmk_h250_w250_lg.gif (renamed from images/Ground Creatures/image_chmk_h250_w250_lg.gif)bin3786 -> 3786 bytes
-rw-r--r--images/Animals/image_djstf_h250_w411_lg.gif (renamed from images/Ground Creatures/image_djstf_h250_w411_lg.gif)bin6694 -> 6694 bytes
-rw-r--r--images/Animals/image_drti_h250_w322_lg.gif (renamed from images/Ground Creatures/image_drti_h250_w322_lg.gif)bin13408 -> 13408 bytes
-rw-r--r--images/Animals/image_howl_h250_w250_lg.gif (renamed from images/Ground Creatures/image_howl_h250_w250_lg.gif)bin3436 -> 3436 bytes
-rw-r--r--images/Animals/image_hsnr_h250_w421_lg.gif (renamed from images/Ground Creatures/image_hsnr_h250_w421_lg.gif)bin9005 -> 9005 bytes
-rw-r--r--images/Animals/image_justi_h250_w333_lg.gif (renamed from images/Ground Creatures/image_justi_h250_w333_lg.gif)bin34659 -> 34659 bytes
-rw-r--r--images/Animals/image_kili_h250_w387_lg.gif (renamed from images/Ground Creatures/image_kili_h250_w387_lg.gif)bin15268 -> 15268 bytes
-rw-r--r--images/Animals/image_lehf_h250_w250_lg.gif (renamed from images/Ground Creatures/image_lehf_h250_w250_lg.gif)bin1523 -> 1523 bytes
-rw-r--r--images/Animals/image_mdic_h250_w250_lg.gif (renamed from images/Ground Creatures/image_mdic_h250_w250_lg.gif)bin2811 -> 2811 bytes
-rw-r--r--images/Animals/image_mdwl_h250_w250_lg.gif (renamed from images/Ground Creatures/image_mdwl_h250_w250_lg.gif)bin1917 -> 1917 bytes
-rw-r--r--images/Animals/image_mrfg_h250_w333_lg.gif (renamed from images/Water Creatures/image_mrfg_h250_w333_lg.gif)bin5206 -> 5206 bytes
-rw-r--r--images/Animals/image_nimo_h250_w299_lg.gif (renamed from images/Ground Creatures/image_nimo_h250_w299_lg.gif)bin5384 -> 5384 bytes
-rw-r--r--images/Animals/image_skat_h250_w363_lg.gifbin0 -> 3880 bytes
-rw-r--r--images/Animals/thumb.gif (renamed from images/Ground Creatures/thumb.gif)bin369 -> 369 bytes
-rw-r--r--images/Birds/image_mbmg_h250_w250_lg.gif (renamed from images/Sky Creatures/image_mbmg_h250_w250_lg.gif)bin2808 -> 2808 bytes
-rw-r--r--images/Birds/image_oitn_h250_w250_lg.gif (renamed from images/Sky Creatures/image_oitn_h250_w250_lg.gif)bin8963 -> 8963 bytes
-rw-r--r--images/Birds/image_s1macaw_lg.gif (renamed from images/Ground Creatures/image_s1macaw_lg.gif)bin14943 -> 14943 bytes
-rw-r--r--images/Birds/thumb.gif (renamed from images/Sky Creatures/thumb.gif)bin376 -> 376 bytes
-rw-r--r--images/Ground Creatures/image_skat_h250_w363_lg.gifbin4318 -> 0 bytes
-rw-r--r--images/My Own Pictures/happy_pig.lnk1
-rw-r--r--images/My Own Pictures/img_150x190.lnk1
-rw-r--r--images/My Own Pictures/img_210x250.lnk1
-rw-r--r--images/My Own Pictures/img_500x50.lnk1
-rw-r--r--images/My Own Pictures/lourenco.lnk1
-rw-r--r--images/Places/image_smrr_h250_w371_lg.gifbin9999 -> 0 bytes
-rw-r--r--images/Places/thumb.gifbin635 -> 0 bytes
-rw-r--r--images/Sea Life/image_atlo_h250_w333_lg.gif (renamed from images/Water Creatures/image_atlo_h250_w333_lg.gif)bin6717 -> 6717 bytes
-rw-r--r--images/Sea Life/image_btfi_h250_w331_lg.gif (renamed from images/Places/image_btfi_h250_w331_lg.gif)bin4395 -> 4395 bytes
-rw-r--r--images/Sea Life/image_cal_h250_w165_lg.gif (renamed from images/Water Creatures/image_cal_h250_w165_lg.gif)bin1954 -> 1954 bytes
-rw-r--r--images/Sea Life/image_clor_h250_w250_lg.gif (renamed from images/Water Creatures/image_clor_h250_w250_lg.gif)bin2601 -> 2601 bytes
-rw-r--r--images/Sea Life/image_col_h250_w333_lg.gif (renamed from images/Water Creatures/image_col_h250_w333_lg.gif)bin5317 -> 5317 bytes
-rw-r--r--images/Sea Life/image_dan_h250_w424_lg.gif (renamed from images/Water Creatures/image_dan_h250_w424_lg.gif)bin14533 -> 14533 bytes
-rw-r--r--images/Sea Life/image_fsuw_h250_w250_lg.gif (renamed from images/Water Creatures/image_fsuw_h250_w250_lg.gif)bin5468 -> 5468 bytes
-rw-r--r--images/Sea Life/image_higc_h250_w250_lg.gif (renamed from images/Water Creatures/image_higc_h250_w250_lg.gif)bin2084 -> 2084 bytes
-rw-r--r--images/Sea Life/image_joc_h250_w333_lg.gif (renamed from images/Water Creatures/image_joc_h250_w333_lg.gif)bin4470 -> 4470 bytes
-rw-r--r--images/Sea Life/image_kitty_lg.gif (renamed from images/Water Creatures/image_kitty_lg.gif)bin5206 -> 5206 bytes
-rw-r--r--images/Sea Life/image_sxykitton_lg.gif (renamed from images/Water Creatures/image_sxykitton_lg.gif)bin2639 -> 2639 bytes
-rw-r--r--images/Sea Life/image_tsoc_h250_w421_lg.gif (renamed from images/Water Creatures/image_tsoc_h250_w421_lg.gif)bin10104 -> 10104 bytes
-rw-r--r--images/Sea Life/image_xxmrtwigxx_lg.gif (renamed from images/Water Creatures/image_xxmrtwigxx_lg.gif)bin2818 -> 2818 bytes
-rw-r--r--images/Sea Life/thumb.gif (renamed from images/Water Creatures/thumb.gif)bin475 -> 475 bytes
-rw-r--r--images/XO/image_XO.svg (renamed from images/XO's/image_XO.svg)0
-rw-r--r--images/XO/image_XO2.svg (renamed from images/XO's/image_XO2.svg)0
-rw-r--r--images/XO/image_XO3.svg (renamed from images/XO's/image_XO3.svg)0
-rw-r--r--images/XO/thumb.svg (renamed from images/XO's/thumb.svg)0
-rw-r--r--json.py310
-rw-r--r--lessons/Lesson 1/default.abw56
-rw-r--r--lessons/Lesson 2/default.abw56
-rw-r--r--lessons/Lesson 3/default.abw56
-rw-r--r--lessons/Lesson 4/default.abw56
-rw-r--r--lessons/lesson_plan.abw (renamed from texts/lesson_plan.abw)0
-rw-r--r--lessons/lesson_plan_pt.abw (renamed from texts/lesson_plan_pt.abw)0
-rw-r--r--locale/org.worldwideworkshop.olpc.SliderPuzzle.pot140
-rw-r--r--locale/pt/LC_MESSAGES/org.worldwideworkshop.olpc.SliderPuzzle.mobin1952 -> 2430 bytes
-rw-r--r--locale/pt/LC_MESSAGES/pt.po154
-rw-r--r--toolbar.py2
61 files changed, 1155 insertions, 315 deletions
diff --git a/MANIFEST b/MANIFEST
index f1993dd..7be3eaa 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -2,86 +2,70 @@ SliderPuzzleActivity.py
SliderPuzzleUI.py
SliderPuzzleWidget.py
i18n.py
+i18n_misc_strings.py
utils.py
-toolbar.py
-icons/brazil.png
-icons/china.svg
+json.py
icons/circle-check.svg
icons/circle-x.svg
-icons/czech_republic.svg
-icons/denmark.svg
-icons/finland.svg
-icons/france.svg
-icons/germany.svg
-icons/hungary.svg
-icons/italy.svg
-icons/japan.svg
-icons/netherlands.svg
-icons/norway.svg
-icons/poland.svg
-icons/portugal.png
-icons/russian_federation.svg
-icons/slovenia.svg
-icons/spain.png
-icons/sweden.svg
-icons/turkey.svg
-icons/united_kingdom.svg
-icons/united_states.png
+icons/logo.png
+images/Sea Life/image_dan_h250_w424_lg.gif
+images/Sea Life/image_atlo_h250_w333_lg.gif
+images/Sea Life/image_col_h250_w333_lg.gif
+images/Sea Life/image_joc_h250_w333_lg.gif
+images/Sea Life/image_xxmrtwigxx_lg.gif
+images/Sea Life/image_higc_h250_w250_lg.gif
+images/Sea Life/image_clor_h250_w250_lg.gif
+images/Sea Life/image_fsuw_h250_w250_lg.gif
+images/Sea Life/image_tsoc_h250_w421_lg.gif
+images/Sea Life/image_sxykitton_lg.gif
+images/Sea Life/image_cal_h250_w165_lg.gif
+images/Sea Life/image_kitty_lg.gif
+images/Sea Life/thumb.gif
+images/Sea Life/image_btfi_h250_w331_lg.gif
+images/Animals/image_mdic_h250_w250_lg.gif
+images/Animals/image_mdwl_h250_w250_lg.gif
+images/Animals/image_justi_h250_w333_lg.gif
+images/Animals/image_chmk_h250_w250_lg.gif
+images/Animals/image_howl_h250_w250_lg.gif
+images/Animals/image_mrfg_h250_w333_lg.gif
+images/Animals/image_hsnr_h250_w421_lg.gif
+images/Animals/image_kili_h250_w387_lg.gif
+images/Animals/image_djstf_h250_w411_lg.gif
+images/Animals/image_lehf_h250_w250_lg.gif
+images/Animals/image_drti_h250_w322_lg.gif
+images/Animals/thumb.gif
+images/Animals/image_nimo_h250_w299_lg.gif
+images/Animals/image_skat_h250_w363_lg.gif
+images/Birds/image_mbmg_h250_w250_lg.gif
+images/Birds/image_oitn_h250_w250_lg.gif
+images/Birds/image_s1macaw_lg.gif
+images/Birds/thumb.gif
+images/Sports/image_czvb_h250_w250_lg.gif
+images/Sports/image_skst_h250_w253_lg.gif
+images/Sports/image_sdkc_h250_w250_lg.gif
+images/Sports/image_bbof_h250_w250_lg.gif
+images/Sports/thumb.gif
+images/Sports/image_jppr_h250_w403_lg.gif
+images/Insects/image_evms_h250_w320_lg.gif
+images/Insects/image_bgim_h250_w250_lg.gif
+images/Insects/image_slls_h250_w333_lg.gif
+images/Insects/image_bbhs_h250_w250_lg.gif
+images/Insects/thumb.gif
+images/Insects/image_bmar_h250_w230_lg.gif
+images/Insects/image_atih_h250_w250_lg.gif
+images/Music/image_tbtn_h250_w365_lg.gif
+images/Music/image_2kgl_h250_w250_lg.gif
+images/Music/image_devin_music_w333_lg.gif
+images/Music/image_weird_h250_w384_lg.gif
+images/Music/image_wpwa_h250_w250_lg.gif
+images/Music/thumb.gif
+images/Space/image_esim_h250_w250_lg.gif
+images/Space/image_tral_h250_w404_lg.gif
+images/Space/thumb.gif
+images/Space/image_aisc_h250_w313_lg.gif
images/default_thumb.svg
-images/XO's/image_XO.svg
-images/XO's/image_XO2.svg
-images/XO's/image_XO3.svg
-images/XO's/thumb.svg
-images/jumbler starter pics/image_2kgl_h250_w250_lg.gif
-images/jumbler starter pics/image_aisc_h250_w313_lg.gif
-images/jumbler starter pics/image_atih_h250_w250_lg.gif
-images/jumbler starter pics/image_atlo_h250_w333_lg.gif
-images/jumbler starter pics/image_bbhs_h250_w250_lg.gif
-images/jumbler starter pics/image_bbof_h250_w250_lg.gif
-images/jumbler starter pics/image_bgim_h250_w250_lg.gif
-images/jumbler starter pics/image_bmar_h250_w230_lg.gif
-images/jumbler starter pics/image_btfi_h250_w331_lg.gif
-images/jumbler starter pics/image_cal_h250_w165_lg.gif
-images/jumbler starter pics/image_chmk_h250_w250_lg.gif
-images/jumbler starter pics/image_clor_h250_w250_lg.gif
-images/jumbler starter pics/image_col_h250_w333_lg.gif
-images/jumbler starter pics/image_czvb_h250_w250_lg.gif
-images/jumbler starter pics/image_dan_h250_w424_lg.gif
-images/jumbler starter pics/image_devin_music_w333_lg.gif
-images/jumbler starter pics/image_djstf_h250_w411_lg.gif
-images/jumbler starter pics/image_drti_h250_w322_lg.gif
-images/jumbler starter pics/image_esim_h250_w250_lg.gif
-images/jumbler starter pics/image_evms_h250_w320_lg.gif
-images/jumbler starter pics/image_fsuw_h250_w250_lg.gif
-images/jumbler starter pics/image_higc_h250_w250_lg.gif
-images/jumbler starter pics/image_howl_h250_w250_lg.gif
-images/jumbler starter pics/image_hsnr_h250_w421_lg.gif
-images/jumbler starter pics/image_joc_h250_w333_lg.gif
-images/jumbler starter pics/image_jppr_h250_w403_lg.gif
-images/jumbler starter pics/image_justi_h250_w333_lg.gif
-images/jumbler starter pics/image_kili_h250_w387_lg.gif
-images/jumbler starter pics/image_kitty_lg.gif
-images/jumbler starter pics/image_lehf_h250_w250_lg.gif
-images/jumbler starter pics/image_mbmg_h250_w250_lg.gif
-images/jumbler starter pics/image_mdic_h250_w250_lg.gif
-images/jumbler starter pics/image_mdwl_h250_w250_lg.gif
-images/jumbler starter pics/image_mrfg_h250_w333_lg.gif
-images/jumbler starter pics/image_nimo_h250_w299_lg.gif
-images/jumbler starter pics/image_oitn_h250_w250_lg.gif
-images/jumbler starter pics/image_s1macaw_lg.gif
-images/jumbler starter pics/image_sdkc_h250_w250_lg.gif
-images/jumbler starter pics/image_skat_h250_w363_lg.gif
-images/jumbler starter pics/image_skst_h250_w253_lg.gif
-images/jumbler starter pics/image_slls_h250_w333_lg.gif
-images/jumbler starter pics/image_smrr_h250_w371_lg.gif
-images/jumbler starter pics/image_sxykitton_lg.gif
-images/jumbler starter pics/image_tbtn_h250_w365_lg.gif
-images/jumbler starter pics/image_tral_h250_w404_lg.gif
-images/jumbler starter pics/image_tsoc_h250_w421_lg.gif
-images/jumbler starter pics/image_weird_h250_w384_lg.gif
-images/jumbler starter pics/image_wpwa_h250_w250_lg.gif
-images/jumbler starter pics/image_xxmrtwigxx_lg.gif
-images/jumbler starter pics/thumb.gif
locale/pt/LC_MESSAGES/pt.po
-texts/lesson_plan.abw
-texts/lesson_plan_pt.abw
+lessons/Lesson 1/default.abw
+lessons/Lesson 2/default.abw
+lessons/Lesson 3/default.abw
+lessons/Lesson 4/default.abw
diff --git a/SliderPuzzleActivity.py b/SliderPuzzleActivity.py
index 0b55c72..2001f8d 100644
--- a/SliderPuzzleActivity.py
+++ b/SliderPuzzleActivity.py
@@ -3,21 +3,141 @@ from gettext import gettext as _
from SliderPuzzleUI import SliderPuzzleUI
import logging, os
+import telepathy.client
+from telepathy import CHANNEL_TEXT_MESSAGE_TYPE_NORMAL, CHANNEL_TYPE_TEXT
+from sugar.presence import presenceservice
+
+
logger = logging.getLogger('sliderpuzzle-activity')
+import json
+
class SliderPuzzleActivity(Activity):
def __init__(self, handle):
+ print "1"
Activity.__init__(self, handle)
+ print "2"
logger.debug('Starting Slider Puzzle activity... %s' % str(get_bundle_path()))
os.chdir(get_bundle_path())
- self.connect('destroy', self.destroy_cb)
+ self.connect('destroy', self._destroy_cb)
self.set_title(_('SliderPuzzle'))
toolbox = ActivityToolbox(self)
self.set_toolbox(toolbox)
toolbox.show()
- game = SliderPuzzleUI(self)
+ print "3"
+ if getattr(self, 'game', None) is None:
+ self.game = SliderPuzzleUI(self)
+ print "4"
+
+ self.set_canvas(self.game)
+ self.game.show_all()
- def destroy_cb(self, data=None):
+# self.connect('shared', self._shared_cb)
+# self.pservice = presenceservice.get_instance()
+#
+# name, path = self.pservice.get_preferred_connection()
+# self.tp_conn_name = name
+# self.tp_conn_path = path
+# self.conn = telepathy.client.Connection(name, path)
+# self.initiating = None
+#
+# owner = self.pservice.get_owner()
+# self.owner = owner
+#
+# if self._shared_activity:
+# print "Joining activity from %s" % owner.get_property('nick')
+# # we are joining the activity
+# #self.buddies_panel.add_watcher(owner)
+# self.connect('joined', self._joined_cb)
+# self._shared_activity.connect('buddy-joined', self._buddy_joined_cb)
+# self._shared_activity.connect('buddy-left', self._buddy_left_cb)
+# if self.get_shared():
+# # oh, OK, we've already joined
+# self._joined_cb()
+#
+#
+# def _shared_cb(self, activity):
+# print 'My Connect activity was shared'
+#
+# print [x.get_property('nick') for x in self._shared_activity.get_joined_buddies()]
+#
+# self._shared_activity.connect('buddy-joined', self._buddy_joined_cb)
+# self._shared_activity.connect('buddy-left', self._buddy_left_cb)
+#
+# self._handle_sharing()
+#
+#
+# def _handle_sharing (self):
+# bus_name, conn_path, channel_paths = self._shared_activity.get_channels()
+# # Work out what our room is called and whether we have Tubes already
+# room = None
+# tubes_chan = None
+# text_chan = None
+# for channel_path in channel_paths:
+# channel = telepathy.client.Channel(bus_name, channel_path)
+# htype, handle = channel.GetHandle()
+# if htype == telepathy.HANDLE_TYPE_ROOM:
+# logger.debug('Found our room: it has handle#%d "%s"',
+# handle, self.conn.InspectHandles(htype, [handle])[0])
+# room = handle
+# ctype = channel.GetChannelType()
+# if ctype == telepathy.CHANNEL_TYPE_TUBES:
+# logger.debug('Found our Tubes channel at %s', channel_path)
+# tubes_chan = channel
+# elif ctype == telepathy.CHANNEL_TYPE_TEXT:
+# logger.debug('Found our Text channel at %s', channel_path)
+# text_chan = channel
+# print room
+# print tubes_chan
+# print text_chan
+#
+# self.text_chan = text_chan
+# self.text_chan[CHANNEL_TYPE_TEXT].connect_to_signal('Received', self._tc_received_cb)
+#
+# def _tc_received_cb (self, id, timestamp, sender, type, flags, text):
+# print "received",id,timestamp,sender,type,flags,text
+#
+# def _joined_cb(self, activity):
+# print 'joined a remote activity'
+# self._handle_sharing()
+# self.text_chan[CHANNEL_TYPE_TEXT].Send(CHANNEL_TEXT_MESSAGE_TYPE_NORMAL, "Ping")
+#
+#
+# def _buddy_joined_cb (self, activity, buddy):
+# print "buddy '%s' joined" % buddy.get_property('nick')
+#
+# def _buddy_left_cb (self, activity, buddy):
+# print "buddy '%s' left" % buddy,get_property('nick')
+
+ def _destroy_cb(self, data=None):
return True
+
+ def read_file(self, file_path):
+ import traceback
+ traceback.print_stack()
+ print "A"
+ f = open(file_path, 'r')
+ try:
+ session_data = f.read()
+ finally:
+ f.close()
+ logging.debug('Trying to set session: %s.' % session_data)
+ if getattr(self, 'game', None) is None:
+ self.game = SliderPuzzleUI(self)
+ self.game._thaw(json.read(session_data))
+
+ def write_file(self, file_path):
+ session_data = json.write(self.game._freeze())
+
+ if self.game.thumb.get_filename:
+ self.metadata['preview'] = self.game.thumb.get_category_name()
+ else:
+ self.metadata['preview'] = ''
+ f = open(file_path, 'w')
+ try:
+ f.write(session_data)
+ finally:
+ f.close()
+
diff --git a/SliderPuzzleUI.py b/SliderPuzzleUI.py
index f76b269..657642f 100644
--- a/SliderPuzzleUI.py
+++ b/SliderPuzzleUI.py
@@ -28,8 +28,10 @@ pygtk.require('2.0')
import gtk, gobject, pango
from utils import load_image
-from toolbar import SliderToolbar
+#from toolbar import SliderToolbar
from i18n import LanguageComboBox
+from abiword import Canvas
+import locale
import logging
from glob import glob
@@ -56,9 +58,9 @@ BORDER_ALL = BORDER_VERTICAL | BORDER_HORIZONTAL
BORDER_ALL_BUT_BOTTOM = BORDER_HORIZONTAL | BORDER_TOP
BORDER_ALL_BUT_LEFT = BORDER_VERTICAL | BORDER_RIGHT
-SLICE_BTN_WIDTH = 40
+SLICE_BTN_WIDTH = 50
-# Colors from the Rich's UI design
+# Colors from Rich's UI design
COLOR_FRAME_OUTER = "#B7B7B7"
COLOR_FRAME_GAME = "#FF0099"
@@ -140,24 +142,27 @@ class BorderFrame (gtk.EventBox):
del self.stack[-1]
self.inner.add(self.stack[-1])
+ def get_child (self):
+ return self.inner.child
+
def get_allocation (self):
return self.inner.get_allocation()
class TimerWidget (gtk.HBox):
- def __init__ (self, bg_color="#DD4040", fg_color="#4444FF"):
+ def __init__ (self, bg_color="#DD4040", fg_color="#4444FF", lbl_color="#DD4040"):
gtk.HBox.__init__(self)
#spacer = gtk.Label()
#spacer.set_size_request(20, -1)
#self.counter = BorderFrame(size=1, bg_color=bg_color, border_color=border_color)
self.counter = gtk.EventBox()
self.counter.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(bg_color))
- self.counter.set_size_request(80, -1)
+ self.counter.set_size_request(120, -1)
hb = gtk.HBox()
self.counter.add(hb)
#self.pack_start(spacer, False)
self.lbl_time = gtk.Label()
- self.lbl_time.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(bg_color))
+ self.lbl_time.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(lbl_color))
self.pack_start(self.lbl_time, False)
self.time_label = gtk.Label("--:--")
self.time_label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(fg_color))
@@ -226,17 +231,46 @@ class TimerWidget (gtk.HBox):
self.time_label.set_text("%i:%0.2i" % (t/60, t%60))
return True
+ def _freeze (self):
+ return (self.start_time, time(), self.finished, self.timer_id is None)
+
+ def _thaw (self, obj):
+ self.start_time, t, finished, stopped = obj
+ if self.start_time is not None:
+ if not stopped:
+ self.start_time = t - self.start_time
+ self.start()
+ return
+ self.start_time = time() - self.start_time
+ self.do_tick()
+ self.stop(finished)
+
class CategoryDirectory (object):
def __init__ (self, path, width=-1, height=-1):
self.path = path
if os.path.isdir(path):
- self.images = glob(os.path.join(path, "image_*"))
- self.images.sort()
+ self.gather_images()
else:
self.images = [path]
self.set_thumb_size(32, 32)
self.set_image_size(width, height)
self.filename = None
+ self.name = os.path.basename(path)
+
+ def gather_images (self):
+ """ Lists all images in the selected path as per the wildcard expansion of 'image_*'.
+ Adds all linked images from files (*.lnk) """
+ self.images = []
+ links = glob(os.path.join(self.path, "*.lnk"))
+ for link in links:
+ fpath = file(link).readlines()[0].strip()
+ if os.path.isfile(fpath) and not (fpath in self.images):
+ self.images.append(fpath)
+ else:
+ os.remove(link)
+ self.images.extend(glob(os.path.join(self.path, "image_*")))
+ self.images.sort()
+
def set_image_size (self, w, h):
self.width = w
@@ -247,6 +281,12 @@ class CategoryDirectory (object):
self.theight = h
self.thumb = self._get_category_thumb()
+ def get_image (self, name):
+ if not len(self.images) or name is None or name not in self.images:
+ return None
+ self.filename = name
+ return load_image(self.filename, self.width, self.height)
+
def get_next_image (self):
if not len(self.images):
return None
@@ -257,8 +297,7 @@ class CategoryDirectory (object):
pos += 1
if pos >= len(self.images):
pos = 0
- self.filename = self.images[pos]
- return load_image(self.images[pos], self.width, self.height)
+ return self.get_image(self.images[pos])
def get_previous_image (self):
if not len(self.images):
@@ -270,8 +309,7 @@ class CategoryDirectory (object):
pos -= 1
if pos < 0:
pos = len(self.images) - 1
- self.filename = self.images[pos]
- return load_image(self.images[pos], self.width, self.height)
+ return self.get_image(self.images[pos])
def has_images (self):
return len(self.images) > 0
@@ -285,7 +323,7 @@ class CategoryDirectory (object):
def _get_category_thumb (self):
if os.path.isdir(self.path):
thumbs = glob(os.path.join(self.path, "thumb.*"))
- thumbs.extend(glob(os.path.join("..", os.path.join(self.path, "default_thumb.*"))))
+ thumbs.extend(glob(os.path.join(self.path, os.path.join("..", "default_thumb.*"))))
thumbs = filter(lambda x: os.path.exists(x), thumbs)
thumbs.append(None)
else:
@@ -298,10 +336,11 @@ class ImageSelectorWidget (gtk.Table):
'image_press' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),}
def __init__ (self, width=-1, height=-1, frame_color=None):
- gtk.Table.__init__(self, 2,4,False)
+ gtk.Table.__init__(self, 2,5,False)
self.width = width
self.height = height
self.image = gtk.Image()
+ self.myownpath = None
img_box = BorderFrame(border_color=frame_color)
img_box.add(self.image)
img_box.set_border_width(5)
@@ -318,7 +357,7 @@ class ImageSelectorWidget (gtk.Table):
self.cat_thumb.set_size_request(32,32)
cteb.add(self.cat_thumb)
cteb.connect('button_press_event', self.emit_cat_pressed)
- self.attach(cteb, 2,3,1,2,0,0)
+ self.attach(cteb, 2,3,1,2,0,0,xpadding=10)
br = gtk.Button()
br.add(gtk.Arrow(gtk.ARROW_RIGHT, gtk.SHADOW_IN))
@@ -329,6 +368,12 @@ class ImageSelectorWidget (gtk.Table):
self.show_all()
self.image.set_size_request(width, height)
+ def set_myownpath (self, path):
+ """ Sets the path to My Own Pictures storage, so we know where to add links to new pictures """
+ if not os.path.exists(path):
+ os.mkdir(path)
+ self.myownpath = path
+
def emit_cat_pressed (self, *args):
self.emit('category_press')
return True
@@ -340,6 +385,9 @@ class ImageSelectorWidget (gtk.Table):
def has_image (self):
return self.category.has_image()
+ def get_category_name (self):
+ return self.category.name
+
def get_filename (self):
return self.category.filename
@@ -360,11 +408,31 @@ class ImageSelectorWidget (gtk.Table):
def load_image(self, filename, force_filename=False):
""" Loads an image from the file """
- self.category = CategoryDirectory(filename, self.width, self.height)
- self.next()
+ if self.myownpath is not None and os.path.isdir(self.myownpath):
+ name = os.path.splitext(os.path.basename(filename))[0]
+ while os.path.exists(os.path.join(self.myownpath, '%s.lnk' % name)):
+ name = name + '_'
+ f = file(os.path.join(self.myownpath, '%s.lnk' % name), 'w')
+ f.write(filename)
+ f.close()
+ self.category = CategoryDirectory(self.myownpath, self.width, self.height)
+ self.image.set_from_pixbuf(self.category.get_image(filename))
+ else:
+ self.category = CategoryDirectory(filename, self.width, self.height)
+ self.next()
self.cat_thumb.set_from_pixbuf(self.category.thumb)
return self.image.get_pixbuf() is not None
+ def _freeze (self):
+ """ returns a json writable object representation capable of being used to restore our current status """
+ return {'image_dir': self.get_image_dir(),
+ 'filename': self.get_filename()}
+
+ def _thaw (self, obj):
+ """ retrieves a frozen status from a python object, as per _freeze """
+ self.set_image_dir(obj.get('image_dir', None))
+ self.image.set_from_pixbuf(self.category.get_image(obj.get('filename', None)))
+
class CategorySelector (gtk.ScrolledWindow):
__gsignals__ = {'selected' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (str,))}
@@ -435,8 +503,34 @@ class CategorySelector (gtk.ScrolledWindow):
tv, it = tree.get_selection().get_selected()
self.emit("selected", tv.get_value(it,0))
-class SliderPuzzleUI:
+class LessonPlanWidget (gtk.Notebook):
+ def __init__ (self):
+ super(LessonPlanWidget, self).__init__()
+ lessons = filter(lambda x: os.path.isdir(os.path.join('lessons', x)), os.listdir('lessons'))
+ lessons.sort()
+ for lesson in lessons:
+ self._load_lesson(os.path.join('lessons', lesson), _(lesson))
+
+ def _load_lesson (self, path, name):
+ code, encoding = locale.getdefaultlocale()
+ canvas = Canvas()
+ canvas.show()
+ files = map(lambda x: os.path.join(path, '%s.abw' % x),
+ ('_'+code.lower(), '_'+code.split('_')[0].lower(), 'default'))
+ files = filter(lambda x: os.path.exists(x), files)
+ try:
+ canvas.load_file('file://%s/%s' % (os.getcwd(), files[0]), 'text/plain')
+ except:
+ canvas.load_file('file://%s/%s' % (os.getcwd(), files[0]))
+ canvas.view_online_layout()
+ canvas.zoom_width()
+ canvas.set_show_margin(False)
+ self.append_page(canvas, gtk.Label(name))
+
+
+class SliderPuzzleUI (gtk.Table):
def __init__(self, parent):
+ super(SliderPuzzleUI, self).__init__(3,3,False)
# Add our own icons here, needed for the translation flags
theme = gtk.icon_theme_get_default()
theme.append_search_path(os.path.join(os.getcwd(), 'icons'))
@@ -448,23 +542,9 @@ class SliderPuzzleUI:
self.labels_to_translate = []
# Basic window settings
- self.window = parent
-
- if _inside_sugar:
- toolbox = activity.ActivityToolbox(parent)
- toolbar = SliderToolbar()
- toolbox.add_toolbar(_('Slider Puzzle Toolbar'), toolbar)
- toolbar.show()
- parent.set_toolbox(toolbox)
- toolbox.show()
- else:
- import gettext
- gettext.bindtextdomain('org.worldwideworkshop.olpc.SliderPuzzle', 'locale')
- gettext.textdomain('org.worldwideworkshop.olpc.SliderPuzzle')
+ self._parent = parent
bgcolor = gtk.gdk.color_parse("#DDDD40")
-
-
# The containers we will use
outer_box = BorderFrame(border_color=COLOR_FRAME_OUTER)
inner_table = gtk.Table(2,2,False)
@@ -473,7 +553,7 @@ class SliderPuzzleUI:
outer_box.add(inner_table)
inner_table.attach(controls_vbox, 0,1,0,1)
- inner_table.attach(self.game_box, 1,2,0,1,0,0)
+ inner_table.attach(self.game_box, 1,2,0,1,1,1)
# Logo image
img_logo = gtk.Image()
@@ -494,25 +574,23 @@ class SliderPuzzleUI:
# Slice buttons
cutter = gtk.HBox(False, 8)
cutter.pack_start(gtk.Label(), True)
- self.btn_9 = prepare_btn(gtk.ToggleButton("9"))
- self.btn_9.set_size_request(SLICE_BTN_WIDTH, -1)
+ self.btn_9 = prepare_btn(gtk.ToggleButton("9"),SLICE_BTN_WIDTH)
self.btn_9.set_active(True)
self.btn_9.connect("clicked", self.set_nr_pieces, 9)
cutter.pack_start(self.btn_9, False, False)
- self.btn_12 = prepare_btn(gtk.ToggleButton("12"))
+ self.btn_12 = prepare_btn(gtk.ToggleButton("12"), SLICE_BTN_WIDTH)
self.btn_12.connect("clicked", self.set_nr_pieces, 12)
- self.btn_12.set_size_request(SLICE_BTN_WIDTH, -1)
cutter.pack_start(self.btn_12, False, False)
- self.btn_16 = prepare_btn(gtk.ToggleButton("16"))
+ self.btn_16 = prepare_btn(gtk.ToggleButton("16"), SLICE_BTN_WIDTH)
self.btn_16.connect("clicked", self.set_nr_pieces, 16)
- self.btn_16.set_size_request(SLICE_BTN_WIDTH, -1)
cutter.pack_start(self.btn_16, False, False)
cutter.pack_start(gtk.Label(), True)
controls_area_1_box.pack_start(cutter, True)
# The image selector with thumbnail
- self.thumb = ImageSelectorWidget(200, 200, frame_color=COLOR_FRAME_THUMB)
+ self.thumb = ImageSelectorWidget(180, 180, frame_color=COLOR_FRAME_THUMB)
self.thumb.set_image_dir("images")
+ self.thumb.set_myownpath("images/My Own Pictures")
self.thumb.connect("category_press", self.do_select_category)
self.thumb.connect("image_press", self.set_nr_pieces, None)
controls_area_1_box.pack_start(self.thumb, False)
@@ -530,10 +608,10 @@ class SliderPuzzleUI:
self.labels_to_translate.append((self.btn_solve, _("Solve")))
self.btn_solve.connect("clicked", self.do_solve)
btn_box.attach(self.btn_solve, 1,2,0,1,0,0)
- self.btn_jumble = prepare_btn(gtk.Button(" "), 200)
- self.labels_to_translate.append((self.btn_jumble, _("Jumble")))
- self.btn_jumble.connect("clicked", self.do_jumble)
- btn_box.attach(self.btn_jumble, 1,2,1,2,0,0)
+ self.btn_shuffle = prepare_btn(gtk.Button(" "), 200)
+ self.labels_to_translate.append((self.btn_shuffle, _("Shuffle")))
+ self.btn_shuffle.connect("clicked", self.do_shuffle)
+ btn_box.attach(self.btn_shuffle, 1,2,1,2,0,0)
self.btn_add = prepare_btn(gtk.Button(" "), 200)
self.labels_to_translate.append((self.btn_add, _("My Own Picture")))
self.btn_add.connect("clicked", self.do_add_image)
@@ -554,10 +632,11 @@ class SliderPuzzleUI:
inner_table.attach(controls_area_2, 0,1,1,2)
# The actual game widget
- self.game = SliderPuzzleWidget(9, 480, 480)
+ self.game = SliderPuzzleWidget(9, 500, 500)
+ self.game.show()
self.game.connect("solved", self.do_solve)
- self.window.connect("key_press_event",self.game.process_key)
- self.window.connect("key_press_event",self.process_key)
+ self._parent.connect("key_press_event",self.game.process_key)
+ self._parent.connect("key_press_event",self.process_key)
self.game_box.add(self.game)
# The timer widget and lesson plans
@@ -566,7 +645,9 @@ class SliderPuzzleUI:
border_color=COLOR_FRAME_CONTROLS)
vbox = gtk.VBox(False)
btn_box = gtk.HBox(False)
- self.timer = TimerWidget(bg_color=COLOR_BG_BUTTONS[0][1], fg_color=COLOR_FG_BUTTONS[0][1])
+ self.timer = TimerWidget(bg_color=COLOR_BG_BUTTONS[0][1],
+ fg_color=COLOR_FG_BUTTONS[0][1],
+ lbl_color=COLOR_BG_BUTTONS[1][1])
#self.timer.modify_bg(gtk.STATE_NORMAL, bgcolor)
self.timer.set_border_width(3)
self.labels_to_translate.append((self.timer, _("Time: ")))
@@ -574,78 +655,18 @@ class SliderPuzzleUI:
btn_box.pack_start(gtk.Label(), True)
self.btn_lesson = prepare_btn(gtk.Button(" "))
- self.labels_to_translate.append((self.btn_lesson, _("Lesson Plan")))
+ self.labels_to_translate.append([self.btn_lesson, _("Lesson Plan")])
+ self.btn_lesson.connect("clicked", self.do_lesson_plan)
btn_box.pack_start(self.btn_lesson, False, padding=8)
vbox.pack_start(btn_box, padding=8)
controls_area_3.add(vbox)
inner_table.attach(controls_area_3, 1,2,1,2)
-
-
- ## Buttons for selecting the number of pieces
- #cutter = gtk.VBox()
- #self.btn_9 = gtk.ToggleButton("9")
- #self.btn_9.set_size_request(50,-1)
- #self.btn_9.set_active(True)
- #self.btn_9.connect("clicked", self.set_nr_pieces, 9)
- #cutter.add(self.btn_9)
- #self.btn_12 = gtk.ToggleButton("12")
- #self.btn_12.connect("clicked", self.set_nr_pieces, 12)
- #cutter.add(self.btn_12)
- #self.btn_16 = gtk.ToggleButton("16")
- #self.btn_16.connect("clicked", self.set_nr_pieces, 16)
- #cutter.add(self.btn_16)
- #
- ## Thumb box has both the image selector and the number of pieces buttons
- #thumb_box = gtk.Table(1,2)
- #thumb_box.attach(self.thumb, 0,1,0,1)
- #thumb_box.attach(cutter,1,2,0,1,0,0)
- #
- # The bottom left buttons
- #buttons_box = BorderFrame(BORDER_TOP)
- #buttons_box.modify_bg(gtk.STATE_NORMAL, bgcolor)
- #inner_buttons_box = gtk.VBox(False, 5)
- #inner_buttons_box.set_border_width(10)
-
-
-
- #inner_buttons_box.add(self.btn_jumble)
- #buttons_box.add(inner_buttons_box)
- #
- #
- ## Everything on the left side of the game widget goes here
- #event_controls_box = gtk.EventBox()
- #event_controls_box.modify_bg(gtk.STATE_NORMAL, bgcolor)
- #controls_box = gtk.VBox(False, 5)
- #
- #controls_box.pack_start(img_logo)
- #
- #
- #controls_box.pack_start(self.timer, False, False)
- #controls_box.add(thumb_box)
- #controls_box.add(buttons_box)
- #event_controls_box.add(controls_box)
- ## This is the horizontal container that holds everything
- #wrapping_box = gtk.HBox()
- #wrapping_box.add(event_controls_box)
-
- #wrapping_box.add(self.game_box)
- ## Put a border around the whole thing
- #inner = BorderFrame(border_color="#B7B7B7")
- #inner.add(wrapping_box)
-
# This has the sole purpose of centering the widget on screen
- outter = gtk.Table(3,3,False)
- outter.attach(gtk.Label(), 0,3,0,1)
- outter.attach(outer_box, 1,2,1,2,0,0)
- outter.attach(gtk.Label(), 0,3,2,3)
+ self.attach(gtk.Label(), 0,3,0,1)
+ self.attach(outer_box, 1,2,1,2,0,0)
+ self.attach(gtk.Label(), 0,3,2,3)
- if _inside_sugar:
- self.window.set_canvas(outter)
- else:
- self.window.add(outter)
-
- self.window.show_all()
self.do_select_category(self)
# Push the gettext translator into the global namespace
@@ -653,21 +674,13 @@ class SliderPuzzleUI:
lang_combo.connect('changed', self.do_select_language)
lang_combo.install()
self.do_select_language(lang_combo)
- if _inside_sugar:
- toolbar.set_language_callback(self.do_select_language)
- #self.do_select_language(self.tb_lang_select)
- pass
- else:
- _ = gettext.gettext
- self.refresh_labels(True)
- #self.timer.start()
def do_select_language (self, combo, *args):
self.refresh_labels()
def refresh_labels (self, first_time=False):
logging.debug(str(_))
- self.window.set_title(_("Slider Puzzle Activity"))
+ self._parent.set_title(_("Slider Puzzle Activity"))
for lbl in self.labels_to_translate:
if isinstance(lbl[0], gtk.Button):
lbl[0].get_child().set_label(_(lbl[1]))
@@ -675,7 +688,11 @@ class SliderPuzzleUI:
lbl[0].set_label(_(lbl[1]))
if not self.game.get_parent() and not first_time:
self.game_box.pop()
- self.do_select_category(self)
+ if isinstance(self.get_box.get_child(), LessonPlanWidget):
+ m = do_lesson_plan
+ else:
+ m = do_select_category
+ m(self)
def set_nr_pieces (self, btn, nr_pieces=None):
if isinstance(btn, gtk.ToggleButton):
@@ -696,7 +713,7 @@ class SliderPuzzleUI:
if b is not btn:
b.set_active(False)
- def do_jumble (self, *args, **kwargs):
+ def do_shuffle (self, *args, **kwargs):
if self.thumb.has_image():
if not self.game.get_parent():
self.game_box.pop()
@@ -717,7 +734,7 @@ class SliderPuzzleUI:
#self.game_box.pop()
else:
if self.game.get_parent():
- s = CategorySelector("images", _("Select Image Category"), self.thumb.get_image_dir())
+ s = CategorySelector("images", _("Choose a Subject"), self.thumb.get_image_dir())
s.connect("selected", self.do_select_category)
s.show()
self.game_box.push(s)
@@ -730,29 +747,55 @@ class SliderPuzzleUI:
imgfilter = gtk.FileFilter()
imgfilter.set_name(_("Image Files"))
imgfilter.add_mime_type('image/*')
- fd = gtk.FileChooserDialog(title=_("Select Image File"), parent=self.window, action=gtk.FILE_CHOOSER_ACTION_OPEN,
+ fd = gtk.FileChooserDialog(title=_("Select Image File"), parent=self._parent,
+ action=gtk.FILE_CHOOSER_ACTION_OPEN,
buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
+
fd.set_current_folder(os.path.expanduser("~/"))
fd.set_modal(True)
fd.add_filter(imgfilter)
fd.connect("response", self.do_add_image)
+ fd.resize(800,600)
fd.show()
else:
if response == gtk.RESPONSE_ACCEPT:
if self.thumb.load_image(widget.get_filename()):
- self.do_jumble()
+ self.do_shuffle()
else:
- err = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK,
+ err = gtk.MessageDialog(self._parent, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK,
_("Not a valid image file"))
err.run()
err.destroy()
return
widget.destroy()
+ def do_lesson_plan (self, btn):
+ if isinstance(self.game_box.get_child(), LessonPlanWidget):
+ self.game_box.pop()
+ else:
+ s = LessonPlanWidget()
+ s.connect('parent-set', self.do_lesson_plan_reparent)
+ s.show_all()
+ self.game_box.push(s)
+
+ def do_lesson_plan_reparent (self, widget, oldparent):
+ if widget.parent is None:
+ for i in range(len(self.labels_to_translate)):
+ if self.labels_to_translate[i][0] == self.btn_lesson:
+ self.labels_to_translate[i][1] = "Lesson Plan"
+ break
+ self.btn_lesson.get_child().set_label(_("Lesson Plan"))
+ else:
+ for i in range(len(self.labels_to_translate)):
+ if self.labels_to_translate[i][0] == self.btn_lesson:
+ self.labels_to_translate[i][1] = "Close Lesson"
+ break
+ self.btn_lesson.get_child().set_label(_("Close Lesson"))
+
def process_key (self, w, e):
""" The callback for key processing. The button shortcuts are all defined here. """
k = gtk.gdk.keyval_name(e.keyval)
- if not isinstance(self.window.get_focus(), gtk.Editable):
+ if not isinstance(self._parent.get_focus(), gtk.Editable):
if k == '1':
self.btn_9.clicked()
return True
@@ -783,9 +826,21 @@ class SliderPuzzleUI:
if k in ('Escape', 'q'):
gtk.main_quit()
return True
- #logging.debug("%s %s %s" % (str(self.window.get_focus()), str(isinstance(self.window.get_focus(), gtk.Editable)), str(k)))
+ #logging.debug("%s %s %s" % (str(self._parent.get_focus()), str(isinstance(self.window.get_focus(), gtk.Editable)), str(k)))
return False
+ def _freeze (self):
+ """ returns a json writable object representation capable of being used to restore our current status """
+ return (self.thumb._freeze(), self.game._freeze(), self.game.get_nr_pieces(), self.timer._freeze())
+
+ def _thaw (self, obj):
+ """ retrieves a frozen status from a python object, as per _freeze """
+ self.thumb._thaw(obj[0])
+ self.game.load_image(self.thumb.get_filename())
+ self.set_nr_pieces(None, obj[2])
+ self.game._thaw(obj[1])
+ self.timer._thaw(obj[3])
+
def main():
win = gtk.Window(gtk.WINDOW_TOPLEVEL)
t = SliderPuzzleUI(win)
diff --git a/SliderPuzzleWidget.py b/SliderPuzzleWidget.py
index a63e8aa..8b4eef9 100644
--- a/SliderPuzzleWidget.py
+++ b/SliderPuzzleWidget.py
@@ -97,6 +97,12 @@ class MatrixPosition (object):
def clone (self):
return MatrixPosition(self.rowsize, self.colsize, self.x, self.y)
+
+ def _freeze (self):
+ return (self.rowsize, self.colsize, self.x, self.y)
+
+ def _thaw (self, obj):
+ self.rowsize, self.colsize, self.x, self.y = obj
class SliderPuzzleMap (object):
@@ -314,6 +320,13 @@ class SliderPuzzleMap (object):
def __call__ (self):
self.debug_map()
+ def _freeze (self):
+ return (self.pieces_map, self.hole_pos._freeze())
+
+ def _thaw (self, obj):
+ self.pieces_map = obj[0]
+ self.hole_pos._thaw(obj[1])
+
###
# Widget Definition
@@ -442,6 +455,15 @@ class SliderPuzzleWidget (gtk.Table):
self.attach(self.image, 0,1,0,1)
self.image.show()
+ def _freeze (self):
+ """ returns a json writable object representation capable of being used to restore our current status """
+ return self.jumbler._freeze()
+
+ def _thaw (self, obj):
+ """ retrieves a frozen status from a python object, as per _freeze """
+ self.jumbler._thaw(obj)
+ self.full_refresh()
+
def _test():
import doctest
doctest.testmod()
diff --git a/i18n.py b/i18n.py
index f16a844..cd6dfd3 100644
--- a/i18n.py
+++ b/i18n.py
@@ -1,5 +1,4 @@
-#!/usr/bin/env python
-
+#!/usr/bin/env python
# -*- coding: utf-8 -*-
# This program is free software; you can redistribute it and/or modify
@@ -146,3 +145,17 @@ class LanguageComboBox (gtk.ComboBox):
self.set_active(0)
# Allow for other callbacks
return False
+
+###
+def gather_other_translations ():
+ from glob import glob
+ entries = filter(lambda x: os.path.isdir(x), glob('images/*'))
+ entries.extend(filter(lambda x: os.path.isdir(x), glob('lessons/*')))
+ entries = map(lambda x: os.path.basename(x), entries)
+ f = file('i18n_misc_strings', 'w')
+ for e in entries:
+ f.write('_("%s")\n' % e)
+ f.close()
+
+if __name__ == '__main__':
+ gather_other_translations()
diff --git a/i18n_misc_strings.py b/i18n_misc_strings.py
new file mode 100644
index 0000000..62b124c
--- /dev/null
+++ b/i18n_misc_strings.py
@@ -0,0 +1,13 @@
+_("Sea Life")
+_("Animals")
+_("Birds")
+_("XO")
+_("Sports")
+_("My Own Pictures")
+_("Insects")
+_("Music")
+_("Space")
+_("Lesson 4")
+_("Lesson 3")
+_("Lesson 1")
+_("Lesson 2")
diff --git a/images/Ground Creatures/image_chmk_h250_w250_lg.gif b/images/Animals/image_chmk_h250_w250_lg.gif
index a0f650e..a0f650e 100644
--- a/images/Ground Creatures/image_chmk_h250_w250_lg.gif
+++ b/images/Animals/image_chmk_h250_w250_lg.gif
Binary files differ
diff --git a/images/Ground Creatures/image_djstf_h250_w411_lg.gif b/images/Animals/image_djstf_h250_w411_lg.gif
index e7eff4f..e7eff4f 100644
--- a/images/Ground Creatures/image_djstf_h250_w411_lg.gif
+++ b/images/Animals/image_djstf_h250_w411_lg.gif
Binary files differ
diff --git a/images/Ground Creatures/image_drti_h250_w322_lg.gif b/images/Animals/image_drti_h250_w322_lg.gif
index bd14a1d..bd14a1d 100644
--- a/images/Ground Creatures/image_drti_h250_w322_lg.gif
+++ b/images/Animals/image_drti_h250_w322_lg.gif
Binary files differ
diff --git a/images/Ground Creatures/image_howl_h250_w250_lg.gif b/images/Animals/image_howl_h250_w250_lg.gif
index ce77aa4..ce77aa4 100644
--- a/images/Ground Creatures/image_howl_h250_w250_lg.gif
+++ b/images/Animals/image_howl_h250_w250_lg.gif
Binary files differ
diff --git a/images/Ground Creatures/image_hsnr_h250_w421_lg.gif b/images/Animals/image_hsnr_h250_w421_lg.gif
index 566cf2d..566cf2d 100644
--- a/images/Ground Creatures/image_hsnr_h250_w421_lg.gif
+++ b/images/Animals/image_hsnr_h250_w421_lg.gif
Binary files differ
diff --git a/images/Ground Creatures/image_justi_h250_w333_lg.gif b/images/Animals/image_justi_h250_w333_lg.gif
index 1adccf2..1adccf2 100644
--- a/images/Ground Creatures/image_justi_h250_w333_lg.gif
+++ b/images/Animals/image_justi_h250_w333_lg.gif
Binary files differ
diff --git a/images/Ground Creatures/image_kili_h250_w387_lg.gif b/images/Animals/image_kili_h250_w387_lg.gif
index a61eaf0..a61eaf0 100644
--- a/images/Ground Creatures/image_kili_h250_w387_lg.gif
+++ b/images/Animals/image_kili_h250_w387_lg.gif
Binary files differ
diff --git a/images/Ground Creatures/image_lehf_h250_w250_lg.gif b/images/Animals/image_lehf_h250_w250_lg.gif
index 16c25bf..16c25bf 100644
--- a/images/Ground Creatures/image_lehf_h250_w250_lg.gif
+++ b/images/Animals/image_lehf_h250_w250_lg.gif
Binary files differ
diff --git a/images/Ground Creatures/image_mdic_h250_w250_lg.gif b/images/Animals/image_mdic_h250_w250_lg.gif
index 365b0dd..365b0dd 100644
--- a/images/Ground Creatures/image_mdic_h250_w250_lg.gif
+++ b/images/Animals/image_mdic_h250_w250_lg.gif
Binary files differ
diff --git a/images/Ground Creatures/image_mdwl_h250_w250_lg.gif b/images/Animals/image_mdwl_h250_w250_lg.gif
index 5979d62..5979d62 100644
--- a/images/Ground Creatures/image_mdwl_h250_w250_lg.gif
+++ b/images/Animals/image_mdwl_h250_w250_lg.gif
Binary files differ
diff --git a/images/Water Creatures/image_mrfg_h250_w333_lg.gif b/images/Animals/image_mrfg_h250_w333_lg.gif
index 4d8ecd4..4d8ecd4 100644
--- a/images/Water Creatures/image_mrfg_h250_w333_lg.gif
+++ b/images/Animals/image_mrfg_h250_w333_lg.gif
Binary files differ
diff --git a/images/Ground Creatures/image_nimo_h250_w299_lg.gif b/images/Animals/image_nimo_h250_w299_lg.gif
index f87bc58..f87bc58 100644
--- a/images/Ground Creatures/image_nimo_h250_w299_lg.gif
+++ b/images/Animals/image_nimo_h250_w299_lg.gif
Binary files differ
diff --git a/images/Animals/image_skat_h250_w363_lg.gif b/images/Animals/image_skat_h250_w363_lg.gif
new file mode 100644
index 0000000..49bd9b6
--- /dev/null
+++ b/images/Animals/image_skat_h250_w363_lg.gif
Binary files differ
diff --git a/images/Ground Creatures/thumb.gif b/images/Animals/thumb.gif
index 489836f..489836f 100644
--- a/images/Ground Creatures/thumb.gif
+++ b/images/Animals/thumb.gif
Binary files differ
diff --git a/images/Sky Creatures/image_mbmg_h250_w250_lg.gif b/images/Birds/image_mbmg_h250_w250_lg.gif
index 3250b7e..3250b7e 100644
--- a/images/Sky Creatures/image_mbmg_h250_w250_lg.gif
+++ b/images/Birds/image_mbmg_h250_w250_lg.gif
Binary files differ
diff --git a/images/Sky Creatures/image_oitn_h250_w250_lg.gif b/images/Birds/image_oitn_h250_w250_lg.gif
index 3b0f64a..3b0f64a 100644
--- a/images/Sky Creatures/image_oitn_h250_w250_lg.gif
+++ b/images/Birds/image_oitn_h250_w250_lg.gif
Binary files differ
diff --git a/images/Ground Creatures/image_s1macaw_lg.gif b/images/Birds/image_s1macaw_lg.gif
index 6138e2c..6138e2c 100644
--- a/images/Ground Creatures/image_s1macaw_lg.gif
+++ b/images/Birds/image_s1macaw_lg.gif
Binary files differ
diff --git a/images/Sky Creatures/thumb.gif b/images/Birds/thumb.gif
index 78b4606..78b4606 100644
--- a/images/Sky Creatures/thumb.gif
+++ b/images/Birds/thumb.gif
Binary files differ
diff --git a/images/Ground Creatures/image_skat_h250_w363_lg.gif b/images/Ground Creatures/image_skat_h250_w363_lg.gif
deleted file mode 100644
index 1c2a875..0000000
--- a/images/Ground Creatures/image_skat_h250_w363_lg.gif
+++ /dev/null
Binary files differ
diff --git a/images/My Own Pictures/happy_pig.lnk b/images/My Own Pictures/happy_pig.lnk
new file mode 100644
index 0000000..f04dec8
--- /dev/null
+++ b/images/My Own Pictures/happy_pig.lnk
@@ -0,0 +1 @@
+/home/cn/Desktop/happy_pig.jpg \ No newline at end of file
diff --git a/images/My Own Pictures/img_150x190.lnk b/images/My Own Pictures/img_150x190.lnk
new file mode 100644
index 0000000..faff546
--- /dev/null
+++ b/images/My Own Pictures/img_150x190.lnk
@@ -0,0 +1 @@
+/home/cn/img_150x190.png \ No newline at end of file
diff --git a/images/My Own Pictures/img_210x250.lnk b/images/My Own Pictures/img_210x250.lnk
new file mode 100644
index 0000000..4eec98d
--- /dev/null
+++ b/images/My Own Pictures/img_210x250.lnk
@@ -0,0 +1 @@
+/home/cn/img_210x250.png \ No newline at end of file
diff --git a/images/My Own Pictures/img_500x50.lnk b/images/My Own Pictures/img_500x50.lnk
new file mode 100644
index 0000000..00947b6
--- /dev/null
+++ b/images/My Own Pictures/img_500x50.lnk
@@ -0,0 +1 @@
+/home/cn/img_500x50.png \ No newline at end of file
diff --git a/images/My Own Pictures/lourenco.lnk b/images/My Own Pictures/lourenco.lnk
new file mode 100644
index 0000000..6785e0b
--- /dev/null
+++ b/images/My Own Pictures/lourenco.lnk
@@ -0,0 +1 @@
+/home/cn/Desktop/lourenco.jpg \ No newline at end of file
diff --git a/images/Places/image_smrr_h250_w371_lg.gif b/images/Places/image_smrr_h250_w371_lg.gif
deleted file mode 100644
index 202eb9d..0000000
--- a/images/Places/image_smrr_h250_w371_lg.gif
+++ /dev/null
Binary files differ
diff --git a/images/Places/thumb.gif b/images/Places/thumb.gif
deleted file mode 100644
index 38c502f..0000000
--- a/images/Places/thumb.gif
+++ /dev/null
Binary files differ
diff --git a/images/Water Creatures/image_atlo_h250_w333_lg.gif b/images/Sea Life/image_atlo_h250_w333_lg.gif
index 12e473e..12e473e 100644
--- a/images/Water Creatures/image_atlo_h250_w333_lg.gif
+++ b/images/Sea Life/image_atlo_h250_w333_lg.gif
Binary files differ
diff --git a/images/Places/image_btfi_h250_w331_lg.gif b/images/Sea Life/image_btfi_h250_w331_lg.gif
index b0f05e3..b0f05e3 100644
--- a/images/Places/image_btfi_h250_w331_lg.gif
+++ b/images/Sea Life/image_btfi_h250_w331_lg.gif
Binary files differ
diff --git a/images/Water Creatures/image_cal_h250_w165_lg.gif b/images/Sea Life/image_cal_h250_w165_lg.gif
index d020ed7..d020ed7 100644
--- a/images/Water Creatures/image_cal_h250_w165_lg.gif
+++ b/images/Sea Life/image_cal_h250_w165_lg.gif
Binary files differ
diff --git a/images/Water Creatures/image_clor_h250_w250_lg.gif b/images/Sea Life/image_clor_h250_w250_lg.gif
index 5f3e045..5f3e045 100644
--- a/images/Water Creatures/image_clor_h250_w250_lg.gif
+++ b/images/Sea Life/image_clor_h250_w250_lg.gif
Binary files differ
diff --git a/images/Water Creatures/image_col_h250_w333_lg.gif b/images/Sea Life/image_col_h250_w333_lg.gif
index c2dc2a8..c2dc2a8 100644
--- a/images/Water Creatures/image_col_h250_w333_lg.gif
+++ b/images/Sea Life/image_col_h250_w333_lg.gif
Binary files differ
diff --git a/images/Water Creatures/image_dan_h250_w424_lg.gif b/images/Sea Life/image_dan_h250_w424_lg.gif
index f2fc0fd..f2fc0fd 100644
--- a/images/Water Creatures/image_dan_h250_w424_lg.gif
+++ b/images/Sea Life/image_dan_h250_w424_lg.gif
Binary files differ
diff --git a/images/Water Creatures/image_fsuw_h250_w250_lg.gif b/images/Sea Life/image_fsuw_h250_w250_lg.gif
index 69eb3cf..69eb3cf 100644
--- a/images/Water Creatures/image_fsuw_h250_w250_lg.gif
+++ b/images/Sea Life/image_fsuw_h250_w250_lg.gif
Binary files differ
diff --git a/images/Water Creatures/image_higc_h250_w250_lg.gif b/images/Sea Life/image_higc_h250_w250_lg.gif
index f52c054..f52c054 100644
--- a/images/Water Creatures/image_higc_h250_w250_lg.gif
+++ b/images/Sea Life/image_higc_h250_w250_lg.gif
Binary files differ
diff --git a/images/Water Creatures/image_joc_h250_w333_lg.gif b/images/Sea Life/image_joc_h250_w333_lg.gif
index 89da89a..89da89a 100644
--- a/images/Water Creatures/image_joc_h250_w333_lg.gif
+++ b/images/Sea Life/image_joc_h250_w333_lg.gif
Binary files differ
diff --git a/images/Water Creatures/image_kitty_lg.gif b/images/Sea Life/image_kitty_lg.gif
index c197337..c197337 100644
--- a/images/Water Creatures/image_kitty_lg.gif
+++ b/images/Sea Life/image_kitty_lg.gif
Binary files differ
diff --git a/images/Water Creatures/image_sxykitton_lg.gif b/images/Sea Life/image_sxykitton_lg.gif
index 08a1597..08a1597 100644
--- a/images/Water Creatures/image_sxykitton_lg.gif
+++ b/images/Sea Life/image_sxykitton_lg.gif
Binary files differ
diff --git a/images/Water Creatures/image_tsoc_h250_w421_lg.gif b/images/Sea Life/image_tsoc_h250_w421_lg.gif
index 96a337a..96a337a 100644
--- a/images/Water Creatures/image_tsoc_h250_w421_lg.gif
+++ b/images/Sea Life/image_tsoc_h250_w421_lg.gif
Binary files differ
diff --git a/images/Water Creatures/image_xxmrtwigxx_lg.gif b/images/Sea Life/image_xxmrtwigxx_lg.gif
index 4f8a273..4f8a273 100644
--- a/images/Water Creatures/image_xxmrtwigxx_lg.gif
+++ b/images/Sea Life/image_xxmrtwigxx_lg.gif
Binary files differ
diff --git a/images/Water Creatures/thumb.gif b/images/Sea Life/thumb.gif
index c321ecb..c321ecb 100644
--- a/images/Water Creatures/thumb.gif
+++ b/images/Sea Life/thumb.gif
Binary files differ
diff --git a/images/XO's/image_XO.svg b/images/XO/image_XO.svg
index 6e4a7b3..6e4a7b3 100644
--- a/images/XO's/image_XO.svg
+++ b/images/XO/image_XO.svg
diff --git a/images/XO's/image_XO2.svg b/images/XO/image_XO2.svg
index fdc6618..fdc6618 100644
--- a/images/XO's/image_XO2.svg
+++ b/images/XO/image_XO2.svg
diff --git a/images/XO's/image_XO3.svg b/images/XO/image_XO3.svg
index 590b077..590b077 100644
--- a/images/XO's/image_XO3.svg
+++ b/images/XO/image_XO3.svg
diff --git a/images/XO's/thumb.svg b/images/XO/thumb.svg
index fdc6618..fdc6618 100644
--- a/images/XO's/thumb.svg
+++ b/images/XO/thumb.svg
diff --git a/json.py b/json.py
new file mode 100644
index 0000000..a28a13e
--- /dev/null
+++ b/json.py
@@ -0,0 +1,310 @@
+import string
+import types
+
+## json.py implements a JSON (http://json.org) reader and writer.
+## Copyright (C) 2005 Patrick D. Logan
+## Contact mailto:patrickdlogan@stardecisions.com
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library 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
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+class _StringGenerator(object):
+ def __init__(self, string):
+ self.string = string
+ self.index = -1
+ def peek(self):
+ i = self.index + 1
+ if i < len(self.string):
+ return self.string[i]
+ else:
+ return None
+ def next(self):
+ self.index += 1
+ if self.index < len(self.string):
+ return self.string[self.index]
+ else:
+ raise StopIteration
+ def all(self):
+ return self.string
+
+class WriteException(Exception):
+ pass
+
+class ReadException(Exception):
+ pass
+
+class JsonReader(object):
+ hex_digits = {'A': 10,'B': 11,'C': 12,'D': 13,'E': 14,'F':15}
+ escapes = {'t':'\t','n':'\n','f':'\f','r':'\r','b':'\b'}
+
+ def read(self, s):
+ self._generator = _StringGenerator(s)
+ result = self._read()
+ return result
+
+ def _read(self):
+ self._eatWhitespace()
+ peek = self._peek()
+ if peek is None:
+ raise ReadException, "Nothing to read: '%s'" % self._generator.all()
+ if peek == '{':
+ return self._readObject()
+ elif peek == '[':
+ return self._readArray()
+ elif peek == '"':
+ return self._readString()
+ elif peek == '-' or peek.isdigit():
+ return self._readNumber()
+ elif peek == 't':
+ return self._readTrue()
+ elif peek == 'f':
+ return self._readFalse()
+ elif peek == 'n':
+ return self._readNull()
+ elif peek == '/':
+ self._readComment()
+ return self._read()
+ else:
+ raise ReadException, "Input is not valid JSON: '%s'" % self._generator.all()
+
+ def _readTrue(self):
+ self._assertNext('t', "true")
+ self._assertNext('r', "true")
+ self._assertNext('u', "true")
+ self._assertNext('e', "true")
+ return True
+
+ def _readFalse(self):
+ self._assertNext('f', "false")
+ self._assertNext('a', "false")
+ self._assertNext('l', "false")
+ self._assertNext('s', "false")
+ self._assertNext('e', "false")
+ return False
+
+ def _readNull(self):
+ self._assertNext('n', "null")
+ self._assertNext('u', "null")
+ self._assertNext('l', "null")
+ self._assertNext('l', "null")
+ return None
+
+ def _assertNext(self, ch, target):
+ if self._next() != ch:
+ raise ReadException, "Trying to read %s: '%s'" % (target, self._generator.all())
+
+ def _readNumber(self):
+ isfloat = False
+ result = self._next()
+ peek = self._peek()
+ while peek is not None and (peek.isdigit() or peek == "."):
+ isfloat = isfloat or peek == "."
+ result = result + self._next()
+ peek = self._peek()
+ try:
+ if isfloat:
+ return float(result)
+ else:
+ return int(result)
+ except ValueError:
+ raise ReadException, "Not a valid JSON number: '%s'" % result
+
+ def _readString(self):
+ result = ""
+ assert self._next() == '"'
+ try:
+ while self._peek() != '"':
+ ch = self._next()
+ if ch == "\\":
+ ch = self._next()
+ if ch in 'brnft':
+ ch = self.escapes[ch]
+ elif ch == "u":
+ ch4096 = self._next()
+ ch256 = self._next()
+ ch16 = self._next()
+ ch1 = self._next()
+ n = 4096 * self._hexDigitToInt(ch4096)
+ n += 256 * self._hexDigitToInt(ch256)
+ n += 16 * self._hexDigitToInt(ch16)
+ n += self._hexDigitToInt(ch1)
+ ch = unichr(n)
+ elif ch not in '"/\\':
+ raise ReadException, "Not a valid escaped JSON character: '%s' in %s" % (ch, self._generator.all())
+ result = result + ch
+ except StopIteration:
+ raise ReadException, "Not a valid JSON string: '%s'" % self._generator.all()
+ assert self._next() == '"'
+ return result
+
+ def _hexDigitToInt(self, ch):
+ try:
+ result = self.hex_digits[ch.upper()]
+ except KeyError:
+ try:
+ result = int(ch)
+ except ValueError:
+ raise ReadException, "The character %s is not a hex digit." % ch
+ return result
+
+ def _readComment(self):
+ assert self._next() == "/"
+ second = self._next()
+ if second == "/":
+ self._readDoubleSolidusComment()
+ elif second == '*':
+ self._readCStyleComment()
+ else:
+ raise ReadException, "Not a valid JSON comment: %s" % self._generator.all()
+
+ def _readCStyleComment(self):
+ try:
+ done = False
+ while not done:
+ ch = self._next()
+ done = (ch == "*" and self._peek() == "/")
+ if not done and ch == "/" and self._peek() == "*":
+ raise ReadException, "Not a valid JSON comment: %s, '/*' cannot be embedded in the comment." % self._generator.all()
+ self._next()
+ except StopIteration:
+ raise ReadException, "Not a valid JSON comment: %s, expected */" % self._generator.all()
+
+ def _readDoubleSolidusComment(self):
+ try:
+ ch = self._next()
+ while ch != "\r" and ch != "\n":
+ ch = self._next()
+ except StopIteration:
+ pass
+
+ def _readArray(self):
+ result = []
+ assert self._next() == '['
+ done = self._peek() == ']'
+ while not done:
+ item = self._read()
+ result.append(item)
+ self._eatWhitespace()
+ done = self._peek() == ']'
+ if not done:
+ ch = self._next()
+ if ch != ",":
+ raise ReadException, "Not a valid JSON array: '%s' due to: '%s'" % (self._generator.all(), ch)
+ assert ']' == self._next()
+ return result
+
+ def _readObject(self):
+ result = {}
+ assert self._next() == '{'
+ done = self._peek() == '}'
+ while not done:
+ key = self._read()
+ if type(key) is not types.StringType:
+ raise ReadException, "Not a valid JSON object key (should be a string): %s" % key
+ self._eatWhitespace()
+ ch = self._next()
+ if ch != ":":
+ raise ReadException, "Not a valid JSON object: '%s' due to: '%s'" % (self._generator.all(), ch)
+ self._eatWhitespace()
+ val = self._read()
+ result[key] = val
+ self._eatWhitespace()
+ done = self._peek() == '}'
+ if not done:
+ ch = self._next()
+ if ch != ",":
+ raise ReadException, "Not a valid JSON array: '%s' due to: '%s'" % (self._generator.all(), ch)
+ assert self._next() == "}"
+ return result
+
+ def _eatWhitespace(self):
+ p = self._peek()
+ while p is not None and p in string.whitespace or p == '/':
+ if p == '/':
+ self._readComment()
+ else:
+ self._next()
+ p = self._peek()
+
+ def _peek(self):
+ return self._generator.peek()
+
+ def _next(self):
+ return self._generator.next()
+
+class JsonWriter(object):
+
+ def _append(self, s):
+ self._results.append(s)
+
+ def write(self, obj, escaped_forward_slash=False):
+ self._escaped_forward_slash = escaped_forward_slash
+ self._results = []
+ self._write(obj)
+ return "".join(self._results)
+
+ def _write(self, obj):
+ ty = type(obj)
+ if ty is types.DictType:
+ n = len(obj)
+ self._append("{")
+ for k, v in obj.items():
+ self._write(k)
+ self._append(":")
+ self._write(v)
+ n = n - 1
+ if n > 0:
+ self._append(",")
+ self._append("}")
+ elif ty is types.ListType or ty is types.TupleType:
+ n = len(obj)
+ self._append("[")
+ for item in obj:
+ self._write(item)
+ n = n - 1
+ if n > 0:
+ self._append(",")
+ self._append("]")
+ elif ty is types.StringType or ty is types.UnicodeType:
+ self._append('"')
+ obj = obj.replace('\\', r'\\')
+ if self._escaped_forward_slash:
+ obj = obj.replace('/', r'\/')
+ obj = obj.replace('"', r'\"')
+ obj = obj.replace('\b', r'\b')
+ obj = obj.replace('\f', r'\f')
+ obj = obj.replace('\n', r'\n')
+ obj = obj.replace('\r', r'\r')
+ obj = obj.replace('\t', r'\t')
+ self._append(obj)
+ self._append('"')
+ elif ty is types.IntType or ty is types.LongType:
+ self._append(str(obj))
+ elif ty is types.FloatType:
+ self._append("%f" % obj)
+ elif obj is True:
+ self._append("true")
+ elif obj is False:
+ self._append("false")
+ elif obj is None:
+ self._append("null")
+ else:
+ raise WriteException, "Cannot write in JSON: %s" % repr(obj)
+
+def write(obj, escaped_forward_slash=False):
+ return JsonWriter().write(obj, escaped_forward_slash)
+
+def read(s):
+ return JsonReader().read(s)
diff --git a/lessons/Lesson 1/default.abw b/lessons/Lesson 1/default.abw
new file mode 100644
index 0000000..da97de9
--- /dev/null
+++ b/lessons/Lesson 1/default.abw
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE abiword PUBLIC "-//ABISOURCE//DTD AWML 1.0 Strict//EN" "http://www.abisource.com/awml.dtd">
+<abiword template="false" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:math="http://www.w3.org/1998/Math/MathML" xid-max="36" xmlns:dc="http://purl.org/dc/elements/1.1/" fileformat="1.1" xmlns:svg="http://www.w3.org/2000/svg" xmlns:awml="http://www.abisource.com/awml.dtd" xmlns="http://www.abisource.com/awml.dtd" xmlns:xlink="http://www.w3.org/1999/xlink" version="2.4.6" xml:space="preserve" props="dom-dir:ltr; document-footnote-restart-section:0; document-endnote-type:numeric; document-endnote-place-enddoc:1; document-endnote-initial:1; lang:en-US; document-endnote-restart-section:0; document-footnote-restart-page:0; document-footnote-type:numeric; document-footnote-initial:1; document-endnote-place-endsection:0">
+<!-- ======================================================================== -->
+<!-- This file is an AbiWord document. -->
+<!-- AbiWord is a free, Open Source word processor. -->
+<!-- More information about AbiWord is available at http://www.abisource.com/ -->
+<!-- You should not edit this file by hand. -->
+<!-- ======================================================================== -->
+
+<metadata>
+<m key="dc.format">application/x-abiword</m>
+<m key="abiword.generator">AbiWord</m>
+</metadata>
+<history version="1" edit-time="49" last-saved="1181641526" uid="88d13a24-18c9-11dc-9a12-98843cc1b3a3">
+<version id="1" started="1181641526" uid="a5f38efe-18c9-11dc-9a12-98843cc1b3a3" auto="0" top-xid="36"/>
+</history>
+<styles>
+<s type="P" name="Normal" followedby="Normal" props="text-indent:0in; margin-top:0pt; margin-left:0pt; font-stretch:normal; line-height:1.0; text-align:left; bgcolor:transparent; lang:en-US; dom-dir:ltr; margin-bottom:0pt; font-weight:normal; text-decoration:none; font-variant:normal; color:000000; text-position:normal; font-size:12pt; margin-right:0pt; font-style:normal; widows:2; font-family:Times New Roman"/>
+<s type="P" name="Table Normal" followedby="Table Normal" props="font-family:Times New Roman; font-size:12pt; dom-dir:ltr; lang:en-US; orphans:0; text-align:left; widows:0"/>
+</styles>
+<lists>
+<l id="1000" parentid="0" type="0" start-value="1" list-delim="%L)" list-decimal="."/>
+<l id="1001" parentid="0" type="0" start-value="1" list-delim="%L)" list-decimal="."/>
+<l id="1002" parentid="0" type="0" start-value="2" list-delim="%L)" list-decimal="."/>
+<l id="1003" parentid="0" type="0" start-value="4" list-delim="%L)" list-decimal="."/>
+</lists>
+<pagesize pagetype="Letter" orientation="portrait" width="8.500000" height="11.000000" units="in" page-scale="1.000000"/>
+<section xid="1" props="page-margin-right:1.2500in; section-restart-value:1; dom-dir:ltr; section-space-after:0.0000in; page-margin-footer:0.5000in; page-margin-header:0.5000in; page-margin-left:1.2500in; page-margin-top:1.0000in; page-margin-bottom:1.0000in">
+<p style="Normal" xid="2" props="text-align:left; line-height:1.0; dom-dir:ltr"><c props="lang:en-US; font-weight:bold; font-size:12pt; font-family:Century Gothic; text-decoration:underline">Lesson 1: Explore the Slider Puzzle</c></p>
+<p style="Normal" xid="3" props="text-align:left; line-height:1.0; dom-dir:ltr"></p>
+<p style="Normal" xid="4" props="text-align:left; line-height:1.0; dom-dir:ltr"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic; font-weight:bold">Objective: </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">To learn how to play a digital Slider Puzzle.</c></p>
+<p style="Normal" xid="5" props="text-align:left; line-height:1.0; dom-dir:ltr"></p>
+<p style="Normal" xid="6" props="text-align:left; line-height:1.0; dom-dir:ltr"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic; font-weight:bold">Specific Goals/Skills</c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">:</c></p>
+<p style="Normal" xid="7" props="margin-left:0.5000in; tabstops:0.5000in/L; dom-dir:ltr; text-indent:-0.2500in; line-height:1.0; text-align:left; margin-right:-0.5000in"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Practice problem solving and building strategies to find a solution.</c></p>
+<p style="Normal" xid="8" props="text-align:left; tabstops:0.5000in/L; text-indent:-0.2500in; line-height:1.0; dom-dir:ltr; margin-left:0.5000in"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Learn how to help peers understand an idea.</c></p>
+<p style="Normal" xid="9" props="text-align:left; tabstops:0.5000in/L; text-indent:-0.2500in; line-height:1.0; dom-dir:ltr; margin-left:0.5000in"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Learn from classmates.</c></p>
+<p style="Normal" xid="10" props="text-align:left; tabstops:0.5000in/L; text-indent:-0.2500in; line-height:1.0; dom-dir:ltr; margin-left:0.5000in"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Practice discussing thought processes around problem solving.</c></p>
+<p style="Normal" xid="11" props="text-align:left; line-height:1.0; dom-dir:ltr"></p>
+<p style="Normal" xid="12" props="text-align:left; line-height:1.0; dom-dir:ltr"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic; font-weight:bold">Steps:</c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="13" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:1; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="14" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Show the students to open the Slider Puzzle from the MaMaMedia menu screen. Demonstrate this on your own computer in the front of the class. </c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="15" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:1; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="16" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Explain to students how they can look at all the available subjects and pictures. </c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="17" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:1; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="18" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Explain that the goal of this puzzle is to create a complete picture, which will be identical to the one they see on the left of their screen. </c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="19" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:1; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="20" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Demonstrate for students how they can move a square up, down, to the right and then to the left. </c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="21" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:1; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="22" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Give students the opportunity to choose one picture that they would like to solve as a puzzle. (Students can work in pairs or independently, whichever you think is better.)</c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="23" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:1; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="24" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Students who complete their puzzle should go around and help their peers who are still working on the puzzle.</c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="25" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:1; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="26" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">After students play the game, encourage them to discuss how they solved the puzzle. Ask them to identify what worked and what didn’t work. Give students a chance to discuss the things they found difficult or frustrating.</c></p>
+<p style="Normal" xid="27" props="text-align:left; line-height:1.0; dom-dir:ltr"></p>
+<p style="Normal" xid="28" props="text-align:left; line-height:1.0; dom-dir:ltr"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic; font-weight:bold">Extended Activity</c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">: Now that students know how to play with the puzzle, your class can have a contest.<br/></c></p>
+<p level="1" listid="1001" parentid="0" style="Normal" xid="29" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:1; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="30" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Each computer has a timer. Point out the timer to the students, and explain to them how to use it.</c></p>
+<p level="1" listid="1002" parentid="0" style="Normal" xid="31" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:2; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="32" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Tell students that they will be playing the Slider Puzzle, but this time they will be timed and the student who finishes first (in the shortest time) will be the winner.</c></p>
+<p style="Normal" xid="33" props="text-align:left; tabstops:0.5000in/L; text-indent:-0.2500in; line-height:1.0; dom-dir:ltr; margin-left:0.2500in"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Once a student wins, have him/her tell the class what strategy they used to solve the puzzle quickly. Ask the student what he or she thought about the puzzle.</c></p>
+<p level="1" listid="1003" parentid="0" style="Normal" xid="34" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:4; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="35" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Give the other students a chance to discuss how their puzzle solving skills have improved since the first time they played.</c></p>
+<p xid="36"></p>
+</section>
+</abiword>
diff --git a/lessons/Lesson 2/default.abw b/lessons/Lesson 2/default.abw
new file mode 100644
index 0000000..da97de9
--- /dev/null
+++ b/lessons/Lesson 2/default.abw
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE abiword PUBLIC "-//ABISOURCE//DTD AWML 1.0 Strict//EN" "http://www.abisource.com/awml.dtd">
+<abiword template="false" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:math="http://www.w3.org/1998/Math/MathML" xid-max="36" xmlns:dc="http://purl.org/dc/elements/1.1/" fileformat="1.1" xmlns:svg="http://www.w3.org/2000/svg" xmlns:awml="http://www.abisource.com/awml.dtd" xmlns="http://www.abisource.com/awml.dtd" xmlns:xlink="http://www.w3.org/1999/xlink" version="2.4.6" xml:space="preserve" props="dom-dir:ltr; document-footnote-restart-section:0; document-endnote-type:numeric; document-endnote-place-enddoc:1; document-endnote-initial:1; lang:en-US; document-endnote-restart-section:0; document-footnote-restart-page:0; document-footnote-type:numeric; document-footnote-initial:1; document-endnote-place-endsection:0">
+<!-- ======================================================================== -->
+<!-- This file is an AbiWord document. -->
+<!-- AbiWord is a free, Open Source word processor. -->
+<!-- More information about AbiWord is available at http://www.abisource.com/ -->
+<!-- You should not edit this file by hand. -->
+<!-- ======================================================================== -->
+
+<metadata>
+<m key="dc.format">application/x-abiword</m>
+<m key="abiword.generator">AbiWord</m>
+</metadata>
+<history version="1" edit-time="49" last-saved="1181641526" uid="88d13a24-18c9-11dc-9a12-98843cc1b3a3">
+<version id="1" started="1181641526" uid="a5f38efe-18c9-11dc-9a12-98843cc1b3a3" auto="0" top-xid="36"/>
+</history>
+<styles>
+<s type="P" name="Normal" followedby="Normal" props="text-indent:0in; margin-top:0pt; margin-left:0pt; font-stretch:normal; line-height:1.0; text-align:left; bgcolor:transparent; lang:en-US; dom-dir:ltr; margin-bottom:0pt; font-weight:normal; text-decoration:none; font-variant:normal; color:000000; text-position:normal; font-size:12pt; margin-right:0pt; font-style:normal; widows:2; font-family:Times New Roman"/>
+<s type="P" name="Table Normal" followedby="Table Normal" props="font-family:Times New Roman; font-size:12pt; dom-dir:ltr; lang:en-US; orphans:0; text-align:left; widows:0"/>
+</styles>
+<lists>
+<l id="1000" parentid="0" type="0" start-value="1" list-delim="%L)" list-decimal="."/>
+<l id="1001" parentid="0" type="0" start-value="1" list-delim="%L)" list-decimal="."/>
+<l id="1002" parentid="0" type="0" start-value="2" list-delim="%L)" list-decimal="."/>
+<l id="1003" parentid="0" type="0" start-value="4" list-delim="%L)" list-decimal="."/>
+</lists>
+<pagesize pagetype="Letter" orientation="portrait" width="8.500000" height="11.000000" units="in" page-scale="1.000000"/>
+<section xid="1" props="page-margin-right:1.2500in; section-restart-value:1; dom-dir:ltr; section-space-after:0.0000in; page-margin-footer:0.5000in; page-margin-header:0.5000in; page-margin-left:1.2500in; page-margin-top:1.0000in; page-margin-bottom:1.0000in">
+<p style="Normal" xid="2" props="text-align:left; line-height:1.0; dom-dir:ltr"><c props="lang:en-US; font-weight:bold; font-size:12pt; font-family:Century Gothic; text-decoration:underline">Lesson 1: Explore the Slider Puzzle</c></p>
+<p style="Normal" xid="3" props="text-align:left; line-height:1.0; dom-dir:ltr"></p>
+<p style="Normal" xid="4" props="text-align:left; line-height:1.0; dom-dir:ltr"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic; font-weight:bold">Objective: </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">To learn how to play a digital Slider Puzzle.</c></p>
+<p style="Normal" xid="5" props="text-align:left; line-height:1.0; dom-dir:ltr"></p>
+<p style="Normal" xid="6" props="text-align:left; line-height:1.0; dom-dir:ltr"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic; font-weight:bold">Specific Goals/Skills</c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">:</c></p>
+<p style="Normal" xid="7" props="margin-left:0.5000in; tabstops:0.5000in/L; dom-dir:ltr; text-indent:-0.2500in; line-height:1.0; text-align:left; margin-right:-0.5000in"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Practice problem solving and building strategies to find a solution.</c></p>
+<p style="Normal" xid="8" props="text-align:left; tabstops:0.5000in/L; text-indent:-0.2500in; line-height:1.0; dom-dir:ltr; margin-left:0.5000in"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Learn how to help peers understand an idea.</c></p>
+<p style="Normal" xid="9" props="text-align:left; tabstops:0.5000in/L; text-indent:-0.2500in; line-height:1.0; dom-dir:ltr; margin-left:0.5000in"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Learn from classmates.</c></p>
+<p style="Normal" xid="10" props="text-align:left; tabstops:0.5000in/L; text-indent:-0.2500in; line-height:1.0; dom-dir:ltr; margin-left:0.5000in"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Practice discussing thought processes around problem solving.</c></p>
+<p style="Normal" xid="11" props="text-align:left; line-height:1.0; dom-dir:ltr"></p>
+<p style="Normal" xid="12" props="text-align:left; line-height:1.0; dom-dir:ltr"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic; font-weight:bold">Steps:</c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="13" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:1; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="14" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Show the students to open the Slider Puzzle from the MaMaMedia menu screen. Demonstrate this on your own computer in the front of the class. </c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="15" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:1; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="16" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Explain to students how they can look at all the available subjects and pictures. </c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="17" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:1; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="18" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Explain that the goal of this puzzle is to create a complete picture, which will be identical to the one they see on the left of their screen. </c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="19" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:1; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="20" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Demonstrate for students how they can move a square up, down, to the right and then to the left. </c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="21" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:1; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="22" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Give students the opportunity to choose one picture that they would like to solve as a puzzle. (Students can work in pairs or independently, whichever you think is better.)</c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="23" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:1; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="24" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Students who complete their puzzle should go around and help their peers who are still working on the puzzle.</c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="25" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:1; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="26" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">After students play the game, encourage them to discuss how they solved the puzzle. Ask them to identify what worked and what didn’t work. Give students a chance to discuss the things they found difficult or frustrating.</c></p>
+<p style="Normal" xid="27" props="text-align:left; line-height:1.0; dom-dir:ltr"></p>
+<p style="Normal" xid="28" props="text-align:left; line-height:1.0; dom-dir:ltr"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic; font-weight:bold">Extended Activity</c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">: Now that students know how to play with the puzzle, your class can have a contest.<br/></c></p>
+<p level="1" listid="1001" parentid="0" style="Normal" xid="29" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:1; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="30" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Each computer has a timer. Point out the timer to the students, and explain to them how to use it.</c></p>
+<p level="1" listid="1002" parentid="0" style="Normal" xid="31" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:2; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="32" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Tell students that they will be playing the Slider Puzzle, but this time they will be timed and the student who finishes first (in the shortest time) will be the winner.</c></p>
+<p style="Normal" xid="33" props="text-align:left; tabstops:0.5000in/L; text-indent:-0.2500in; line-height:1.0; dom-dir:ltr; margin-left:0.2500in"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Once a student wins, have him/her tell the class what strategy they used to solve the puzzle quickly. Ask the student what he or she thought about the puzzle.</c></p>
+<p level="1" listid="1003" parentid="0" style="Normal" xid="34" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:4; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="35" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Give the other students a chance to discuss how their puzzle solving skills have improved since the first time they played.</c></p>
+<p xid="36"></p>
+</section>
+</abiword>
diff --git a/lessons/Lesson 3/default.abw b/lessons/Lesson 3/default.abw
new file mode 100644
index 0000000..da97de9
--- /dev/null
+++ b/lessons/Lesson 3/default.abw
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE abiword PUBLIC "-//ABISOURCE//DTD AWML 1.0 Strict//EN" "http://www.abisource.com/awml.dtd">
+<abiword template="false" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:math="http://www.w3.org/1998/Math/MathML" xid-max="36" xmlns:dc="http://purl.org/dc/elements/1.1/" fileformat="1.1" xmlns:svg="http://www.w3.org/2000/svg" xmlns:awml="http://www.abisource.com/awml.dtd" xmlns="http://www.abisource.com/awml.dtd" xmlns:xlink="http://www.w3.org/1999/xlink" version="2.4.6" xml:space="preserve" props="dom-dir:ltr; document-footnote-restart-section:0; document-endnote-type:numeric; document-endnote-place-enddoc:1; document-endnote-initial:1; lang:en-US; document-endnote-restart-section:0; document-footnote-restart-page:0; document-footnote-type:numeric; document-footnote-initial:1; document-endnote-place-endsection:0">
+<!-- ======================================================================== -->
+<!-- This file is an AbiWord document. -->
+<!-- AbiWord is a free, Open Source word processor. -->
+<!-- More information about AbiWord is available at http://www.abisource.com/ -->
+<!-- You should not edit this file by hand. -->
+<!-- ======================================================================== -->
+
+<metadata>
+<m key="dc.format">application/x-abiword</m>
+<m key="abiword.generator">AbiWord</m>
+</metadata>
+<history version="1" edit-time="49" last-saved="1181641526" uid="88d13a24-18c9-11dc-9a12-98843cc1b3a3">
+<version id="1" started="1181641526" uid="a5f38efe-18c9-11dc-9a12-98843cc1b3a3" auto="0" top-xid="36"/>
+</history>
+<styles>
+<s type="P" name="Normal" followedby="Normal" props="text-indent:0in; margin-top:0pt; margin-left:0pt; font-stretch:normal; line-height:1.0; text-align:left; bgcolor:transparent; lang:en-US; dom-dir:ltr; margin-bottom:0pt; font-weight:normal; text-decoration:none; font-variant:normal; color:000000; text-position:normal; font-size:12pt; margin-right:0pt; font-style:normal; widows:2; font-family:Times New Roman"/>
+<s type="P" name="Table Normal" followedby="Table Normal" props="font-family:Times New Roman; font-size:12pt; dom-dir:ltr; lang:en-US; orphans:0; text-align:left; widows:0"/>
+</styles>
+<lists>
+<l id="1000" parentid="0" type="0" start-value="1" list-delim="%L)" list-decimal="."/>
+<l id="1001" parentid="0" type="0" start-value="1" list-delim="%L)" list-decimal="."/>
+<l id="1002" parentid="0" type="0" start-value="2" list-delim="%L)" list-decimal="."/>
+<l id="1003" parentid="0" type="0" start-value="4" list-delim="%L)" list-decimal="."/>
+</lists>
+<pagesize pagetype="Letter" orientation="portrait" width="8.500000" height="11.000000" units="in" page-scale="1.000000"/>
+<section xid="1" props="page-margin-right:1.2500in; section-restart-value:1; dom-dir:ltr; section-space-after:0.0000in; page-margin-footer:0.5000in; page-margin-header:0.5000in; page-margin-left:1.2500in; page-margin-top:1.0000in; page-margin-bottom:1.0000in">
+<p style="Normal" xid="2" props="text-align:left; line-height:1.0; dom-dir:ltr"><c props="lang:en-US; font-weight:bold; font-size:12pt; font-family:Century Gothic; text-decoration:underline">Lesson 1: Explore the Slider Puzzle</c></p>
+<p style="Normal" xid="3" props="text-align:left; line-height:1.0; dom-dir:ltr"></p>
+<p style="Normal" xid="4" props="text-align:left; line-height:1.0; dom-dir:ltr"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic; font-weight:bold">Objective: </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">To learn how to play a digital Slider Puzzle.</c></p>
+<p style="Normal" xid="5" props="text-align:left; line-height:1.0; dom-dir:ltr"></p>
+<p style="Normal" xid="6" props="text-align:left; line-height:1.0; dom-dir:ltr"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic; font-weight:bold">Specific Goals/Skills</c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">:</c></p>
+<p style="Normal" xid="7" props="margin-left:0.5000in; tabstops:0.5000in/L; dom-dir:ltr; text-indent:-0.2500in; line-height:1.0; text-align:left; margin-right:-0.5000in"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Practice problem solving and building strategies to find a solution.</c></p>
+<p style="Normal" xid="8" props="text-align:left; tabstops:0.5000in/L; text-indent:-0.2500in; line-height:1.0; dom-dir:ltr; margin-left:0.5000in"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Learn how to help peers understand an idea.</c></p>
+<p style="Normal" xid="9" props="text-align:left; tabstops:0.5000in/L; text-indent:-0.2500in; line-height:1.0; dom-dir:ltr; margin-left:0.5000in"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Learn from classmates.</c></p>
+<p style="Normal" xid="10" props="text-align:left; tabstops:0.5000in/L; text-indent:-0.2500in; line-height:1.0; dom-dir:ltr; margin-left:0.5000in"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Practice discussing thought processes around problem solving.</c></p>
+<p style="Normal" xid="11" props="text-align:left; line-height:1.0; dom-dir:ltr"></p>
+<p style="Normal" xid="12" props="text-align:left; line-height:1.0; dom-dir:ltr"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic; font-weight:bold">Steps:</c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="13" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:1; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="14" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Show the students to open the Slider Puzzle from the MaMaMedia menu screen. Demonstrate this on your own computer in the front of the class. </c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="15" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:1; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="16" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Explain to students how they can look at all the available subjects and pictures. </c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="17" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:1; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="18" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Explain that the goal of this puzzle is to create a complete picture, which will be identical to the one they see on the left of their screen. </c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="19" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:1; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="20" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Demonstrate for students how they can move a square up, down, to the right and then to the left. </c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="21" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:1; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="22" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Give students the opportunity to choose one picture that they would like to solve as a puzzle. (Students can work in pairs or independently, whichever you think is better.)</c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="23" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:1; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="24" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Students who complete their puzzle should go around and help their peers who are still working on the puzzle.</c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="25" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:1; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="26" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">After students play the game, encourage them to discuss how they solved the puzzle. Ask them to identify what worked and what didn’t work. Give students a chance to discuss the things they found difficult or frustrating.</c></p>
+<p style="Normal" xid="27" props="text-align:left; line-height:1.0; dom-dir:ltr"></p>
+<p style="Normal" xid="28" props="text-align:left; line-height:1.0; dom-dir:ltr"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic; font-weight:bold">Extended Activity</c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">: Now that students know how to play with the puzzle, your class can have a contest.<br/></c></p>
+<p level="1" listid="1001" parentid="0" style="Normal" xid="29" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:1; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="30" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Each computer has a timer. Point out the timer to the students, and explain to them how to use it.</c></p>
+<p level="1" listid="1002" parentid="0" style="Normal" xid="31" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:2; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="32" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Tell students that they will be playing the Slider Puzzle, but this time they will be timed and the student who finishes first (in the shortest time) will be the winner.</c></p>
+<p style="Normal" xid="33" props="text-align:left; tabstops:0.5000in/L; text-indent:-0.2500in; line-height:1.0; dom-dir:ltr; margin-left:0.2500in"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Once a student wins, have him/her tell the class what strategy they used to solve the puzzle quickly. Ask the student what he or she thought about the puzzle.</c></p>
+<p level="1" listid="1003" parentid="0" style="Normal" xid="34" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:4; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="35" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Give the other students a chance to discuss how their puzzle solving skills have improved since the first time they played.</c></p>
+<p xid="36"></p>
+</section>
+</abiword>
diff --git a/lessons/Lesson 4/default.abw b/lessons/Lesson 4/default.abw
new file mode 100644
index 0000000..da97de9
--- /dev/null
+++ b/lessons/Lesson 4/default.abw
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE abiword PUBLIC "-//ABISOURCE//DTD AWML 1.0 Strict//EN" "http://www.abisource.com/awml.dtd">
+<abiword template="false" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:math="http://www.w3.org/1998/Math/MathML" xid-max="36" xmlns:dc="http://purl.org/dc/elements/1.1/" fileformat="1.1" xmlns:svg="http://www.w3.org/2000/svg" xmlns:awml="http://www.abisource.com/awml.dtd" xmlns="http://www.abisource.com/awml.dtd" xmlns:xlink="http://www.w3.org/1999/xlink" version="2.4.6" xml:space="preserve" props="dom-dir:ltr; document-footnote-restart-section:0; document-endnote-type:numeric; document-endnote-place-enddoc:1; document-endnote-initial:1; lang:en-US; document-endnote-restart-section:0; document-footnote-restart-page:0; document-footnote-type:numeric; document-footnote-initial:1; document-endnote-place-endsection:0">
+<!-- ======================================================================== -->
+<!-- This file is an AbiWord document. -->
+<!-- AbiWord is a free, Open Source word processor. -->
+<!-- More information about AbiWord is available at http://www.abisource.com/ -->
+<!-- You should not edit this file by hand. -->
+<!-- ======================================================================== -->
+
+<metadata>
+<m key="dc.format">application/x-abiword</m>
+<m key="abiword.generator">AbiWord</m>
+</metadata>
+<history version="1" edit-time="49" last-saved="1181641526" uid="88d13a24-18c9-11dc-9a12-98843cc1b3a3">
+<version id="1" started="1181641526" uid="a5f38efe-18c9-11dc-9a12-98843cc1b3a3" auto="0" top-xid="36"/>
+</history>
+<styles>
+<s type="P" name="Normal" followedby="Normal" props="text-indent:0in; margin-top:0pt; margin-left:0pt; font-stretch:normal; line-height:1.0; text-align:left; bgcolor:transparent; lang:en-US; dom-dir:ltr; margin-bottom:0pt; font-weight:normal; text-decoration:none; font-variant:normal; color:000000; text-position:normal; font-size:12pt; margin-right:0pt; font-style:normal; widows:2; font-family:Times New Roman"/>
+<s type="P" name="Table Normal" followedby="Table Normal" props="font-family:Times New Roman; font-size:12pt; dom-dir:ltr; lang:en-US; orphans:0; text-align:left; widows:0"/>
+</styles>
+<lists>
+<l id="1000" parentid="0" type="0" start-value="1" list-delim="%L)" list-decimal="."/>
+<l id="1001" parentid="0" type="0" start-value="1" list-delim="%L)" list-decimal="."/>
+<l id="1002" parentid="0" type="0" start-value="2" list-delim="%L)" list-decimal="."/>
+<l id="1003" parentid="0" type="0" start-value="4" list-delim="%L)" list-decimal="."/>
+</lists>
+<pagesize pagetype="Letter" orientation="portrait" width="8.500000" height="11.000000" units="in" page-scale="1.000000"/>
+<section xid="1" props="page-margin-right:1.2500in; section-restart-value:1; dom-dir:ltr; section-space-after:0.0000in; page-margin-footer:0.5000in; page-margin-header:0.5000in; page-margin-left:1.2500in; page-margin-top:1.0000in; page-margin-bottom:1.0000in">
+<p style="Normal" xid="2" props="text-align:left; line-height:1.0; dom-dir:ltr"><c props="lang:en-US; font-weight:bold; font-size:12pt; font-family:Century Gothic; text-decoration:underline">Lesson 1: Explore the Slider Puzzle</c></p>
+<p style="Normal" xid="3" props="text-align:left; line-height:1.0; dom-dir:ltr"></p>
+<p style="Normal" xid="4" props="text-align:left; line-height:1.0; dom-dir:ltr"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic; font-weight:bold">Objective: </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">To learn how to play a digital Slider Puzzle.</c></p>
+<p style="Normal" xid="5" props="text-align:left; line-height:1.0; dom-dir:ltr"></p>
+<p style="Normal" xid="6" props="text-align:left; line-height:1.0; dom-dir:ltr"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic; font-weight:bold">Specific Goals/Skills</c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">:</c></p>
+<p style="Normal" xid="7" props="margin-left:0.5000in; tabstops:0.5000in/L; dom-dir:ltr; text-indent:-0.2500in; line-height:1.0; text-align:left; margin-right:-0.5000in"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Practice problem solving and building strategies to find a solution.</c></p>
+<p style="Normal" xid="8" props="text-align:left; tabstops:0.5000in/L; text-indent:-0.2500in; line-height:1.0; dom-dir:ltr; margin-left:0.5000in"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Learn how to help peers understand an idea.</c></p>
+<p style="Normal" xid="9" props="text-align:left; tabstops:0.5000in/L; text-indent:-0.2500in; line-height:1.0; dom-dir:ltr; margin-left:0.5000in"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Learn from classmates.</c></p>
+<p style="Normal" xid="10" props="text-align:left; tabstops:0.5000in/L; text-indent:-0.2500in; line-height:1.0; dom-dir:ltr; margin-left:0.5000in"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Practice discussing thought processes around problem solving.</c></p>
+<p style="Normal" xid="11" props="text-align:left; line-height:1.0; dom-dir:ltr"></p>
+<p style="Normal" xid="12" props="text-align:left; line-height:1.0; dom-dir:ltr"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic; font-weight:bold">Steps:</c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="13" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:1; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="14" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Show the students to open the Slider Puzzle from the MaMaMedia menu screen. Demonstrate this on your own computer in the front of the class. </c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="15" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:1; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="16" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Explain to students how they can look at all the available subjects and pictures. </c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="17" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:1; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="18" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Explain that the goal of this puzzle is to create a complete picture, which will be identical to the one they see on the left of their screen. </c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="19" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:1; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="20" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Demonstrate for students how they can move a square up, down, to the right and then to the left. </c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="21" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:1; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="22" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Give students the opportunity to choose one picture that they would like to solve as a puzzle. (Students can work in pairs or independently, whichever you think is better.)</c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="23" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:1; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="24" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Students who complete their puzzle should go around and help their peers who are still working on the puzzle.</c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="25" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:1; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="26" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">After students play the game, encourage them to discuss how they solved the puzzle. Ask them to identify what worked and what didn’t work. Give students a chance to discuss the things they found difficult or frustrating.</c></p>
+<p style="Normal" xid="27" props="text-align:left; line-height:1.0; dom-dir:ltr"></p>
+<p style="Normal" xid="28" props="text-align:left; line-height:1.0; dom-dir:ltr"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic; font-weight:bold">Extended Activity</c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">: Now that students know how to play with the puzzle, your class can have a contest.<br/></c></p>
+<p level="1" listid="1001" parentid="0" style="Normal" xid="29" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:1; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="30" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Each computer has a timer. Point out the timer to the students, and explain to them how to use it.</c></p>
+<p level="1" listid="1002" parentid="0" style="Normal" xid="31" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:2; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="32" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Tell students that they will be playing the Slider Puzzle, but this time they will be timed and the student who finishes first (in the shortest time) will be the winner.</c></p>
+<p style="Normal" xid="33" props="text-align:left; tabstops:0.5000in/L; text-indent:-0.2500in; line-height:1.0; dom-dir:ltr; margin-left:0.2500in"><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Once a student wins, have him/her tell the class what strategy they used to solve the puzzle quickly. Ask the student what he or she thought about the puzzle.</c></p>
+<p level="1" listid="1003" parentid="0" style="Normal" xid="34" props="margin-left:0.2500in; tabstops:0.5000in/L; dom-dir:ltr; field-font:Times New Roman; start-value:4; line-height:1.0; text-align:left; text-indent:-0.2500in; list-style:Numbered List"><field type="list_label" xid="35" props="text-decoration:none"></field><c props="text-decoration:none"> </c><c props="lang:en-US; font-size:12pt; font-family:Century Gothic">Give the other students a chance to discuss how their puzzle solving skills have improved since the first time they played.</c></p>
+<p xid="36"></p>
+</section>
+</abiword>
diff --git a/texts/lesson_plan.abw b/lessons/lesson_plan.abw
index 0c78a51..0c78a51 100644
--- a/texts/lesson_plan.abw
+++ b/lessons/lesson_plan.abw
diff --git a/texts/lesson_plan_pt.abw b/lessons/lesson_plan_pt.abw
index cf94e2f..cf94e2f 100644
--- a/texts/lesson_plan_pt.abw
+++ b/lessons/lesson_plan_pt.abw
diff --git a/locale/org.worldwideworkshop.olpc.SliderPuzzle.pot b/locale/org.worldwideworkshop.olpc.SliderPuzzle.pot
index 4531401..be88784 100644
--- a/locale/org.worldwideworkshop.olpc.SliderPuzzle.pot
+++ b/locale/org.worldwideworkshop.olpc.SliderPuzzle.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-05-31 00:30+0100\n"
+"POT-Creation-Date: 2007-06-12 14:21+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -16,150 +16,198 @@ msgstr ""
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
-#: SliderPuzzleActivity.py:15
+#: SliderPuzzleActivity.py:24
msgid "SliderPuzzle"
msgstr ""
-#: SliderPuzzleUI.py:402
-msgid "Slider Puzzle Toolbar"
+#: SliderPuzzleUI.py:608
+msgid "Solve"
msgstr ""
-#: SliderPuzzleUI.py:450
-msgid "My Own Picture"
+#: SliderPuzzleUI.py:612
+msgid "Shuffle"
msgstr ""
-#: SliderPuzzleUI.py:454
-msgid "Solve"
+#: SliderPuzzleUI.py:616
+msgid "My Own Picture"
msgstr ""
-#: SliderPuzzleUI.py:458
-msgid "Jumble"
+#: SliderPuzzleUI.py:653
+msgid "Time: "
msgstr ""
-#: SliderPuzzleUI.py:467
-msgid "Time: "
+#: SliderPuzzleUI.py:658 SliderPuzzleUI.py:787
+msgid "Lesson Plan"
msgstr ""
-#: SliderPuzzleUI.py:517
+#: SliderPuzzleUI.py:683
msgid "Slider Puzzle Activity"
msgstr ""
-#: SliderPuzzleUI.py:566
-msgid "Select Image Category"
+#: SliderPuzzleUI.py:737
+msgid "Choose a Subject"
msgstr ""
-#: SliderPuzzleUI.py:577
+#: SliderPuzzleUI.py:748
msgid "Image Files"
msgstr ""
-#: SliderPuzzleUI.py:579
+#: SliderPuzzleUI.py:750
msgid "Select Image File"
msgstr ""
-#: SliderPuzzleUI.py:592
+#: SliderPuzzleUI.py:766
msgid "Not a valid image file"
msgstr ""
-#: i18n.py:35
+#: SliderPuzzleUI.py:793
+msgid "Close Lesson"
+msgstr ""
+
+#: i18n.py:39
msgid "Chinese (simplified)"
msgstr ""
-#: i18n.py:36
+#: i18n.py:40
msgid "Chinese (traditional)"
msgstr ""
-#: i18n.py:37
+#: i18n.py:41
msgid "Czech"
msgstr ""
-#: i18n.py:38
+#: i18n.py:42
msgid "Danish"
msgstr ""
-#: i18n.py:39
+#: i18n.py:43
msgid "Dutch"
msgstr ""
-#: i18n.py:40
+#: i18n.py:44
msgid "English"
msgstr ""
-#: i18n.py:41
+#: i18n.py:45
msgid "English - Great Britain"
msgstr ""
-#: i18n.py:42
+#: i18n.py:46
msgid "English - U.S."
msgstr ""
-#: i18n.py:43
+#: i18n.py:47
msgid "Finnish"
msgstr ""
-#: i18n.py:44
+#: i18n.py:48
msgid "French"
msgstr ""
-#: i18n.py:45
+#: i18n.py:49
msgid "German"
msgstr ""
-#: i18n.py:46
+#: i18n.py:50
msgid "Hungarian"
msgstr ""
-#: i18n.py:47
+#: i18n.py:51
msgid "Italian"
msgstr ""
-#: i18n.py:48
+#: i18n.py:52
msgid "Japanese"
msgstr ""
-#: i18n.py:49
+#: i18n.py:53
msgid "Korean"
msgstr ""
-#: i18n.py:50
+#: i18n.py:54
msgid "Norwegian"
msgstr ""
-#: i18n.py:51
+#: i18n.py:55
msgid "Polish"
msgstr ""
-#: i18n.py:52
+#: i18n.py:56
msgid "Portuguese"
msgstr ""
-#: i18n.py:53
+#: i18n.py:57
msgid "Portuguese - Brazilian"
msgstr ""
-#: i18n.py:54
+#: i18n.py:58
msgid "Russian"
msgstr ""
-#: i18n.py:55
+#: i18n.py:59
msgid "Slovak"
msgstr ""
-#: i18n.py:56
+#: i18n.py:60
msgid "Spanish"
msgstr ""
-#: i18n.py:57
+#: i18n.py:61
msgid "Swedish"
msgstr ""
-#: i18n.py:58
+#: i18n.py:62
msgid "Turkish"
msgstr ""
-#: toolbar.py:74
-msgid "Lesson Plan"
+#: i18n_misc_strings.py:1
+msgid "Sea Life"
+msgstr ""
+
+#: i18n_misc_strings.py:2
+msgid "Animals"
+msgstr ""
+
+#: i18n_misc_strings.py:3
+msgid "Birds"
+msgstr ""
+
+#: i18n_misc_strings.py:4
+msgid "XO"
+msgstr ""
+
+#: i18n_misc_strings.py:5
+msgid "Sports"
+msgstr ""
+
+#: i18n_misc_strings.py:6
+msgid "My Own Pictures"
+msgstr ""
+
+#: i18n_misc_strings.py:7
+msgid "Insects"
+msgstr ""
+
+#: i18n_misc_strings.py:8
+msgid "Music"
+msgstr ""
+
+#: i18n_misc_strings.py:9
+msgid "Space"
+msgstr ""
+
+#: i18n_misc_strings.py:10
+msgid "Lesson 4"
+msgstr ""
+
+#: i18n_misc_strings.py:11
+msgid "Lesson 3"
+msgstr ""
+
+#: i18n_misc_strings.py:12
+msgid "Lesson 1"
msgstr ""
-#: toolbar.py:79
-msgid "Dismiss"
+#: i18n_misc_strings.py:13
+msgid "Lesson 2"
msgstr ""
diff --git a/locale/pt/LC_MESSAGES/org.worldwideworkshop.olpc.SliderPuzzle.mo b/locale/pt/LC_MESSAGES/org.worldwideworkshop.olpc.SliderPuzzle.mo
index c342076..24655fd 100644
--- a/locale/pt/LC_MESSAGES/org.worldwideworkshop.olpc.SliderPuzzle.mo
+++ b/locale/pt/LC_MESSAGES/org.worldwideworkshop.olpc.SliderPuzzle.mo
Binary files differ
diff --git a/locale/pt/LC_MESSAGES/pt.po b/locale/pt/LC_MESSAGES/pt.po
index fa80699..dba64b9 100644
--- a/locale/pt/LC_MESSAGES/pt.po
+++ b/locale/pt/LC_MESSAGES/pt.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-05-31 00:30+0100\n"
+"POT-Creation-Date: 2007-06-12 14:21+0100\n"
"PO-Revision-Date: 2007-05-23 10:48+0100\n"
"Last-Translator: Carlos Neves <cn@sueste>\n"
"Language-Team: Portuguese <info@worldwideworkshop.org>\n"
@@ -17,154 +17,198 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: SliderPuzzleActivity.py:15
+#: SliderPuzzleActivity.py:24
msgid "SliderPuzzle"
msgstr ""
-#: SliderPuzzleUI.py:402
-msgid "Slider Puzzle Toolbar"
-msgstr ""
-
-#: SliderPuzzleUI.py:450
-msgid "My Own Picture"
-msgstr "Minha Imagem"
-
-#: SliderPuzzleUI.py:454
+#: SliderPuzzleUI.py:608
msgid "Solve"
msgstr "Resolver"
-#: SliderPuzzleUI.py:458
-msgid "Jumble"
+#: SliderPuzzleUI.py:612
+msgid "Shuffle"
msgstr "Baralhar"
-#: SliderPuzzleUI.py:467
+#: SliderPuzzleUI.py:616
+msgid "My Own Picture"
+msgstr "Minha Imagem"
+
+#: SliderPuzzleUI.py:653
msgid "Time: "
msgstr "Tempo: "
-#: SliderPuzzleUI.py:517
+#: SliderPuzzleUI.py:658 SliderPuzzleUI.py:787
+msgid "Lesson Plan"
+msgstr "Plano de Ensino"
+
+#: SliderPuzzleUI.py:683
msgid "Slider Puzzle Activity"
msgstr ""
-#: SliderPuzzleUI.py:566
-msgid "Select Image Category"
-msgstr "Selecciona a Categoria das Imagens"
+#: SliderPuzzleUI.py:737
+msgid "Choose a Subject"
+msgstr "Escolhe um Assunto"
-#: SliderPuzzleUI.py:577
+#: SliderPuzzleUI.py:748
msgid "Image Files"
msgstr "Imagens"
-#: SliderPuzzleUI.py:579
-#, fuzzy
+#: SliderPuzzleUI.py:750
msgid "Select Image File"
-msgstr "Selecciona a Categoria das Imagens"
+msgstr "Selecciona uma Imagen"
-#: SliderPuzzleUI.py:592
+#: SliderPuzzleUI.py:766
msgid "Not a valid image file"
msgstr "Imagem inválida"
-#: i18n.py:35
+#: SliderPuzzleUI.py:793
+msgid "Close Lesson"
+msgstr "Fechar Plano"
+
+#: i18n.py:39
msgid "Chinese (simplified)"
msgstr "Chinês (simplificado)"
-#: i18n.py:36
+#: i18n.py:40
msgid "Chinese (traditional)"
msgstr "Chinês (tradicional)"
-#: i18n.py:37
+#: i18n.py:41
msgid "Czech"
msgstr "Checo"
-#: i18n.py:38
+#: i18n.py:42
msgid "Danish"
msgstr "Dinamarquês"
-#: i18n.py:39
+#: i18n.py:43
msgid "Dutch"
msgstr "Holandês"
-#: i18n.py:40
+#: i18n.py:44
msgid "English"
msgstr "Inglês"
-#: i18n.py:41
+#: i18n.py:45
msgid "English - Great Britain"
msgstr "Inglês - Reino Unido"
-#: i18n.py:42
+#: i18n.py:46
msgid "English - U.S."
msgstr "Inglês - E.U.A."
-#: i18n.py:43
+#: i18n.py:47
msgid "Finnish"
msgstr "Filandês"
-#: i18n.py:44
+#: i18n.py:48
msgid "French"
msgstr "Francês"
-#: i18n.py:45
+#: i18n.py:49
msgid "German"
msgstr "Alemão"
-#: i18n.py:46
+#: i18n.py:50
msgid "Hungarian"
msgstr "Hungaro"
-#: i18n.py:47
+#: i18n.py:51
msgid "Italian"
msgstr "Italiano"
-#: i18n.py:48
+#: i18n.py:52
msgid "Japanese"
msgstr "Japonês"
-#: i18n.py:49
+#: i18n.py:53
msgid "Korean"
msgstr "Coreano"
-#: i18n.py:50
+#: i18n.py:54
msgid "Norwegian"
msgstr "Norueguês"
-#: i18n.py:51
+#: i18n.py:55
msgid "Polish"
msgstr "Polaco"
-#: i18n.py:52
+#: i18n.py:56
msgid "Portuguese"
msgstr "Português"
-#: i18n.py:53
+#: i18n.py:57
msgid "Portuguese - Brazilian"
msgstr "Portugês - Brasil"
-#: i18n.py:54
+#: i18n.py:58
msgid "Russian"
msgstr "Russo"
-#: i18n.py:55
+#: i18n.py:59
msgid "Slovak"
msgstr "Eslovaco"
-#: i18n.py:56
+#: i18n.py:60
msgid "Spanish"
msgstr "Espanhol"
-#: i18n.py:57
+#: i18n.py:61
msgid "Swedish"
msgstr "Sueco"
-#: i18n.py:58
+#: i18n.py:62
msgid "Turkish"
msgstr "Turco"
-#: toolbar.py:74
-msgid "Lesson Plan"
-msgstr "Plano de Ensino"
+#: i18n_misc_strings.py:1
+msgid "Sea Life"
+msgstr "Vida Marinha"
+
+#: i18n_misc_strings.py:2
+msgid "Animals"
+msgstr "Animais"
+
+#: i18n_misc_strings.py:3
+msgid "Birds"
+msgstr "Pássaros"
+
+#: i18n_misc_strings.py:4
+msgid "XO"
+msgstr ""
+
+#: i18n_misc_strings.py:5
+msgid "Sports"
+msgstr "Desporto"
+
+#: i18n_misc_strings.py:6
+msgid "My Own Pictures"
+msgstr "As Minhas Imagens"
+
+#: i18n_misc_strings.py:7
+msgid "Insects"
+msgstr "Insetos"
+
+#: i18n_misc_strings.py:8
+msgid "Music"
+msgstr "Música"
+
+#: i18n_misc_strings.py:9
+msgid "Space"
+msgstr "Espaço"
+
+#: i18n_misc_strings.py:10
+msgid "Lesson 4"
+msgstr "Lição 4"
+
+#: i18n_misc_strings.py:11
+msgid "Lesson 3"
+msgstr "Lição 3"
-#: toolbar.py:79
-msgid "Dismiss"
-msgstr "Fechar"
+#: i18n_misc_strings.py:12
+msgid "Lesson 1"
+msgstr "Lição 1"
-msgid "jumbler starter pics"
-msgstr "Imagens iniciais do Jumbler"
+#: i18n_misc_strings.py:13
+msgid "Lesson 2"
+msgstr "Lição 2"
diff --git a/toolbar.py b/toolbar.py
index 54b4944..faed768 100644
--- a/toolbar.py
+++ b/toolbar.py
@@ -21,6 +21,8 @@
### author: Carlos Neves (cn (at) sueste.net)
### (c) 2007 World Wide Workshop Foundation
+raise RuntimeError('not to be used for now')
+
import gtk
import gettext
import locale