Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMorgan Collett <morgan.collett@gmail.com>2007-07-28 10:51:01 (GMT)
committer Morgan Collett <morgan.collett@gmail.com>2007-07-28 10:51:01 (GMT)
commit0351c26fdd0484ca20521a8f9730f2930870a439 (patch)
tree311982901084b953914d2d2e2c6cf800f12edd2c
Initial import
-rw-r--r--.gitignore5
-rw-r--r--GameLogoCharacter.pngbin0 -> 15307 bytes
-rw-r--r--MANIFEST8
-rw-r--r--NEWS4
-rw-r--r--activity/activity-poll.svg65
-rw-r--r--activity/activity.info7
-rw-r--r--i18n.py161
-rw-r--r--i18n_misc_strings.py5
-rw-r--r--lessons/Introduction/default.abw51
-rw-r--r--lessons/Lesson 1/default.abw52
-rw-r--r--lessons/Lesson 2/default.abw55
-rw-r--r--lessons/Lesson 3/default.abw42
-rw-r--r--lessons/Lesson 4/default.abw46
-rw-r--r--locale/af.po218
-rw-r--r--locale/org.worldwideworkshop.poll.pot217
-rw-r--r--poll.py1352
-rwxr-xr-xsetup.py4
-rw-r--r--tubeconn.py107
18 files changed, 2399 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..189a057
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+*.pyc
+.bzr
+.bzrignore
+*.swp
+*.xo
diff --git a/GameLogoCharacter.png b/GameLogoCharacter.png
new file mode 100644
index 0000000..b8887c2
--- /dev/null
+++ b/GameLogoCharacter.png
Binary files differ
diff --git a/MANIFEST b/MANIFEST
new file mode 100644
index 0000000..386a3b3
--- /dev/null
+++ b/MANIFEST
@@ -0,0 +1,8 @@
+poll.py
+i18n.py
+GameLogoCharacter.png
+lessons/Lesson 1/default.abw
+lessons/Lesson 2/default.abw
+lessons/Lesson 3/default.abw
+lessons/Lesson 4/default.abw
+locale/org.worldwideworkshop.poll.pot
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..92fb1f9
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,4 @@
+4
+
+* Better icon since it is displayed in the mesh view
+* Mesh collaboration functionality
diff --git a/activity/activity-poll.svg b/activity/activity-poll.svg
new file mode 100644
index 0000000..7f3d8eb
--- /dev/null
+++ b/activity/activity-poll.svg
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
+ <!ENTITY ns_svg "http://www.w3.org/2000/svg">
+ <!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
+ <!ENTITY stroke_color "#000000">
+ <!ENTITY fill_color "#AAAAAA">
+]>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ id="Icon"
+ width="45"
+ height="45"
+ viewBox="0 0 45 45"
+ overflow="visible"
+ enable-background="new 0 0 45 45"
+ xml:space="preserve"
+ sodipodi:version="0.32"
+ inkscape:version="0.45"
+ sodipodi:docname="new.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ sodipodi:docbase="/home/morgan/wwwf/projects/ksp/poll-activity/activity"
+ sodipodi:modified="true"><metadata
+ id="metadata86"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs84" /><sodipodi:namedview
+ inkscape:window-height="480"
+ inkscape:window-width="640"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ guidetolerance="10.0"
+ gridtolerance="10.0"
+ objecttolerance="10.0"
+ borderopacity="1.0"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base" />
+<rect
+ style="fill:&fill_color;;stroke:&stroke_color;;stroke-width:3.5;"
+ id="rect1"
+ width="18"
+ height="18"
+ x="7"
+ y="1" />
+<rect
+ style="fill:&fill_color;;stroke:&stroke_color;;stroke-width:3.5;"
+ id="rect2"
+ width="18"
+ height="18"
+ x="7"
+ y="25" />
+<path d="M 7,25 L 25,43" style="stroke:&stroke_color;;stroke-width:3.5" />
+<path d="M 25,25 L 7,43" style="stroke:&stroke_color;;stroke-width:3.5" />
+<path
+ id="Pencil"
+ d="M 31.33613,11.694477 L 21.14313,25.189477 L 19.05513,27.906477 L 15.57913,36.173477 C 15.53313,36.277477 15.56113,36.396477 15.64813,36.468477 C 15.73713,36.539477 15.85913,36.552477 15.95513,36.488477 L 23.78113,31.451477 C 23.79313,31.443477 23.79313,31.424477 23.80313,31.408477 C 23.86713,31.359477 23.94513,31.316477 23.99813,31.246477 C 24.00213,31.244477 24.03213,31.205477 24.03213,31.197477 L 25.86313,28.926477 L 31.33213,21.872477 L 39.34413,11.543477 C 39.36513,11.520477 39.49213,11.340477 39.49213,11.340477 C 39.58913,11.179477 39.64013,10.995477 39.64013,10.784477 C 39.64013,10.723477 39.64013,10.666477 39.62813,10.608477 C 39.54013,9.8454766 38.91213,8.9264766 37.98813,8.1954766 C 37.06513,7.4674766 36.01913,7.0724766 35.26013,7.1614766 C 34.93413,7.2034766 34.47113,7.5364766 34.47113,7.5364766 L 31.33613,11.694477 z "
+ style="fill:&fill_color;;stroke:&stroke_color;;stroke-width:3.5" />
+</svg>
diff --git a/activity/activity.info b/activity/activity.info
new file mode 100644
index 0000000..2923eca
--- /dev/null
+++ b/activity/activity.info
@@ -0,0 +1,7 @@
+[Activity]
+name = Poll
+service_name = org.worldwideworkshop.PollBuilder
+class = poll.PollBuilder
+icon = activity-poll
+activity_version = 4
+show_launcher = no
diff --git a/i18n.py b/i18n.py
new file mode 100644
index 0000000..c393db1
--- /dev/null
+++ b/i18n.py
@@ -0,0 +1,161 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+
+### SliderPuzzeUI
+### TODO: Describe
+### $Id: $
+###
+### author: Carlos Neves (cn (at) sueste.net)
+### (c) 2007 World Wide Workshop Foundation
+
+import os
+import gettext
+import locale
+
+import gtk, gobject
+
+_ = lambda x: x
+
+# Images were taken from http://www.sodipodi.com/
+# except for korea taken from http://zh.wikipedia.org/wiki/Image:Unification_flag_of_Korea.svg
+
+lang_name_mapping = {
+ 'zh_cn':(None, _('Chinese (simplified)'), 'china'),
+ 'zh_tw':(None, _('Chinese (traditional)'), 'china'),
+ 'cs':(None, _('Czech'),'czech_republic'),
+ 'da':(None, _('Danish'),'denmark'),
+ 'nl':(None, _('Dutch'), 'netherlands'),
+ 'en':('English', _('English'),'united_states'),
+ 'en_gb':('English', _('English - Great Britain'),'united_kingdom'),
+ 'en_us':('English', _('English - U.S.'),'united_states'),
+ 'fi':(None, _('Finnish'),'finland'),
+ 'fr':('Français', _('French'),'france'),
+ 'de':(None, _('German'),'germany'),
+ 'hu':(None, _('Hungarian'),'hungary'),
+ 'it':(None, _('Italian'),'italy'),
+ 'ja':(None, _('Japanese'),'japan'),
+ 'ko':(None, _('Korean'),'korea'),
+ 'no':(None, _('Norwegian'),'norway'),
+ 'pl':(None, _('Polish'),'poland'),
+ 'pt':('Português', _('Portuguese'),'portugal'),
+ 'pt_br':('Português do Brasil', _('Portuguese - Brazilian'),'brazil'),
+ 'ru':(None, _('Russian'),'russian_federation'),
+ 'sk':(None, _('Slovak'),'slovenia'),
+ 'es':('Español', _('Spanish'),'spain'),
+ 'sv':(None, _('Swedish'),'sweden'),
+ 'tr':(None, _('Turkish'),'turkey'),
+ }
+
+class LangDetails (object):
+ def __init__ (self, code, name, image):
+ self.code = code
+ self.country_code = self.code.split('_')[0]
+ self.name = name
+ self.image = image
+
+ def guess_translation (self, fallback=False):
+ self.gnutranslation = gettext.translation('org.worldwideworkshop.olpc.SliderPuzzle', 'locale', [self.code], fallback=fallback)
+
+ def install (self):
+ self.gnutranslation.install()
+
+ def matches (self, code, exact=True):
+ if exact:
+ return code.lower() == self.code.lower()
+ return code.split('_')[0].lower() == self.country_code.lower()
+
+def get_lang_details (lang):
+ mapping = lang_name_mapping.get(lang.lower(), None)
+ if mapping is None:
+ # Try just the country code
+ lang = lang.split('_')[0]
+ mapping = lang_name_mapping.get(lang.lower(), None)
+ if mapping is None:
+ return None
+ if mapping[0] is None:
+ return LangDetails(lang, mapping[1], mapping[2])
+ return LangDetails(lang, mapping[0], mapping[2])
+
+def list_available_translations ():
+ rv = [get_lang_details('en')]
+ rv[0].guess_translation(True)
+ for i,x in enumerate([x for x in os.listdir('locale') if os.path.isdir('locale/' + x) and not x.startswith('.')]):
+ try:
+ details = get_lang_details(x)
+ if details is not None:
+ details.guess_translation()
+ rv.append(details)
+ except:
+ raise
+ pass
+ return rv
+
+class LanguageComboBox (gtk.ComboBox):
+ def __init__ (self):
+ liststore = gtk.ListStore(gobject.TYPE_STRING)
+ gtk.ComboBox.__init__(self, liststore)
+
+ self.cell = gtk.CellRendererText()
+ self.pack_start(self.cell, True)
+ self.add_attribute(self.cell, 'text', 0)
+
+ self.translations = list_available_translations()
+ for i,x in enumerate(self.translations):
+ liststore.insert(i+1, (gettext.gettext(x.name), ))
+ self.connect('changed', self.install)
+
+ def modify_bg (self, state, color):
+ setattr(self.cell, 'background-gdk',color)
+ setattr(self.cell, 'background-set',True)
+
+ def install (self, *args):
+ if self.get_active() > -1:
+ self.translations[self.get_active()].install()
+ else:
+ code, encoding = locale.getdefaultlocale()
+ # Try to find the exact translation
+ for i,t in enumerate(self.translations):
+ if t.matches(code):
+ self.set_active(i)
+ break
+ if self.get_active() < 0:
+ # Failed, try to get the translation based only in the country
+ for i,t in enumerate(self.translations):
+ if t.matches(code, False):
+ self.set_active(i)
+ break
+ if self.get_active() < 0:
+ # nothing found, select first translation
+ 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.py', '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..d31a70e
--- /dev/null
+++ b/i18n_misc_strings.py
@@ -0,0 +1,5 @@
+_("Lesson 1")
+_("Lesson 2")
+_("Lesson 3")
+_("Lesson 4")
+_("Introduction")
diff --git a/lessons/Introduction/default.abw b/lessons/Introduction/default.abw
new file mode 100644
index 0000000..6fddc6a
--- /dev/null
+++ b/lessons/Introduction/default.abw
@@ -0,0 +1,51 @@
+<?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" styles="unlocked" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg" xid-max="33" xmlns:dc="http://purl.org/dc/elements/1.1/" fileformat="1.1" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:awml="http://www.abisource.com/awml.dtd" xmlns="http://www.abisource.com/awml.dtd" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.9.1" 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-ZA; 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="57" last-saved="1182178231" uid="2144d4a6-1dab-11dc-840e-ddd22c2fbabf">
+<version id="1" started="1182178231" uid="42f93024-1dab-11dc-840e-ddd22c2fbabf" auto="0" top-xid="33"/>
+</history>
+<styles>
+<s type="P" name="Normal" followedby="Current Settings" props="font-family:Times New Roman; margin-top:0pt; color:000000; margin-left:0pt; text-position:normal; widows:2; font-style:normal; text-indent:0in; font-variant:normal; margin-right:0pt; lang:en-ZA; line-height:1.0; font-size:12pt; text-decoration:none; margin-bottom:0pt; font-weight:normal; bgcolor:transparent; text-align:left; font-stretch:normal"/>
+<s type="P" name="Footer" basedon="Normal" props="lang:en-US; tabstops:3.000000in/C0,6.000000in/C0; font-family:Times New Roman; font-size:12pt"/>
+<s type="C" name="Reference" props="font-size:10pt"/>
+<s type="P" name="Table Normal" props="lang:en-US; font-size:12pt; font-family:Times New Roman"/>
+</styles>
+<lists>
+<l id="1000" parentid="0" type="5" start-value="1" 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="32" props="page-margin-footer:0.5000in; page-margin-header:0.5000in; page-margin-right:1.0000in; page-margin-left:1.0000in; page-margin-top:1.0000in; page-margin-bottom:1.0000in">
+<p style="Normal" xid="33" props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:underline "><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:underline ">Poll Builder Lesson Plans Overview</c></p>
+<p style="Normal" xid="1" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.0000in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p style="Normal" xid="2" props="font-family:Century Gothic; dom-dir:ltr; font-style:normal; margin-left:0.0000in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none">A poll is </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">a research tool</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">that helps explain what a group of people think</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> about a subject. First you present the group with a question and a set of answer choices. Then each person in the group gets to vote for the answer which best describes their personal feelings or opinion. After collecting votes from the whole group, </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">you</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">look for a pattern in their answers.</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> You can also ask the same question of different groups (i.e. boys and girls or children and adults) and see how each group answers.</c></p>
+<p style="Normal" xid="3" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.0000in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p style="Normal" xid="4" props="font-family:Century Gothic; dom-dir:ltr; font-style:normal; margin-left:0.0000in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:bold; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">A poll can be used to help a community make a decision</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">and take action. </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> It can also be used to understand the similarities and differences among individuals and groups of people. </c></p>
+<p style="Normal" xid="5" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.0000in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p style="Normal" xid="6" props="font-family:Century Gothic; dom-dir:ltr; font-style:normal; margin-left:0.0000in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none">Polls are a helpful tool for any research project. </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">Use this Poll tool and lesson plans with whatever subject you are studying.</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> It can also be used to make collaborative decisions in the classroom about academic activities and among friends about social issues. </c></p>
+<p style="Normal" xid="7" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.0000in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p style="Normal" xid="8" props="font-family:Century Gothic; dom-dir:ltr; font-style:normal; margin-left:0.0000in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:bold; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">Skills</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none">: </c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="9" props="text-decoration:none; text-indent:-0.2500in; field-font:Symbol; margin-top:0.0000in; margin-left:0.5000in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Bullet List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:-0.5000in; font-style:normal; tabstops:0.500000in/L0; list-delim:%L; font-family:Times New Roman"><field type="list_label" xid="21" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:normal; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> Learn what a poll is and how it works.</c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="10" props="text-decoration:none; text-indent:-0.2500in; field-font:Symbol; margin-top:0.0000in; margin-left:0.5000in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Bullet List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:-0.5000in; font-style:normal; tabstops:0.500000in/L0; list-delim:%L; font-family:Times New Roman"><field type="list_label" xid="22" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:normal; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> Learn how to use polls to gather information and make decisions.</c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="11" props="text-decoration:none; text-indent:-0.2500in; field-font:Symbol; margin-top:0.0000in; margin-left:0.5000in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Bullet List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:-0.5000in; font-style:normal; tabstops:0.500000in/L0; list-delim:%L; font-family:Times New Roman"><field type="list_label" xid="23" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:normal; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> Practice choosing poll subjects.</c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="12" props="text-decoration:none; text-indent:-0.2500in; field-font:Symbol; margin-top:0.0000in; margin-left:0.5000in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Bullet List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:-0.5000in; font-style:normal; tabstops:0.500000in/L0; list-delim:%L; font-family:Times New Roman"><field type="list_label" xid="24" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:normal; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> Learn how to formulate good poll questions and answer choices.</c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="13" props="text-decoration:none; text-indent:-0.2500in; field-font:Symbol; margin-top:0.0000in; margin-left:0.5000in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Bullet List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:-0.5000in; font-style:normal; tabstops:0.500000in/L0; list-delim:%L; font-family:Times New Roman"><field type="list_label" xid="25" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:normal; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> Practice basic survey skills of data collection, analysis and presentation.</c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="14" props="text-decoration:none; text-indent:-0.2500in; field-font:Symbol; margin-top:0.0000in; margin-left:0.5000in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Bullet List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:-0.5000in; font-style:normal; tabstops:0.500000in/L0; list-delim:%L; font-family:Times New Roman"><field type="list_label" xid="26" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:normal; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> Learn how to use a bar graph to represent votes and opinions.</c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="15" props="text-decoration:none; text-indent:-0.2500in; field-font:Symbol; margin-top:0.0000in; margin-left:0.5000in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Bullet List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:-0.5000in; font-style:normal; tabstops:0.500000in/L0; list-delim:%L; font-family:Times New Roman"><field type="list_label" xid="27" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:normal; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> Learn how to represent poll results using ratios and percentages.</c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="16" props="text-decoration:none; text-indent:-0.2500in; field-font:Symbol; margin-top:0.0000in; margin-left:0.5000in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Bullet List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; tabstops:0.500000in/L0; list-delim:%L; font-family:Times New Roman"><field type="list_label" xid="28" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:normal; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> Learn how to help peers understand an idea or an opinion.</c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="17" props="text-decoration:none; text-indent:-0.2500in; field-font:Symbol; margin-top:0.0000in; margin-left:0.5000in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Bullet List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; tabstops:0.500000in/L0; list-delim:%L; font-family:Times New Roman"><field type="list_label" xid="29" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:normal; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> Learn from classmates.</c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="18" props="text-decoration:none; text-indent:-0.2500in; field-font:Symbol; margin-top:0.0000in; margin-left:0.5000in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Bullet List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; tabstops:0.500000in/L0; list-delim:%L; font-family:Times New Roman"><field type="list_label" xid="30" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:normal; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> Learn how to present poll results and make collaborative decisions based on those results.</c></p>
+<p level="1" listid="1000" parentid="0" style="Normal" xid="19" props="text-decoration:none; text-indent:-0.2500in; field-font:Symbol; margin-top:0.0000in; margin-left:0.5000in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Bullet List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; tabstops:0.500000in/L0; list-delim:%L; font-family:Times New Roman"><field type="list_label" xid="31" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:normal; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> Practice using new functions and features of the XO Laptop.</c></p>
+<p style="Normal" xid="20" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.0000in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+</section>
+</abiword>
diff --git a/lessons/Lesson 1/default.abw b/lessons/Lesson 1/default.abw
new file mode 100644
index 0000000..f9b3df0
--- /dev/null
+++ b/lessons/Lesson 1/default.abw
@@ -0,0 +1,52 @@
+<?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" styles="unlocked" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg" xid-max="33" xmlns:dc="http://purl.org/dc/elements/1.1/" fileformat="1.1" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:awml="http://www.abisource.com/awml.dtd" xmlns="http://www.abisource.com/awml.dtd" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.9.1" 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-ZA; 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="21" last-saved="1182178256" uid="451acdc2-1dab-11dc-840e-ddd22c2fbabf">
+<version id="1" started="1182178256" uid="5219a76e-1dab-11dc-840e-ddd22c2fbabf" auto="0" top-xid="33"/>
+</history>
+<styles>
+<s type="P" name="Normal" followedby="Current Settings" props="font-family:Times New Roman; margin-top:0pt; color:000000; margin-left:0pt; text-position:normal; widows:2; font-style:normal; text-indent:0in; font-variant:normal; margin-right:0pt; lang:en-ZA; line-height:1.0; font-size:12pt; text-decoration:none; margin-bottom:0pt; font-weight:normal; bgcolor:transparent; text-align:left; font-stretch:normal"/>
+<s type="P" name="Footer" basedon="Normal" props="lang:en-US; tabstops:3.000000in/C0,6.000000in/C0; font-family:Times New Roman; font-size:12pt"/>
+<s type="C" name="Reference" props="font-size:10pt"/>
+<s type="P" name="Table Normal" props="lang:en-US; font-size:12pt; font-family:Times New Roman"/>
+</styles>
+<lists>
+<l id="1001" parentid="0" type="0" start-value="1" 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="32" props="page-margin-footer:0.5000in; page-margin-header:0.5000in; page-margin-right:1.0000in; page-margin-left:1.0000in; page-margin-top:1.0000in; page-margin-bottom:1.0000in">
+<p style="Normal" xid="33" props="font-family:Century Gothic; font-size:12pt; color:000000; text-decoration:none; text-position:normal; font-weight:normal; font-style:normal"><c props="font-family:Century Gothic; font-size:12pt; color:000000; text-decoration:underline ; text-position:normal; font-weight:bold; font-style:normal; lang:en-US">Lesson 1: Participate in a Poll</c></p>
+<p style="Normal" xid="1" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.0000in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p level="1" listid="1001" parentid="0" style="Normal" xid="2" props="text-decoration:none; text-indent:-0.2500in; field-font:Times New Roman; margin-top:0.0000in; margin-left:0.2500in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Numbered List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; tabstops:0.250000in/L0; list-delim:%L); font-family:Times New Roman"><field type="list_label" xid="22" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:normal; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; color:000000; text-decoration:underline ; text-position:normal; font-weight:bold; font-style:normal; lang:en-US"> </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none">From the Home screen of your XO, </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">click on the MaMaMedia icon</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none">.</c></p>
+<p style="Normal" xid="3" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.0000in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p level="1" listid="1001" parentid="0" style="Normal" xid="4" props="text-decoration:none; text-indent:-0.2500in; field-font:Times New Roman; margin-top:0.0000in; margin-left:0.2500in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Numbered List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; tabstops:0.250000in/L0; list-delim:%L); font-family:Times New Roman"><field type="list_label" xid="23" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:normal; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">Open the Poll Builder</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> activity from the MaMaMedia Activity Center. </c></p>
+<p style="Normal" xid="5" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.0000in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p level="1" listid="1001" parentid="0" style="Normal" xid="6" props="text-decoration:none; text-indent:-0.2500in; field-font:Times New Roman; margin-top:0.0000in; margin-left:0.2500in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Numbered List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; tabstops:0.250000in/L0; list-delim:%L); font-family:Times New Roman"><field type="list_label" xid="24" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:normal; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">Choose a Poll </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none">topic from the list, and click the “</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">VOTE</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none">” button next to it. </c></p>
+<p style="Normal" xid="7" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.0000in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p level="1" listid="1001" parentid="0" style="Normal" xid="8" props="text-decoration:none; text-indent:-0.2500in; field-font:Times New Roman; margin-top:0.0000in; margin-left:0.2500in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Numbered List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; tabstops:0.250000in/L0; list-delim:%L); font-family:Times New Roman"><field type="list_label" xid="25" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:normal; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> A Poll question and answer choices will appear. Read them carefully, then click on your favorite answer. Click the “VOTE” button to submit your answer.</c></p>
+<p style="Normal" xid="9" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.0000in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p level="1" listid="1001" parentid="0" style="Normal" xid="10" props="text-decoration:none; text-indent:-0.2500in; field-font:Times New Roman; margin-top:0.0000in; margin-left:0.2500in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Numbered List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; tabstops:0.250000in/L0; list-delim:%L); font-family:Times New Roman"><field type="list_label" xid="26" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:normal; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">After you vote, current Poll results will appear</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none">. You will see the exact number of votes cast (so far) for each answer. You will also see a bar graph that shows which answer is currently the most popular among the whole group. </c></p>
+<p style="Normal" xid="11" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.0000in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p level="1" listid="1001" parentid="0" style="Normal" xid="12" props="text-decoration:none; text-indent:-0.2500in; field-font:Times New Roman; margin-top:0.0000in; margin-left:0.2500in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Numbered List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; tabstops:0.250000in/L0; list-delim:%L); font-family:Times New Roman"><field type="list_label" xid="27" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:normal; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">Look at the number of votes next to each answer</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none">. Which one has the most votes so far? How many people chose the same answer as you? Which answer do you think will win? Why?</c></p>
+<p style="Normal" xid="13" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.0000in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p level="1" listid="1001" parentid="0" style="Normal" xid="14" props="text-decoration:none; text-indent:-0.2500in; field-font:Times New Roman; margin-top:0.0000in; margin-left:0.2500in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Numbered List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; tabstops:0.250000in/L0; list-delim:%L); font-family:Times New Roman"><field type="list_label" xid="28" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:normal; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">Look at the bar graph</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none">. Which answer has the longest bar? What does that mean? Which answer has the shortest bar? What does that mean?</c></p>
+<p style="Normal" xid="15" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.0000in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p level="1" listid="1001" parentid="0" style="Normal" xid="16" props="text-decoration:none; text-indent:-0.2500in; field-font:Times New Roman; margin-top:0.0000in; margin-left:0.2500in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Numbered List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; tabstops:0.250000in/L0; list-delim:%L); font-family:Times New Roman"><field type="list_label" xid="29" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:normal; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">Let each person in your group vote</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> in this poll. How did the votes and bar graphs change?</c></p>
+<p style="Normal" xid="17" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.0000in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p level="1" listid="1001" parentid="0" style="Normal" xid="18" props="text-decoration:none; text-indent:-0.2500in; field-font:Times New Roman; margin-top:0.0000in; margin-left:0.2500in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Numbered List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; tabstops:0.250000in/L0; list-delim:%L); font-family:Times New Roman"><field type="list_label" xid="30" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:normal; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">After everyone votes,</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">discuss the final results</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none">. What did you learn from the poll? Were you surprised by the results? How could you use this information? </c></p>
+<p style="Normal" xid="19" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.0000in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p level="1" listid="1001" parentid="0" style="Normal" xid="20" props="text-decoration:none; text-indent:-0.2500in; field-font:Times New Roman; margin-top:0.0000in; margin-left:0.2500in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Numbered List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; tabstops:0.250000in/L0; list-delim:%L); font-family:Times New Roman"><field type="list_label" xid="31" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:normal; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">Generate a list of ideas for polls</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none">. Record your ideas on a blackboard, on paper or in the “Write” program on the XO Laptop. What would you like to learn from each poll you thought of? What would you do with the results? </c></p>
+<p style="Normal" xid="21" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.0000in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+</section>
+</abiword>
diff --git a/lessons/Lesson 2/default.abw b/lessons/Lesson 2/default.abw
new file mode 100644
index 0000000..404af7e
--- /dev/null
+++ b/lessons/Lesson 2/default.abw
@@ -0,0 +1,55 @@
+<?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" styles="unlocked" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg" xid-max="36" xmlns:dc="http://purl.org/dc/elements/1.1/" fileformat="1.1" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:awml="http://www.abisource.com/awml.dtd" xmlns="http://www.abisource.com/awml.dtd" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.9.1" 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-ZA; 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="14" last-saved="1182178388" uid="9820e74a-1dab-11dc-808f-f556125eb004">
+<version id="1" started="1182178388" uid="a0a27d5c-1dab-11dc-808f-f556125eb004" auto="0" top-xid="36"/>
+</history>
+<styles>
+<s type="P" name="Normal" followedby="Current Settings" props="font-family:Times New Roman; margin-top:0pt; color:000000; margin-left:0pt; text-position:normal; widows:2; font-style:normal; text-indent:0in; font-variant:normal; margin-right:0pt; lang:en-ZA; line-height:1.0; font-size:12pt; text-decoration:none; margin-bottom:0pt; font-weight:normal; bgcolor:transparent; text-align:left; font-stretch:normal"/>
+<s type="P" name="Footer" basedon="Normal" props="lang:en-US; tabstops:3.000000in/C0,6.000000in/C0; font-family:Times New Roman; font-size:12pt"/>
+<s type="C" name="Reference" props="font-size:10pt"/>
+<s type="P" name="Table Normal" props="lang:en-US; font-size:12pt; font-family:Times New Roman"/>
+</styles>
+<lists>
+<l id="1002" parentid="0" type="0" start-value="1" 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="35" props="page-margin-footer:0.5000in; page-margin-header:0.5000in; page-margin-right:1.0000in; page-margin-left:1.0000in; page-margin-top:1.0000in; page-margin-bottom:1.0000in">
+<p style="Normal" xid="36" props="font-family:Century Gothic; font-size:12pt; color:000000; text-decoration:none; text-position:normal; font-weight:normal; font-style:normal"><c props="font-family:Century Gothic; font-size:12pt; color:000000; text-decoration:underline ; text-position:normal; font-weight:bold; font-style:normal; lang:en-US">Lesson 2: Build a Poll</c></p>
+<p style="Normal" xid="1" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.0000in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p level="1" listid="1002" parentid="0" style="Normal" xid="2" props="text-decoration:none; text-indent:-0.2500in; field-font:Times New Roman; margin-top:0.0000in; margin-left:0.2500in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Numbered List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; tabstops:0.250000in/L0; list-delim:%L; font-family:Times New Roman"><field type="list_label" xid="25" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:bold; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; color:000000; text-decoration:underline ; text-position:normal; font-weight:bold; font-style:normal; lang:en-US"> </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">Make a poll of your own!</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> The goal is to build a poll that is interesting to you, and learn to collect votes from people and reach conclusions or make decisions based on your poll. </c></p>
+<p style="Normal" xid="3" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.0000in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p style="Normal" xid="4" props="font-family:Century Gothic; dom-dir:ltr; font-style:italic; margin-left:0.5000in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:bold; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:italic; text-decoration:none">Example poll idea</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:italic; text-decoration:none">: “What is your favorite activity on the XO?” </c></p>
+<p style="Normal" xid="5" props="font-family:Century Gothic; dom-dir:ltr; font-style:normal; margin-left:0.5000in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none">You can use this poll in your classroom or your family, to find out what activity is the most favorite or popular. </c></p>
+<p style="Normal" xid="6" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.2500in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p level="1" listid="1002" parentid="0" style="Normal" xid="7" props="text-decoration:none; text-indent:-0.2500in; field-font:Times New Roman; margin-top:0.0000in; margin-left:0.2500in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Numbered List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; tabstops:0.250000in/L0; list-delim:%L; font-family:Times New Roman"><field type="list_label" xid="26" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:bold; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> Open the Poll Builder activity and </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">click on the “Build a Poll” button</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> at the bottom of the screen.</c></p>
+<p style="Normal" xid="8" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.2500in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p level="1" listid="1002" parentid="0" style="Normal" xid="9" props="text-decoration:none; text-indent:-0.2500in; field-font:Times New Roman; margin-top:0.0000in; margin-left:0.2500in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Numbered List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; tabstops:0.250000in/L0; list-delim:%L; font-family:Times New Roman"><field type="list_label" xid="27" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:bold; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">Fill in your poll details </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none">on the blank form that appears. Type in your poll title, question and answers, and the number of votes you want to collect.</c></p>
+<p style="Normal" xid="10" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.2500in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p level="1" listid="1002" parentid="0" style="Normal" xid="11" props="text-decoration:none; text-indent:-0.2500in; field-font:Times New Roman; margin-top:0.0000in; margin-left:0.2500in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Numbered List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; tabstops:0.250000in/L0; list-delim:%L; font-family:Times New Roman"><field type="list_label" xid="28" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:bold; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">Think about your “Poll Title” and “Question.”</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> The title is the name of your poll, and the question is what you want to know. In our example poll, the title is “</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:italic; text-decoration:none">Favorite Food”</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> and the question is “</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:italic; text-decoration:none">What is your favorite food?”</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> </c></p>
+<p style="Normal" xid="12" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.2500in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p level="1" listid="1002" parentid="0" style="Normal" xid="13" props="text-decoration:none; text-indent:-0.2500in; field-font:Times New Roman; margin-top:0.0000in; margin-left:0.2500in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Numbered List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; tabstops:0.250000in/L0; list-delim:%L; font-family:Times New Roman"><field type="list_label" xid="29" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:bold; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> Next </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">type in the number of votes you want to collect</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> in your poll. This number is called a “</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">sample size</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none">” by researchers. To do this correctly, think about how many people you want to poll. Is it all of the students in your class? Just the 12-year-olds? All of the people in your family? All of the women in your town? </c></p>
+<p style="Normal" xid="14" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.2500in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p level="1" listid="1002" parentid="0" style="Normal" xid="15" props="text-decoration:none; text-indent:-0.2500in; field-font:Times New Roman; margin-top:0.0000in; margin-left:0.2500in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Numbered List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; tabstops:0.250000in/L0; list-delim:%L; font-family:Times New Roman"><field type="list_label" xid="30" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:bold; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">Now type in the “Answer choices,”</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> you want people to choose from. You can offer 2, 3, 4 or 5 answer choices in this poll. In our </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:italic; text-decoration:none">Favorite Food</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> example, the answer choices could be: 1. </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:italic; text-decoration:none">Bread</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none">, 2. </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:italic; text-decoration:none">Rice</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none">, 3. </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:italic; text-decoration:none">Beans</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none">, 4. </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:italic; text-decoration:none">Candy</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none">, 5. </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:italic; text-decoration:none">Bananas</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none">.</c></p>
+<p style="Normal" xid="16" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.2500in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p level="1" listid="1002" parentid="0" style="Normal" xid="17" props="text-decoration:none; text-indent:-0.2500in; field-font:Times New Roman; margin-top:0.0000in; margin-left:0.2500in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Numbered List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; tabstops:0.250000in/L0; list-delim:%L; font-family:Times New Roman"><field type="list_label" xid="31" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:bold; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> Once you have filled in all of the “Build a Poll” fields, </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">click “Step 1:</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">Preview</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none">” </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">to see how your poll will look</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none">. </c></p>
+<p style="Normal" xid="18" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.2500in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p level="1" listid="1002" parentid="0" style="Normal" xid="19" props="text-decoration:none; text-indent:-0.2500in; field-font:Times New Roman; margin-top:0.0000in; margin-left:0.2500in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Numbered List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; tabstops:0.250000in/L0; list-delim:%L; font-family:Times New Roman"><field type="list_label" xid="32" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:bold; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> If you like how it looks, click </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">“Save Poll.”</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> </c></p>
+<p style="Normal" xid="20" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.2500in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p level="1" listid="1002" parentid="0" style="Normal" xid="21" props="text-decoration:none; text-indent:-0.2500in; field-font:Times New Roman; margin-top:0.0000in; margin-left:0.2500in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Numbered List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; tabstops:0.250000in/L0; list-delim:%L; font-family:Times New Roman"><field type="list_label" xid="33" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:bold; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> If you want to change something, click “</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">Edit Poll.”</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> You can change the information in any field. </c></p>
+<p style="Normal" xid="22" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.2500in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p level="1" listid="1002" parentid="0" style="Normal" xid="23" props="text-decoration:none; text-indent:-0.2500in; field-font:Times New Roman; margin-top:0.0000in; margin-left:0.2500in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Numbered List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; tabstops:0.250000in/L0; list-delim:%L; font-family:Times New Roman"><field type="list_label" xid="34" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:bold; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> When you are happy, </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">click “Step 2: Save Poll” -- your poll will be built.</c></p>
+<p style="Normal" xid="24" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.2500in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+</section>
+</abiword>
diff --git a/lessons/Lesson 3/default.abw b/lessons/Lesson 3/default.abw
new file mode 100644
index 0000000..4643f92
--- /dev/null
+++ b/lessons/Lesson 3/default.abw
@@ -0,0 +1,42 @@
+<?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" styles="unlocked" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg" xid-max="18" xmlns:dc="http://purl.org/dc/elements/1.1/" fileformat="1.1" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:awml="http://www.abisource.com/awml.dtd" xmlns="http://www.abisource.com/awml.dtd" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.9.1" 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-ZA; 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="15" last-saved="1182178445" uid="b9817ce2-1dab-11dc-90ea-8027ba63b26e">
+<version id="1" started="1182178445" uid="c26659f4-1dab-11dc-90ea-8027ba63b26e" auto="0" top-xid="18"/>
+</history>
+<styles>
+<s type="P" name="Normal" followedby="Current Settings" props="font-family:Times New Roman; margin-top:0pt; color:000000; margin-left:0pt; text-position:normal; widows:2; font-style:normal; text-indent:0in; font-variant:normal; margin-right:0pt; lang:en-ZA; line-height:1.0; font-size:12pt; text-decoration:none; margin-bottom:0pt; font-weight:normal; bgcolor:transparent; text-align:left; font-stretch:normal"/>
+<s type="P" name="Footer" basedon="Normal" props="lang:en-US; tabstops:3.000000in/C0,6.000000in/C0; font-family:Times New Roman; font-size:12pt"/>
+<s type="C" name="Reference" props="font-size:10pt"/>
+<s type="P" name="Table Normal" props="lang:en-US; font-size:12pt; font-family:Times New Roman"/>
+</styles>
+<lists>
+<l id="1003" parentid="0" type="0" start-value="1" 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="17" props="page-margin-footer:0.5000in; page-margin-header:0.5000in; page-margin-right:1.0000in; page-margin-left:1.0000in; page-margin-top:1.0000in; page-margin-bottom:1.0000in">
+<p style="Normal" xid="18" props="font-family:Century Gothic; font-size:12pt; color:000000; text-decoration:none; text-position:normal; font-weight:normal; font-style:normal"><c props="font-family:Century Gothic; font-size:12pt; color:000000; text-decoration:underline ; text-position:normal; font-weight:bold; font-style:normal; lang:en-US">Lesson 3: Collect Poll Data </c></p>
+<p style="Normal" xid="1" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.0000in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p level="1" listid="1003" parentid="0" style="Normal" xid="2" props="text-decoration:none; text-indent:-0.2500in; field-font:Times New Roman; margin-top:0.0000in; margin-left:0.2500in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Numbered List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; tabstops:0.250000in/L0; list-delim:%L); font-family:Times New Roman"><field type="list_label" xid="12" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:normal; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; color:000000; text-decoration:underline ; text-position:normal; font-weight:bold; font-style:normal; lang:en-US"> </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none">Now that your poll is built, </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">invite people to take your poll on the XO.</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> Walk around with your laptop, and ask people to answer your research question. </c></p>
+<p style="Normal" xid="3" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.0000in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p level="1" listid="1003" parentid="0" style="Normal" xid="4" props="text-decoration:none; text-indent:-0.2500in; field-font:Times New Roman; margin-top:0.0000in; margin-left:0.2500in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Numbered List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; tabstops:0.250000in/L0; list-delim:%L); font-family:Times New Roman"><field type="list_label" xid="13" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:normal; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">Decide how you are going to get the information you need.</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> You could read your question and the answer choices to each person and click their answer on your XO. Or, you can show each person how to select your poll from the list, read the poll by themselves and click on their answer choice by themselves. </c></p>
+<p style="Normal" xid="5" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.0000in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p level="1" listid="1003" parentid="0" style="Normal" xid="6" props="text-decoration:none; text-indent:-0.2500in; field-font:Times New Roman; margin-top:0.0000in; margin-left:0.2500in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Numbered List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; tabstops:0.250000in/L0; list-delim:%L); font-family:Times New Roman"><field type="list_label" xid="14" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:normal; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> For best results, </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">each person should</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">vote only once</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none">. The Poll will close when you reach the number of your “sample size.” </c></p>
+<p style="Normal" xid="7" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.0000in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p level="1" listid="1003" parentid="0" style="Normal" xid="8" props="text-decoration:none; text-indent:-0.2500in; field-font:Times New Roman; margin-top:0.0000in; margin-left:0.2500in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Numbered List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; tabstops:0.250000in/L0; list-delim:%L); font-family:Times New Roman"><field type="list_label" xid="15" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:normal; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">Try to collect votes from the people you originally thought about</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> when you chose the “number of votes to collect.” If it was girls, ask only girls. Otherwise your results will not reflect the group you had in mind.</c></p>
+<p style="Normal" xid="9" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.0000in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p level="1" listid="1003" parentid="0" style="Normal" xid="10" props="text-decoration:none; text-indent:-0.2500in; field-font:Times New Roman; margin-top:0.0000in; margin-left:0.2500in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Numbered List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; tabstops:0.250000in/L0; list-delim:%L); font-family:Times New Roman"><field type="list_label" xid="16" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:normal; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> Remember, </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">you can create the same poll again, and ask different kinds of people to answer</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> each time. It will be very interesting to compare the results of the same question asked to different groups, such as boys and girls or adults and children.</c></p>
+<p style="Normal" xid="11" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.0000in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+</section>
+</abiword>
diff --git a/lessons/Lesson 4/default.abw b/lessons/Lesson 4/default.abw
new file mode 100644
index 0000000..1f0f57b
--- /dev/null
+++ b/lessons/Lesson 4/default.abw
@@ -0,0 +1,46 @@
+<?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" styles="unlocked" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg" xid-max="23" xmlns:dc="http://purl.org/dc/elements/1.1/" fileformat="1.1" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:awml="http://www.abisource.com/awml.dtd" xmlns="http://www.abisource.com/awml.dtd" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.9.1" 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-ZA; 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="12" last-saved="1182178467" uid="c8c608b2-1dab-11dc-9293-8ece866e9ee6">
+<version id="1" started="1182178467" uid="cfb456e2-1dab-11dc-9293-8ece866e9ee6" auto="0" top-xid="23"/>
+</history>
+<styles>
+<s type="P" name="Normal" followedby="Current Settings" props="font-family:Times New Roman; margin-top:0pt; color:000000; margin-left:0pt; text-position:normal; widows:2; font-style:normal; text-indent:0in; font-variant:normal; margin-right:0pt; lang:en-ZA; line-height:1.0; font-size:12pt; text-decoration:none; margin-bottom:0pt; font-weight:normal; bgcolor:transparent; text-align:left; font-stretch:normal"/>
+<s type="P" name="Footer" basedon="Normal" props="lang:en-US; tabstops:3.000000in/C0,6.000000in/C0; font-family:Times New Roman; font-size:12pt"/>
+<s type="C" name="Reference" props="font-size:10pt"/>
+<s type="P" name="Table Normal" props="lang:en-US; font-size:12pt; font-family:Times New Roman"/>
+</styles>
+<lists>
+<l id="1004" parentid="0" type="0" start-value="1" 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="22" props="page-margin-footer:0.5000in; page-margin-header:0.5000in; page-margin-right:1.0000in; page-margin-left:1.0000in; page-margin-top:1.0000in; page-margin-bottom:1.0000in">
+<p style="Normal" xid="23" props="font-family:Century Gothic; font-size:12pt; color:000000; text-decoration:none; text-position:normal; font-weight:normal; font-style:normal"><c props="font-family:Century Gothic; font-size:12pt; color:000000; text-decoration:underline ; text-position:normal; font-weight:bold; font-style:normal; lang:en-US">Lesson 4: Use Data to make Observations and Decisions</c></p>
+<p style="Normal" xid="1" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.0000in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p level="1" listid="1004" parentid="0" style="Normal" xid="2" props="text-decoration:none; text-indent:-0.2500in; field-font:Times New Roman; margin-top:0.0000in; margin-left:0.2500in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Numbered List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; tabstops:0.250000in/L0; list-delim:%L); font-family:Times New Roman"><field type="list_label" xid="16" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:normal; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; color:000000; text-decoration:underline ; text-position:normal; font-weight:bold; font-style:normal; lang:en-US"> </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">After you have collected the poll data</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> you needed from one or more groups, </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">look at the results</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> and think about what they mean.</c></p>
+<p style="Normal" xid="3" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.0000in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p level="1" listid="1004" parentid="0" style="Normal" xid="4" props="text-decoration:none; text-indent:-0.2500in; field-font:Times New Roman; margin-top:0.0000in; margin-left:0.2500in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Numbered List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; tabstops:0.250000in/L0; list-delim:%L); font-family:Times New Roman"><field type="list_label" xid="17" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:normal; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> Open the Poll Builder activity on your XO and </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">find your poll</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> title on the list. </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">Click the “See Results” button</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> to see how people voted.</c></p>
+<p style="Normal" xid="5" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.0000in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p level="1" listid="1004" parentid="0" style="Normal" xid="6" props="text-decoration:none; text-indent:-0.2500in; field-font:Times New Roman; margin-top:0.0000in; margin-left:0.2500in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Numbered List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; tabstops:0.250000in/L0; list-delim:%L); font-family:Times New Roman"><field type="list_label" xid="18" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:normal; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">Look at the</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">Bar Graphs</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> that represent the votes (results) of your poll. </c></p>
+<p style="Normal" xid="7" props="font-family:Century Gothic; dom-dir:ltr; font-style:normal; margin-left:0.0000in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none">Which answer has the longest bar? What does that mean? Which answer has the shortest bar? What does that mean?</c></p>
+<p style="Normal" xid="8" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.2500in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p level="1" listid="1004" parentid="0" style="Normal" xid="9" props="text-decoration:none; text-indent:-0.2500in; field-font:Times New Roman; margin-top:0.0000in; margin-left:0.2500in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Numbered List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; list-delim:%L); font-family:Times New Roman"><field type="list_label" xid="19" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:normal; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">If you tried your poll with different groups </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none">(girls, boys, teachers, students, adults, children, etc.) Open each poll and </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">see if there are any differences.</c></p>
+<p style="Normal" xid="10" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.2500in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p level="1" listid="1004" parentid="0" style="Normal" xid="11" props="text-decoration:none; text-indent:-0.2500in; field-font:Times New Roman; margin-top:0.0000in; margin-left:0.2500in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Numbered List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; tabstops:0.250000in/L0; list-delim:%L); font-family:Times New Roman"><field type="list_label" xid="20" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:normal; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none"> Write down notes about what you see</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none">; put your findings on paper or record them with the “Write” activity on your XO. How does this kind of information help you draw conclusions about the people you surveyed? Does the data accurately represent an entire group? Does it matter if you questioned 25 people or 100 people? Why?</c></p>
+<p style="Normal" xid="12" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.2500in; lang:en-US; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p level="1" listid="1004" parentid="0" style="Normal" xid="13" props="text-decoration:none; text-indent:-0.2500in; field-font:Times New Roman; margin-top:0.0000in; margin-left:0.2500in; list-decimal:.; line-height:1.000000; text-align:left; list-style:Numbered List; lang:en-US; dom-dir:ltr; margin-bottom:0.0000in; font-weight:normal; start-value:1; text-position:normal; font-size:12pt; margin-right:0.0000in; font-style:normal; tabstops:0.250000in/L0; list-delim:%L); font-family:Times New Roman"><field type="list_label" xid="21" props="width:0in; font-family:Century Gothic; display:inline; font-style:normal; font-weight:normal; bgcolor:transparent; lang:en-US; text-position:normal; homogeneous:1; color:000000; font-variant:normal; text-decoration:none; font-size:12pt; height:0in; list-style:None; font-stretch:normal"></field><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> </c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:bold; font-style:normal; text-decoration:none">Present you findings</c><c props="font-family:Century Gothic; font-size:12pt; lang:en-US; text-position:normal; font-weight:normal; font-style:normal; text-decoration:none"> to your class, or to the people who took the poll. Tell them what you learned for the poll and discuss the results together. Brainstorm about what could be done with this information. </c></p>
+<p style="Normal" xid="14" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.2500in; lang:en-ZA; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+<p style="Normal" xid="15" props="font-family:Times New Roman; dom-dir:ltr; font-style:normal; margin-left:0.0000in; lang:en-ZA; margin-bottom:0.0000in; text-indent:0.0000in; text-position:normal; margin-top:0.0000in; font-weight:normal; margin-right:0.0000in; text-decoration:none; text-align:left; line-height:1.000000; font-size:12pt"></p>
+</section>
+</abiword>
diff --git a/locale/af.po b/locale/af.po
new file mode 100644
index 0000000..012b5c1
--- /dev/null
+++ b/locale/af.po
@@ -0,0 +1,218 @@
+# Afrikaans translation for olpc-poll-builder
+# Copyright (c) 2007 Rosetta Contributors and Canonical Ltd 2007
+# This file is distributed under the same license as the olpc-poll-builder package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2007.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: olpc-poll-builder\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2007-06-14 14:01+0200\n"
+"PO-Revision-Date: 2007-06-22 08:43+0000\n"
+"Last-Translator: Morgan Collett <morgan.collett+launchpad@gmail.com>\n"
+"Language-Team: Afrikaans <af@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Rosetta-Export-Date: 2007-06-22 08:48:10+0000\n"
+
+#: poll.py:151
+msgid "Poll Builder"
+msgstr "Verkiesing Bou"
+
+#: poll.py:178
+msgid "VOTE!"
+msgstr "STEM!"
+
+#: poll.py:180
+msgid "Poll Preview"
+msgstr "Stem Voorskou"
+
+#: poll.py:213 poll.py:989
+msgid "Choose a Poll"
+msgstr "Kies 'n Verkiesing"
+
+#: poll.py:264
+msgid "VOTE"
+msgstr "STEM"
+
+#: poll.py:266
+msgid "SEE RESULTS"
+msgstr "SIEN UITSLAE"
+
+#: poll.py:276
+msgid "DELETE"
+msgstr "UITWIS"
+
+#: poll.py:302
+msgid "Lesson Plans"
+msgstr "Les Planne"
+
+#: poll.py:454
+msgid "votes"
+msgstr "stemme"
+
+#: poll.py:470
+msgid "Vote"
+msgstr "Stem"
+
+#: poll.py:478
+msgid "Edit Poll"
+msgstr "Redigeer Verkiesing"
+
+#: poll.py:481
+msgid "Save Poll"
+msgstr "Stoor Verkiesing"
+
+#: poll.py:565 poll.py:984
+msgid "Build a Poll"
+msgstr "Bou 'n Verkiesing"
+
+#: poll.py:583
+msgid "Poll Title:"
+msgstr "Verkiesingstitel"
+
+#: poll.py:593
+msgid "Question:"
+msgstr "Vraag:"
+
+#: poll.py:603
+msgid "Number of votes to collect:"
+msgstr "Nommer stemme om te kollekteer:"
+
+#: poll.py:614
+msgid "Answer"
+msgstr "Antwoord"
+
+#: poll.py:626
+msgid "Step 1: Preview"
+msgstr "Trap 1: Voorskou"
+
+#: poll.py:629
+msgid "Step 2: Save"
+msgstr "Trap 2: Stoor"
+
+#: poll.py:706
+msgid "Favorite Color"
+msgstr "Gunstelling Kleur"
+
+#: poll.py:712
+msgid "What is your favorite color?"
+msgstr "Wat is jou gunstelling kleur?"
+
+#: poll.py:715
+msgid "Green"
+msgstr "Groen"
+
+#: poll.py:716
+msgid "Red"
+msgstr "Rooi"
+
+#: poll.py:717
+msgid "Blue"
+msgstr "Blou"
+
+#: poll.py:718
+msgid "Orange"
+msgstr "Oranje"
+
+#: poll.py:719
+msgid "None of the above"
+msgstr "Geen van die bogenoemde"
+
+#: i18n.py:39
+msgid "Chinese (simplified)"
+msgstr "Sjinees (vereenvoudig)"
+
+#: i18n.py:40
+msgid "Chinese (traditional)"
+msgstr "Sjnees (tradisioneel)"
+
+#: i18n.py:41
+msgid "Czech"
+msgstr "Tsjeggies"
+
+#: i18n.py:42
+msgid "Danish"
+msgstr "Deens"
+
+#: i18n.py:43
+msgid "Dutch"
+msgstr "Hollandse"
+
+#: i18n.py:44
+msgid "English"
+msgstr "Engels"
+
+#: i18n.py:45
+msgid "English - Great Britain"
+msgstr "Engels - GB"
+
+#: i18n.py:46
+msgid "English - U.S."
+msgstr "Engels - VSA"
+
+#: i18n.py:47
+msgid "Finnish"
+msgstr "Feense"
+
+#: i18n.py:48
+msgid "French"
+msgstr "Fraans"
+
+#: i18n.py:49
+msgid "German"
+msgstr "Duits"
+
+#: i18n.py:50
+msgid "Hungarian"
+msgstr "Hongaars"
+
+#: i18n.py:51
+msgid "Italian"
+msgstr "Italiaans"
+
+#: i18n.py:52
+msgid "Japanese"
+msgstr "Japannees"
+
+#: i18n.py:53
+msgid "Korean"
+msgstr "Koriaans"
+
+#: i18n.py:54
+msgid "Norwegian"
+msgstr "Noörwees"
+
+#: i18n.py:55
+msgid "Polish"
+msgstr "Pools"
+
+#: i18n.py:56
+msgid "Portuguese"
+msgstr "Portugees"
+
+#: i18n.py:57
+msgid "Portuguese - Brazilian"
+msgstr "Portugees - Braziliaanse"
+
+#: i18n.py:58
+msgid "Russian"
+msgstr "Russies"
+
+#: i18n.py:59
+msgid "Slovak"
+msgstr "Slovakies"
+
+#: i18n.py:60
+msgid "Spanish"
+msgstr "Spaans"
+
+#: i18n.py:61
+msgid "Swedish"
+msgstr "Sweeds"
+
+#: i18n.py:62
+msgid "Turkish"
+msgstr "Turks" \ No newline at end of file
diff --git a/locale/org.worldwideworkshop.poll.pot b/locale/org.worldwideworkshop.poll.pot
new file mode 100644
index 0000000..f919b10
--- /dev/null
+++ b/locale/org.worldwideworkshop.poll.pot
@@ -0,0 +1,217 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-06-14 14:01+0200\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"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: poll.py:151
+msgid "Poll Builder"
+msgstr ""
+
+#: poll.py:178
+msgid "VOTE!"
+msgstr ""
+
+#: poll.py:180
+msgid "Poll Preview"
+msgstr ""
+
+#: poll.py:213 poll.py:989
+msgid "Choose a Poll"
+msgstr ""
+
+#: poll.py:264
+msgid "VOTE"
+msgstr ""
+
+#: poll.py:266
+msgid "SEE RESULTS"
+msgstr ""
+
+#: poll.py:276
+msgid "DELETE"
+msgstr ""
+
+#: poll.py:302
+msgid "Lesson Plans"
+msgstr ""
+
+#: poll.py:454
+msgid "votes"
+msgstr ""
+
+#: poll.py:470
+msgid "Vote"
+msgstr ""
+
+#: poll.py:478
+msgid "Edit Poll"
+msgstr ""
+
+#: poll.py:481
+msgid "Save Poll"
+msgstr ""
+
+#: poll.py:565 poll.py:984
+msgid "Build a Poll"
+msgstr ""
+
+#: poll.py:583
+msgid "Poll Title:"
+msgstr ""
+
+#: poll.py:593
+msgid "Question:"
+msgstr ""
+
+#: poll.py:603
+msgid "Number of votes to collect:"
+msgstr ""
+
+#: poll.py:614
+msgid "Answer"
+msgstr ""
+
+#: poll.py:626
+msgid "Step 1: Preview"
+msgstr ""
+
+#: poll.py:629
+msgid "Step 2: Save"
+msgstr ""
+
+#: poll.py:706
+msgid "Favorite Color"
+msgstr ""
+
+#: poll.py:712
+msgid "What is your favorite color?"
+msgstr ""
+
+#: poll.py:715
+msgid "Green"
+msgstr ""
+
+#: poll.py:716
+msgid "Red"
+msgstr ""
+
+#: poll.py:717
+msgid "Blue"
+msgstr ""
+
+#: poll.py:718
+msgid "Orange"
+msgstr ""
+
+#: poll.py:719
+msgid "None of the above"
+msgstr ""
+
+#: i18n.py:39
+msgid "Chinese (simplified)"
+msgstr ""
+
+#: i18n.py:40
+msgid "Chinese (traditional)"
+msgstr ""
+
+#: i18n.py:41
+msgid "Czech"
+msgstr ""
+
+#: i18n.py:42
+msgid "Danish"
+msgstr ""
+
+#: i18n.py:43
+msgid "Dutch"
+msgstr ""
+
+#: i18n.py:44
+msgid "English"
+msgstr ""
+
+#: i18n.py:45
+msgid "English - Great Britain"
+msgstr ""
+
+#: i18n.py:46
+msgid "English - U.S."
+msgstr ""
+
+#: i18n.py:47
+msgid "Finnish"
+msgstr ""
+
+#: i18n.py:48
+msgid "French"
+msgstr ""
+
+#: i18n.py:49
+msgid "German"
+msgstr ""
+
+#: i18n.py:50
+msgid "Hungarian"
+msgstr ""
+
+#: i18n.py:51
+msgid "Italian"
+msgstr ""
+
+#: i18n.py:52
+msgid "Japanese"
+msgstr ""
+
+#: i18n.py:53
+msgid "Korean"
+msgstr ""
+
+#: i18n.py:54
+msgid "Norwegian"
+msgstr ""
+
+#: i18n.py:55
+msgid "Polish"
+msgstr ""
+
+#: i18n.py:56
+msgid "Portuguese"
+msgstr ""
+
+#: i18n.py:57
+msgid "Portuguese - Brazilian"
+msgstr ""
+
+#: i18n.py:58
+msgid "Russian"
+msgstr ""
+
+#: i18n.py:59
+msgid "Slovak"
+msgstr ""
+
+#: i18n.py:60
+msgid "Spanish"
+msgstr ""
+
+#: i18n.py:61
+msgid "Swedish"
+msgstr ""
+
+#: i18n.py:62
+msgid "Turkish"
+msgstr ""
diff --git a/poll.py b/poll.py
new file mode 100644
index 0000000..89711d6
--- /dev/null
+++ b/poll.py
@@ -0,0 +1,1352 @@
+# Copyright 2007 World Wide Workshop, Collabora Ltd.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+import os
+import pickle
+import gtk
+import hippo
+import pango
+import locale
+import logging
+from datetime import date
+from gettext import gettext as _
+import telepathy
+import telepathy.client
+from dbus import Interface
+from dbus.service import method, signal
+from dbus.gobject_service import ExportedGObject
+from tubeconn import TubeConnection
+
+try:
+ from hashlib import sha1
+except ImportError:
+ # Python < 2.5
+ from sha import new as sha1
+
+from sugar.activity import activity
+from sugar.graphics import color
+from sugar.graphics.units import points_to_pixels as px
+from sugar.presence import presenceservice
+from abiword import Canvas as AbiCanvas
+from i18n import LanguageComboBox
+
+#logger = logging.getLogger('poll-activity')
+
+SERVICE = "org.worldwideworkshop.PollBuilder"
+IFACE = SERVICE
+PATH = "/org/worldwideworkshop/PollBuilder"
+
+# Theme definitions - colors
+LIGHT_GREEN = '#66CC00'
+DARK_GREEN = '#027F01'
+PINK = '#FF0198'
+YELLOW = '#FFFF00'
+GRAY = '#ACACAC'
+LIGHT_GRAY = '#E2E2E3'
+RED = '#FF0000'
+
+COLOR_FG_BUTTONS = (
+ (gtk.STATE_NORMAL,"#CCFF99"),
+ (gtk.STATE_ACTIVE,"#CCFF99"),
+ (gtk.STATE_PRELIGHT,"#CCFF99"),
+ (gtk.STATE_SELECTED,"#CCFF99"),
+ (gtk.STATE_INSENSITIVE,"#CCFF99"),
+ )
+COLOR_BG_BUTTONS = (
+ (gtk.STATE_NORMAL,"#027F01"),
+ (gtk.STATE_ACTIVE,"#014D01"),
+ (gtk.STATE_PRELIGHT,"#016D01"),
+ (gtk.STATE_SELECTED,"#027F01"),
+ (gtk.STATE_INSENSITIVE,"#027F01"),
+ )
+COLOR_BG_RADIOBUTTONS = (
+ (gtk.STATE_NORMAL,LIGHT_GRAY),
+ (gtk.STATE_ACTIVE,LIGHT_GRAY),
+ (gtk.STATE_PRELIGHT,LIGHT_GRAY),
+ (gtk.STATE_SELECTED,LIGHT_GRAY),
+ (gtk.STATE_INSENSITIVE,LIGHT_GRAY),
+ )
+COLOR_FG_RADIOBUTTONS = (
+ (gtk.STATE_NORMAL,DARK_GREEN),
+ (gtk.STATE_ACTIVE,DARK_GREEN),
+ (gtk.STATE_PRELIGHT,DARK_GREEN),
+ (gtk.STATE_SELECTED,DARK_GREEN),
+ (gtk.STATE_INSENSITIVE,DARK_GREEN),
+ )
+
+def theme_button(btn, w=-1, h=-1, highlight=False):
+ """Apply colors to gtk Buttons
+
+ btn is the button
+ w and h are optional width and height for resizing the button
+ highlight is a boolean to override the theme and apply a
+ different color to show "you are here".
+
+ returns the modified button.
+ """
+ for state, color in COLOR_BG_BUTTONS:
+ if highlight:
+ btn.modify_bg(state, gtk.gdk.color_parse("#CCFF99"))
+ else:
+ btn.modify_bg(state, gtk.gdk.color_parse(color))
+ c = btn.get_child()
+ if c is not None:
+ for state, color in COLOR_FG_BUTTONS:
+ if highlight:
+ c.modify_fg(state, gtk.gdk.color_parse(DARK_GREEN))
+ else:
+ c.modify_fg(state, gtk.gdk.color_parse(color))
+ else:
+ for state, color in COLOR_FG_BUTTONS:
+ btn.modify_fg(state, gtk.gdk.color_parse(color))
+ if w>0 or h>0:
+ btn.set_size_request(w, h)
+ return btn
+
+def theme_radiobutton(btn, size=12):
+ """Apply colors and font to gtk RadioButtons
+
+ btn -- gtk RadioButton
+ size -- integer for font size
+
+ returns the modified button.
+ """
+ if type(size) != type(1):
+ size = 12
+ for state, color in COLOR_BG_RADIOBUTTONS:
+ btn.modify_bg(state, gtk.gdk.color_parse(color))
+ c = btn.get_child()
+ if c is not None:
+ for state, color in COLOR_FG_RADIOBUTTONS:
+ c.modify_fg(state, gtk.gdk.color_parse(color))
+ c.modify_font(pango.FontDescription('Sans %d' % size))
+ else:
+ for state, color in COLOR_FG_RADIOBUTTONS:
+ btn.modify_fg(state, gtk.gdk.color_parse(color))
+ btn.modify_font(pango.FontDescription('Sans %d' % size))
+ return btn
+
+
+class PollBuilder(activity.Activity):
+ """Sugar activity for polls
+
+ Poll implements a simple tool that allows children to express
+ their opinions on a given topic by selecting one of five
+ answer choices and submitting a vote. The results are tallied
+ by total number of votes and percentage of total votes cast.
+
+ A future version of this activity will be networked over the
+ OLPC mesh to allow sharing of the poll.
+
+ """
+ def __init__(self, handle):
+ activity.Activity.__init__(self, handle)
+ # XXX Make self.poll_ stuff into a dict for easier loading and saving
+ # or even a class of its own
+
+ self._logger = logging.getLogger('poll-activity')
+ self._logger.debug('Starting Poll activity')
+
+ self._basepath = activity.get_bundle_path()
+ os.chdir(self._basepath) # required for i18n.py to work
+ self.journal_path = os.path.join(os.path.expanduser("~"), "Journal", "poll-builder")
+ if (not os.path.exists(self.journal_path)):
+ os.makedirs(self.journal_path)
+ self.journal_index = os.path.join(self.journal_path, 'pollindex.txt')
+
+ self._journal_index_load()
+
+ # setup poll with default if journal index empty
+ if self._polls_index == {}:
+ self._make_default_poll()
+ self._write_to_journal(update_index=True)
+ else:
+ self._make_blank_poll()
+ self._has_voted = False
+ self._preview = False
+ self._current_view = None # so we can switch back
+
+ self.set_title(_('Poll Builder'))
+
+ toolbox = activity.ActivityToolbox(self)
+ self.set_toolbox(toolbox)
+ toolbox.show()
+
+ # Show poll screen
+ # Setup screen
+ self._canvas = hippo.Canvas()
+ self._canvas.set_root(self._select_canvas())
+ self.set_canvas(self._canvas)
+ self.show_all()
+
+ self.poll_session = None # PollSession
+
+ # get the Presence Service
+ 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
+
+ self.connect('shared', self._shared_cb)
+
+ # Buddy object for you
+ owner = self.pservice.get_owner()
+ self.owner = owner
+
+ if self._shared_activity:
+ # we are joining the activity
+ 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():
+ # we've already joined
+ self._joined_cb()
+
+ def _poll_canvas(self):
+ """Show the poll canvas where children vote on an existing poll."""
+ self._current_view = 'poll'
+ canvasbox = self._canvas_root()
+
+ # pollbuilderbox is centered within canvasbox
+ pollbuilderbox = self._canvas_pollbuilder_box()
+ canvasbox.append(pollbuilderbox)
+
+ pollbuilderbox.append(self._canvas_topbox())
+
+ mainbox = self._canvas_mainbox()
+ pollbuilderbox.append(mainbox)
+
+ if not self._preview:
+ mainbox.append(self._text_mainbox(_('VOTE!')))
+ else:
+ mainbox.append(self._text_mainbox(_('Poll Preview')))
+
+ poll_details_box = hippo.CanvasBox(spacing=8,
+ background_color=color.WHITE.get_int(),
+ border=4,
+ border_color=color.HTMLColor(PINK).get_int(),
+ padding=20,
+ xalign=hippo.ALIGNMENT_START,
+ orientation=hippo.ORIENTATION_VERTICAL)
+ mainbox.append(poll_details_box)
+ self.poll_details_box = poll_details_box
+
+ self.current_vote = None
+ self.draw_poll_details_box()
+
+ button_box = self._canvas_buttonbox()
+ mainbox.append(button_box, hippo.PACK_END)
+
+ return canvasbox
+
+ def _select_canvas(self):
+ """Show the select canvas where children choose an existing poll."""
+ self._current_view = 'select'
+ canvasbox = self._canvas_root()
+
+ # pollbuilderbox is centered within canvasbox
+ pollbuilderbox = self._canvas_pollbuilder_box()
+ canvasbox.append(pollbuilderbox)
+
+ pollbuilderbox.append(self._canvas_topbox())
+
+ mainbox = self._canvas_mainbox()
+ pollbuilderbox.append(mainbox)
+
+ mainbox.append(self._text_mainbox(_('Choose a Poll')))
+
+ poll_details_box = hippo.CanvasBox(spacing=8,
+ background_color=color.WHITE.get_int(),
+ border=4,
+ border_color=color.HTMLColor(PINK).get_int(),
+ padding=20,
+ xalign=hippo.ALIGNMENT_START,
+ orientation=hippo.ORIENTATION_VERTICAL)
+ mainbox.append(poll_details_box)
+
+ # add scroll window XXX add to canvas how?
+ scrolledwindow = gtk.ScrolledWindow()
+ scrolledwindow.set_policy(
+ hscrollbar_policy=gtk.POLICY_NEVER,
+ vscrollbar_policy=gtk.POLICY_AUTOMATIC)
+
+ poll_selector_box = hippo.CanvasBox(
+ orientation=hippo.ORIENTATION_VERTICAL)
+ poll_details_box.append(poll_selector_box) # XXX scrolledwindow?
+
+ row_number = 0
+ for title in self._polls_index.keys():
+ poll = self._polls_index[title]
+ if row_number % 2:
+ row_bgcolor=color.WHITE.get_int()
+ else:
+ row_bgcolor=color.DESKTOP_BACKGROUND.get_int()
+ row_number += 1
+ poll_row = hippo.CanvasBox(
+ padding_top=4, padding_bottom=4,
+ background_color=row_bgcolor,
+ orientation=hippo.ORIENTATION_HORIZONTAL)
+ poll_selector_box.append(poll_row)
+
+ sized_box = hippo.CanvasBox(
+ box_width=600,
+ orientation=hippo.ORIENTATION_HORIZONTAL)
+ poll_row.append(sized_box)
+ title = hippo.CanvasText(
+ text=title+' ('+poll['author']+')',
+ xalign=hippo.ALIGNMENT_START,
+ color=color.HTMLColor(DARK_GREEN).get_int(),
+ font_desc = pango.FontDescription('Sans 10'))
+ sized_box.append(title)
+
+ sized_box = hippo.CanvasBox(
+ box_width=180,
+ orientation=hippo.ORIENTATION_HORIZONTAL)
+ poll_row.append(sized_box)
+ if poll['active']:
+ button = gtk.Button(_('VOTE'))
+ else:
+ button = gtk.Button(_('SEE RESULTS'))
+ button.connect('clicked', self._select_poll_button_cb,
+ poll['sha'])
+ sized_box.append(hippo.CanvasWidget(widget=theme_button(button)))
+
+ sized_box = hippo.CanvasBox(
+ box_width=150,
+ orientation=hippo.ORIENTATION_HORIZONTAL)
+ poll_row.append(sized_box)
+ if poll['author'] == self._pservice.get_owner().props.nick:
+ button = gtk.Button(_('DELETE'))
+ button.connect('clicked', self._delete_poll_button_cb,
+ poll['sha'])
+ sized_box.append(hippo.CanvasWidget(widget=theme_button(button)))
+ poll_row.append(hippo.CanvasText(
+ text=self.poll_createdate.strftime('%d/%m/%y'),
+ color=color.HTMLColor(DARK_GREEN).get_int()))
+
+ button_box = self._canvas_buttonbox(button_to_highlight=2)
+ mainbox.append(button_box, hippo.PACK_END)
+
+ return canvasbox
+
+ def _lessonplan_canvas(self):
+ """Show the select canvas where children choose an existing poll."""
+ previous_view = self._current_view
+ self._current_view = 'lessonplan'
+ canvasbox = self._canvas_root()
+
+ # pollbuilderbox is centered within canvasbox
+ pollbuilderbox = self._canvas_pollbuilder_box()
+ canvasbox.append(pollbuilderbox)
+
+ pollbuilderbox.append(self._canvas_topbox(lesson_return=previous_view))
+
+ mainbox = self._canvas_mainbox()
+ pollbuilderbox.append(mainbox)
+
+ mainbox.append(self._text_mainbox(_('Lesson Plans')))
+
+ poll_details_box = hippo.CanvasBox(spacing=8,
+ background_color=color.WHITE.get_int(),
+ border=4,
+ border_color=color.HTMLColor(PINK).get_int(),
+ padding=20,
+ xalign=hippo.ALIGNMENT_START,
+ orientation=hippo.ORIENTATION_VERTICAL)
+ mainbox.append(poll_details_box)
+
+ lessonplan = LessonPlanWidget(self._basepath)
+ lessonplan.set_size_request(1050, 500)
+ poll_details_box.append(hippo.CanvasWidget(widget=lessonplan),
+ hippo.PACK_EXPAND)
+
+ button_box = self._canvas_buttonbox()
+ mainbox.append(button_box, hippo.PACK_END)
+
+ return canvasbox
+
+ def _select_poll_button_cb(self, button, sha=None):
+ """A VOTE or SEE RESULTS button was clicked."""
+ if not sha:
+ self._logger.debug('Strange, which button was clicked?')
+ return
+ self._resume_from_journal(sha)
+ self._has_voted = False
+ self._canvas.set_root(self._poll_canvas())
+ self.show_all()
+
+ def _delete_poll_button_cb(self, button, sha=None):
+ """A DELETE button was clicked."""
+ if not sha:
+ self._logger.debug('Strange, which button was clicked?')
+ return
+ self._journal_index_del(sha)
+ self._canvas.set_root(self._select_canvas())
+ self.show_all()
+
+ def draw_poll_details_box(self):
+ """(Re)draw the poll details box
+
+ self.poll_details_box should be already defined on the canvas.
+ """
+ poll_details_box = self.poll_details_box
+ poll_details_box.remove_all()
+
+ votes_total = self.get_votes_total()
+
+ text_size = self._size_heading_text(self.poll_title)
+ title = hippo.CanvasText(
+ text=self.poll_title,
+ xalign=hippo.ALIGNMENT_START,
+ color=color.HTMLColor(DARK_GREEN).get_int(),
+ font_desc = pango.FontDescription('Sans %d' % text_size))
+ poll_details_box.append(title)
+ text_size = self._size_heading_text(self.poll_question)
+ question = hippo.CanvasText(
+ text=self.poll_question,
+ xalign=hippo.ALIGNMENT_START,
+ color=color.HTMLColor(DARK_GREEN).get_int(),
+ font_desc = pango.FontDescription('Sans %d' % text_size))
+ poll_details_box.append(question)
+
+ button = None # required for radio button group
+ button = gtk.RadioButton()
+ for choice in range(self.poll_number_of_options):
+ self._logger.debug(self.poll_options[choice])
+ answer_row = hippo.CanvasBox(spacing=8,
+ orientation=hippo.ORIENTATION_HORIZONTAL)
+
+ sized_box = hippo.CanvasBox(
+ box_width=400,
+ orientation=hippo.ORIENTATION_HORIZONTAL)
+ answer_row.append(sized_box)
+ if self.poll_active:
+ button = gtk.RadioButton(button, ' '+self.poll_options[choice])
+ button.set_size_request(400, -1)
+ button.connect('toggled', self.vote_choice_radio_button, choice)
+ sized_box.append(hippo.CanvasWidget(
+ widget=theme_radiobutton(
+ button,
+ size=self._size_answer_text(choice))))
+ else:
+ sized_box.append(hippo.CanvasText(
+ text=self.poll_options[choice],
+ color=color.HTMLColor(DARK_GREEN).get_int(),
+ font_desc = pango.FontDescription('Sans %d' %
+ self._size_answer_text(choice))))
+
+ # show results if the user has just voted,
+ # unless the poll is closed - then show it straight away
+ if votes_total > 0 and ((self.poll_active and self._has_voted) or
+ not self.poll_active):
+ # show results
+ self._logger.debug(str(self.poll_data[choice] * 1.0 / votes_total))
+ result_box = hippo.CanvasBox(
+ orientation=hippo.ORIENTATION_VERTICAL,
+ box_width=100)
+ answer_row.append(result_box)
+ result_box.append(hippo.CanvasText(
+ #text=str(self.poll_data[choice]),
+ text=justify(self.poll_data, choice),
+ xalign=hippo.ALIGNMENT_END,
+ color=color.HTMLColor(DARK_GREEN).get_int(),
+ font_desc = pango.FontDescription('Sans 12')))
+ # int(self.poll_data[choice] * 1.0 / votes_total * 20) * '*',
+ # APPEND BARGRAPH TO result_box
+ graphbox = hippo.CanvasBox(
+ orientation=hippo.ORIENTATION_HORIZONTAL,
+ background_color=color.HTMLColor(PINK).get_int(),
+ box_width=int(self.poll_data[choice] * 1.0 / votes_total * 20) * 20)
+ answer_row.append(graphbox)
+ answer_row.append(hippo.CanvasText(
+ text=str(self.poll_data[choice] * 100 / votes_total)+'%',
+ color=color.HTMLColor(DARK_GREEN).get_int(),
+ font_desc=pango.FontDescription('Sans 10')))
+
+ poll_details_box.append(answer_row)
+
+ if (self.poll_active and self._has_voted) or\
+ not self.poll_active:
+ # Line above total
+ line_box = hippo.CanvasBox(
+ spacing=8,
+ box_height=4,
+ orientation=hippo.ORIENTATION_HORIZONTAL)
+ spacer = hippo.CanvasBox(
+ box_width=430, orientation=hippo.ORIENTATION_HORIZONTAL)
+ line_box.append(spacer)
+ line = hippo.CanvasBox(
+ background_color=color.HTMLColor(DARK_GREEN).get_int(),
+ box_width=600,
+ orientation=hippo.ORIENTATION_HORIZONTAL)
+ line_box.append(line)
+ poll_details_box.append(line_box)
+
+ # total votes
+ totals_box = hippo.CanvasBox(
+ spacing=8,
+ orientation=hippo.ORIENTATION_HORIZONTAL)
+ poll_details_box.append(totals_box)
+ spacer = hippo.CanvasBox(
+ box_width=400, orientation=hippo.ORIENTATION_HORIZONTAL)
+ totals_box.append(spacer)
+ spacer = hippo.CanvasBox(
+ box_width=100, orientation=hippo.ORIENTATION_VERTICAL)
+ spacer.append(hippo.CanvasText(
+ text=str(votes_total),
+ xalign=hippo.ALIGNMENT_END,
+ color=color.HTMLColor(DARK_GREEN).get_int(),
+ font_desc = pango.FontDescription('Sans 12')))
+ totals_box.append(spacer)
+ totals_box.append(hippo.CanvasText(
+ text=' '+_('votes'),
+ xalign=hippo.ALIGNMENT_START,
+ color=color.HTMLColor(DARK_GREEN).get_int(),
+ font_desc = pango.FontDescription('Sans 12')))
+ if votes_total < self.poll_maxvoters:
+ totals_box.append(hippo.CanvasText(
+ text=' ('+str(self.poll_maxvoters-votes_total)+
+ ' votes left to collect)',
+ color=color.HTMLColor(DARK_GREEN).get_int(),
+ font_desc = pango.FontDescription('Sans 12')))
+
+ # Button area
+ if self.poll_active and not self._preview:
+ button_box = hippo.CanvasBox(spacing=8,
+ padding = 8,
+ orientation=hippo.ORIENTATION_HORIZONTAL)
+ button = gtk.Button(_("Vote"))
+ button.connect('clicked', self.button_vote_clicked)
+ button_box.append(hippo.CanvasWidget(widget=theme_button(button)))
+ poll_details_box.append(button_box)
+ elif self._preview:
+ button_box = hippo.CanvasBox(spacing=8,
+ padding = 8,
+ orientation=hippo.ORIENTATION_HORIZONTAL)
+ button = gtk.Button(_("Edit Poll"))
+ button.connect('clicked', self.button_edit_clicked)
+ button_box.append(hippo.CanvasWidget(widget=theme_button(button)))
+ button = gtk.Button(_("Save Poll"))
+ button.connect('clicked', self._button_save_cb)
+ button_box.append(hippo.CanvasWidget(widget=theme_button(button)))
+ poll_details_box.append(button_box)
+
+ def vote_choice_radio_button(self, widget, data=None):
+ """Track which radio button has been selected
+
+ This is connected to the vote choice radio buttons.
+ data contains the choice (0 - 4) selected.
+ """
+ self.current_vote = data
+
+ def button_vote_clicked(self, button):
+ """Register a vote
+
+ Take the selected option from self.current_vote
+ and increment the poll_data.
+ """
+ if self.current_vote is not None:
+ if self.get_votes_total() >= self.poll_maxvoters:
+ self._logger.debug(
+ 'Hit the max voters, ignoring this vote.')
+ return
+ self._logger.debug('Voted '+str(self.current_vote))
+ self._has_voted = True
+ self.poll_data[self.current_vote] += 1
+ if self.get_votes_total() >= self.poll_maxvoters:
+ self.poll_active = False # close poll
+ self._logger.debug('Results: '+str(self.poll_data))
+ self.draw_poll_details_box()
+ # Update index when writing as poll may have closed:
+ self._write_to_journal(update_index=True)
+
+ def button_select_clicked(self, button):
+ """Show Choose a Poll canvas"""
+ self._canvas.set_root(self._select_canvas())
+ self.show_all()
+
+ def button_new_clicked(self, button):
+ """Show Build a Poll canvas.
+
+ Make sure current poll is saved.
+ """
+ if self.poll_title:
+ self._write_to_journal(update_index=True)
+ # Reset vote data to 0
+ self._make_blank_poll()
+ owner = self._pservice.get_owner()
+ self.poll_author = owner.props.nick
+ self.poll_active = False
+ self._canvas.set_root(self._build_canvas())
+ self.show_all()
+
+ def button_edit_clicked(self, button):
+ """Go back from preview to edit"""
+ self._canvas.set_root(self._build_canvas())
+ self.show_all()
+
+ def _build_canvas(self, editing=False, highlight=[]):
+ """Show the canvas to set up a new poll.
+
+ editing is False to start a new poll, or
+ True to edit the current poll
+
+ highlight is a list of strings denoting items failing validation.
+ """
+ self._current_view = 'build'
+ canvasbox = self._canvas_root()
+
+ # pollbuilderbox is centered within canvasbox
+ pollbuilderbox = self._canvas_pollbuilder_box()
+ canvasbox.append(pollbuilderbox)
+
+ pollbuilderbox.append(self._canvas_topbox())
+
+ mainbox = self._canvas_mainbox()
+ pollbuilderbox.append(mainbox)
+
+ mainbox.append(self._text_mainbox(_('Build a Poll')))
+
+ poll_details_box = hippo.CanvasBox(spacing=8,
+ background_color=color.WHITE.get_int(),
+ border=4,
+ border_color=color.HTMLColor(PINK).get_int(),
+ padding=20,
+ xalign=hippo.ALIGNMENT_START,
+ orientation=hippo.ORIENTATION_VERTICAL)
+ mainbox.append(poll_details_box)
+
+ buildbox = hippo.CanvasBox(spacing=8,
+ #xalign=hippo.ALIGNMENT_CENTER,
+ orientation=hippo.ORIENTATION_VERTICAL)
+ poll_details_box.append(buildbox, hippo.PACK_EXPAND)
+
+ hbox = hippo.CanvasBox(spacing=8,
+ orientation=hippo.ORIENTATION_HORIZONTAL)
+ hbox.append(self._text_mainbox(_('Poll Title:'),
+ warn='title' in highlight))
+ entrybox = gtk.Entry()
+ entrybox.set_size_request(800, -1)
+ entrybox.set_text(self.poll_title)
+ entrybox.connect('changed', self._entry_activate_cb, 'title')
+ hbox.append(hippo.CanvasWidget(widget=entrybox), hippo.PACK_EXPAND)
+ buildbox.append(hbox, hippo.PACK_EXPAND)
+
+ hbox = hippo.CanvasBox(spacing=8,
+ orientation=hippo.ORIENTATION_HORIZONTAL)
+ hbox.append(self._text_mainbox(_('Question:'),
+ warn='question' in highlight))
+ entrybox = gtk.Entry()
+ entrybox.set_text(self.poll_question)
+ entrybox.connect('changed', self._entry_activate_cb, 'question')
+ hbox.append(hippo.CanvasWidget(widget=entrybox), hippo.PACK_EXPAND)
+ buildbox.append(hbox, hippo.PACK_EXPAND)
+
+ hbox = hippo.CanvasBox(spacing=8,
+ orientation=hippo.ORIENTATION_HORIZONTAL)
+ hbox.append(self._text_mainbox(_('Number of votes to collect:'),
+ warn='maxvoters' in highlight))
+ entrybox = gtk.Entry()
+ entrybox.set_text(str(self.poll_maxvoters))
+ entrybox.connect('changed', self._entry_activate_cb, 'maxvoters')
+ hbox.append(hippo.CanvasWidget(widget=entrybox))
+ buildbox.append(hbox)
+
+ for choice in self.poll_options.keys():
+ hbox = hippo.CanvasBox(spacing=8,
+ orientation=hippo.ORIENTATION_HORIZONTAL)
+ hbox.append(self._text_mainbox(_('Answer') + ' ' + str(choice+1) +
+ ':',
+ warn=str(choice) in highlight))
+ entrybox = gtk.Entry()
+ entrybox.set_text(self.poll_options[choice])
+ entrybox.connect('changed', self._entry_activate_cb, str(choice))
+ hbox.append(hippo.CanvasWidget(widget=entrybox), hippo.PACK_EXPAND)
+ buildbox.append(hbox, hippo.PACK_EXPAND)
+
+ # PREVIEW & SAVE buttons
+ hbox = hippo.CanvasBox(spacing=8,
+ orientation=hippo.ORIENTATION_HORIZONTAL)
+ button = gtk.Button(_("Step 1: Preview"))
+ button.connect('clicked', self._button_preview_cb)
+ hbox.append(hippo.CanvasWidget(widget=theme_button(button)))
+ button = gtk.Button(_("Step 2: Save"))
+ button.connect('clicked', self._button_save_cb)
+ hbox.append(hippo.CanvasWidget(widget=theme_button(button)))
+ buildbox.append(hbox)
+
+ button_box = self._canvas_buttonbox(button_to_highlight=1)
+ mainbox.append(button_box, hippo.PACK_END)
+
+ return canvasbox
+
+ def _button_preview_cb(self, button, data=None):
+ """Preview button clicked."""
+ # Validate data
+ failed_items = self._validate()
+ if failed_items:
+ self._canvas.set_root(self._build_canvas(highlight=failed_items))
+ self.show_all()
+ return
+ # Data OK
+ self.poll_active = True # Show radio buttons
+ self._preview = True
+ self._canvas.set_root(self._poll_canvas())
+ self.show_all()
+
+ def _button_save_cb(self, button, data=None):
+ """Save button clicked."""
+ # Validate data
+ failed_items = self._validate()
+ if failed_items:
+ self._canvas.set_root(self._build_canvas(highlight=failed_items))
+ self.show_all()
+ return
+ # Data OK
+ self._preview = False
+ self.poll_active = True
+ self._write_to_journal(update_index=True)
+ self._canvas.set_root(self._poll_canvas())
+ self.show_all()
+
+ def _entry_activate_cb(self, entrycontrol, data=None):
+ text = entrycontrol.props.text
+ if data:
+ if text:
+ if data=='title':
+ self.poll_title = text
+ elif data=='question':
+ self.poll_question = text
+ elif data=='maxvoters':
+ try:
+ self.poll_maxvoters = int(text)
+ except ValueError:
+ self.poll_maxvoters = 0 # invalid, will be trapped
+ else:
+ self.poll_options[int(data)] = text
+
+ def _make_blank_poll(self):
+ """Initialize the poll state."""
+ self.poll_title = self.poll_author = ''
+ self.poll_active = False
+ self.poll_createdate = date.today()
+ self.poll_maxvoters = 20
+ self.poll_question = ''
+ self.poll_number_of_options = 5
+ self.poll_options = {0: '', 1: '', 2: '', 3: '', 4: ''}
+ self.poll_data = {0: 0, 1:0, 2:0, 3:0, 4:0}
+ self.current_vote = None
+
+ def _make_default_poll(self):
+ """A hardcoded poll for first time launch."""
+ self.poll_title = _('Favorite Color')
+ self.poll_createdate = date.today()
+ owner = self._pservice.get_owner()
+ self.poll_author = owner.props.nick
+ self.poll_active = True
+ self.poll_maxvoters = 20
+ self.poll_question = _('What is your favorite color?')
+ self.poll_number_of_options = 5
+ self.poll_options = {
+ 0: _('Green'),
+ 1: _('Red'),
+ 2: _('Blue'),
+ 3: _('Orange'),
+ 4: _('None of the above'),
+ }
+ self.poll_data = {0: 0, 1:0, 2:0, 3:0, 4:0}
+ self.current_vote = None
+ # XXX The above must be extended to cater for only one vote per XO, tracking
+ # an anonymous but unique identifier per XO and the vote cast
+ self._journal_index_add()
+
+ def _validate(self):
+ failed_items = []
+ if self.poll_title == '':
+ failed_items.append('title')
+ if self.poll_question == '':
+ failed_items.append('question')
+ if self.poll_maxvoters == 0:
+ failed_items.append('maxvoters')
+ if self.poll_options[0] == '':
+ failed_items.append('0')
+ if self.poll_options[1] == '':
+ failed_items.append('1')
+ if self.poll_options[3] != '' and self.poll_options[2] == '':
+ failed_items.append('2')
+ if self.poll_options[4] != '' and self.poll_options[3] == '':
+ failed_items.append('3')
+ if self.poll_options[2] == '':
+ self.poll_number_of_options = 2
+ elif self.poll_options[3] == '':
+ self.poll_number_of_options = 3
+ elif self.poll_options[4] == '':
+ self.poll_number_of_options = 4
+ else:
+ self.poll_number_of_options = 5
+ return failed_items
+
+ def _write_to_journal(self, update_index=False):
+ """Write current poll to journal.
+
+ Pass update_index=True if you need to make sure
+ this poll is in the journal index file. For example,
+ when creating a new poll.
+ """
+ sha = self._get_sha()
+ self.filename = os.path.join(self.journal_path, sha)
+ f = open(self.filename, 'w')
+ pickle.dump(self.poll_title, f)
+ pickle.dump(self.poll_author, f)
+ pickle.dump(self.poll_active, f)
+ pickle.dump(self.poll_createdate, f)
+ pickle.dump(self.poll_maxvoters, f)
+ pickle.dump(self.poll_question, f)
+ pickle.dump(self.poll_number_of_options, f)
+ pickle.dump(self.poll_options, f)
+ pickle.dump(self.poll_data, f)
+ f.close()
+ if update_index:
+ self._journal_index_add()
+
+ def _journal_index_add(self):
+ """Write the current poll to the journal index."""
+ self._journal_index_load()
+ # insert self
+ self._polls_index[self.poll_title] = {
+ 'author': self.poll_author,
+ 'active': self.poll_active,
+ 'createdate': self.poll_createdate,
+ 'sha': self._get_sha(),
+ }
+ # write index
+ self._journal_index_write()
+
+ def _journal_index_del(self, sha):
+ """Delete a poll from the journal index."""
+ self._journal_index_load()
+ for poll in self._polls_index.keys():
+ if self._polls_index[poll]['sha'] == sha:
+ del self._polls_index[poll]
+ self._journal_index_write()
+ return
+
+ def _get_sha(self):
+ """Return a sha1 hash of something about this poll.
+
+ Currently we sha1 the poll title and author.
+ This is used for the filename of the saved poll.
+ It will probably be used for the mesh networking too.
+ """
+ sha = sha1(self.poll_title + self.poll_author).hexdigest()
+ return sha
+
+ def _journal_index_load(self):
+ """Load the journal index of saved polls."""
+ self._polls_index = {}
+ try:
+ lines = open(self.journal_index).readlines()
+ except IOError: # File does not exist
+ lines = []
+ for line in lines:
+ try:
+ title, author, active, createdate, sha =\
+ line.strip().split('\t')
+ except ValueError:
+ # incompatible file format change
+ self._logger.debug('Loading journal index file failed, resetting')
+ continue
+ self._polls_index[title] = {
+ 'author': author, 'active': int(active),
+ 'createdate': date.fromordinal(int(createdate)), 'sha': sha}
+
+ def _journal_index_write(self):
+ """Write the journal file."""
+ # XXX Need to validate self._polls_index!
+ f = open(self.journal_index, 'w')
+ for title in self._polls_index.keys():
+ f.write('%s\t%s\t%d\t%d\t%s\n' %
+ (title,
+ self._polls_index[title]['author'],
+ self._polls_index[title]['active'],
+ self._polls_index[title]['createdate'].toordinal(),
+ self._polls_index[title]['sha']))
+ f.close()
+
+ def _resume_from_journal(self, sha):
+ """Load from journal based on the sha
+
+ The sha comes from the index file.
+ """
+ self.sha = sha
+ self.filename = os.path.join(self.journal_path, self.sha)
+ f = open(self.filename)
+ self.poll_title = pickle.load(f)
+ self.poll_author = pickle.load(f)
+ self.poll_active = pickle.load(f)
+ self.poll_createdate = pickle.load(f)
+ self.poll_maxvoters = pickle.load(f)
+ self.poll_question = pickle.load(f)
+ self.poll_number_of_options = pickle.load(f)
+ self.poll_options = pickle.load(f)
+ self.poll_data = pickle.load(f)
+ f.close()
+
+ def get_votes_total(self):
+ """Return the total votes cast."""
+ total = 0
+ for choice in self.poll_options.keys():
+ total += self.poll_data[choice]
+ return total
+
+ def _canvas_language_select_box(self):
+ """CanvasBox definition for lang select box.
+
+ Called from _poll_canvas, _select_canvas, _build_canvas
+ """
+ languageselectbox = hippo.CanvasBox(
+ background_color=color.HTMLColor(LIGHT_GREEN).get_int(),
+ border_top=4, border_left=4,
+ border_color=color.HTMLColor(YELLOW).get_int(),
+ padding_top=12, padding_bottom=12,
+ padding_left=100, padding_right=100,
+ orientation=hippo.ORIENTATION_VERTICAL)
+ button = LanguageComboBox()
+ button.install()
+ languageselectbox.append(hippo.CanvasWidget(widget=theme_button(button)))
+ return languageselectbox
+
+ def _canvas_pollbuilder_box(self):
+ """CanvasBox definition for pollbuilderbox.
+
+ Called from _poll_canvas, _select_canvas, _build_canvas
+ """
+ pollbuilderbox = hippo.CanvasBox(
+ border=4,
+ border_color=color.HTMLColor(GRAY).get_int(),
+ orientation=hippo.ORIENTATION_VERTICAL)
+ return pollbuilderbox
+
+ def _canvas_root(self):
+ """CanvasBox definition for main canvas.
+
+ Called from _poll_canvas, _select_canvas, _build_canvas
+ """
+ canvasbox = hippo.CanvasBox(
+ background_color=color.DESKTOP_BACKGROUND.get_int(),
+ #padding = 100,
+ orientation=hippo.ORIENTATION_VERTICAL)
+ return canvasbox
+
+ def _canvas_topbox(self, lesson_return=None):
+ """Render topbox.
+
+ lesson_return is the view we want to return to from
+ lesson plan if the lesson plan button is clicked.
+ """
+ topbox = hippo.CanvasBox(
+ background_color=color.HTMLColor(LIGHT_GREEN).get_int(),
+ orientation=hippo.ORIENTATION_HORIZONTAL)
+ topbox.append(hippo.CanvasWidget(widget=self._logo()))
+ languageselectbox = self._canvas_language_select_box()
+ topbox.append(languageselectbox, hippo.PACK_EXPAND)
+ lessonplanbox = self._canvas_lessonplanbox(lesson_return)
+ topbox.append(lessonplanbox, hippo.PACK_EXPAND)
+ return topbox
+
+ def _logo(self):
+ logoimage = gtk.Image()
+ logoimage.set_from_file(os.path.join(
+ self._basepath,
+ 'GameLogoCharacter.png'))
+ return logoimage
+
+ def _canvas_lessonplanbox(self, lesson_return=None):
+ """Render the lessonplanbox.
+
+ disconnect_lp True does not connect the button.
+ """
+ lessonplanbox = hippo.CanvasBox(
+ background_color=color.HTMLColor(LIGHT_GREEN).get_int(),
+ border_top=4, border_left=4, border_right=4,
+ border_color=color.HTMLColor(YELLOW).get_int(),
+ padding_top=12, padding_bottom=12,
+ padding_left=30, padding_right=30,
+ orientation=hippo.ORIENTATION_VERTICAL)
+ if lesson_return:
+ highlight = True
+ button = gtk.Button(_("Close Lessons"))
+ else:
+ highlight = False
+ button = gtk.Button(_("Lesson Plans"))
+ if lesson_return:
+ button.connect('clicked', self._button_closelessonplan_cb, lesson_return)
+ else:
+ button.connect('clicked', self._button_lessonplan_cb)
+ lessonplanbox.append(hippo.CanvasWidget(widget=theme_button(
+ button, highlight=highlight)))
+ return lessonplanbox
+
+ def _button_lessonplan_cb(self, button):
+ """Lesson Plan button clicked."""
+ self._logger.debug('%s -> Lesson Plan' % self._current_view)
+ self._canvas.set_root(self._lessonplan_canvas())
+ self.show_all()
+
+ def _button_closelessonplan_cb(self, button, lesson_return):
+ """Lesson Plan button clicked in Lesson Plan view.
+
+ Go back to the view we had previously.
+ """
+ self._logger.debug('Lesson plans -> %s' % lesson_return)
+ if lesson_return == 'poll':
+ self._canvas.set_root(self._poll_canvas())
+ elif lesson_return == 'select':
+ self._canvas.set_root(self._select_canvas())
+ elif lesson_return == 'build':
+ self._canvas.set_root(self._build_canvas())
+ self.show_all()
+
+ def _size_answer_text(self, choice):
+ """Choose font size for poll answers.
+
+ choice -- integer to choose an answer.
+
+ returns font size as integer.
+ """
+ text = self.poll_options[choice]
+ if len(text) <= 16:
+ text_size = 12
+ elif len(text) <= 18:
+ text_size = 11
+ elif len(text) <= 20:
+ text_size = 10
+ elif len(text) <= 22:
+ text_size = 9
+ elif len(text) <= 25:
+ text_size = 8
+ elif len(text) <= 29:
+ text_size = 7
+ elif len(text) <= 33:
+ text_size = 6
+ else:
+ text_size = 5
+ return text_size
+
+ def _size_heading_text(self, text):
+ """Choose font size for poll headings.
+
+ text -- string of the title or question.
+
+ returns font size as integer.
+ """
+ if len(text) <= 38:
+ text_size = 12
+ elif len(text) <= 55:
+ text_size = 11
+ elif len(text) <= 59:
+ text_size = 10
+ elif len(text) <= 65:
+ text_size = 9
+ elif len(text) <= 74:
+ text_size = 8
+ elif len(text) <= 80:
+ text_size = 7
+ elif len(text) <= 90:
+ text_size = 6
+ else:
+ text_size = 5
+ return text_size
+
+ def _canvas_mainbox(self):
+ mainbox = hippo.CanvasBox(spacing=4,
+ background_color=color.HTMLColor(LIGHT_GREEN).get_int(),
+ border=4,
+ border_color=color.HTMLColor(YELLOW).get_int(),
+ padding_top=20, padding_left=40, padding_right=40,
+ padding_bottom=20,
+ orientation=hippo.ORIENTATION_VERTICAL)
+ return mainbox
+
+ def _text_mainbox(self, text, warn=False):
+ """Main text style.
+
+ warn=True makes the text color RED and appends ???.
+ """
+ if warn:
+ text_color = RED
+ text = text + '???'
+ else:
+ text_color = DARK_GREEN
+ return hippo.CanvasText(
+ text=text,
+ xalign=hippo.ALIGNMENT_START,
+ font_desc = pango.FontDescription('Sans 12'),
+ color=color.HTMLColor(text_color).get_int())
+
+ def _canvas_buttonbox(self, button_to_highlight=None):
+ button_box = hippo.CanvasBox(
+ spacing=8,
+ padding=8,
+ orientation=hippo.ORIENTATION_HORIZONTAL)
+ button = gtk.Button(_("Build a Poll"))
+ button.connect('clicked', self.button_new_clicked)
+ button_box.append(hippo.CanvasWidget(
+ widget=theme_button(button,
+ highlight=(button_to_highlight==1))))
+ button = gtk.Button(_("Choose a Poll"))
+ button.connect('clicked', self.button_select_clicked)
+ button_box.append(hippo.CanvasWidget(
+ widget=theme_button(button,
+ highlight=(button_to_highlight==2))))
+ return button_box
+
+ def _shared_cb(self, activity):
+ """Callback for completion of sharing this activity."""
+ self._logger.debug('My activity was shared')
+ self.initiating = True
+ self._setup()
+
+ for buddy in self._shared_activity.get_joined_buddies():
+ self._logger.debug('Buddy %s is already in the activity' %
+ buddy.props.nick)
+
+ self._shared_activity.connect('buddy-joined', self._buddy_joined_cb)
+ self._shared_activity.connect('buddy-left', self._buddy_left_cb)
+
+ self._logger.debug('This is my activity: making a tube...')
+ id = self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].OfferTube(
+ telepathy.TUBE_TYPE_DBUS, SERVICE, {})
+
+ def _setup(self):
+ """Setup my Tubes channel.
+
+ Called from _shared_cb or _joined_cb.
+ """
+ if self._shared_activity is None:
+ self._logger.error('Failed to share or join activity')
+ return
+
+ 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:
+ self._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:
+ self._logger.debug('Found our Tubes channel at %s', channel_path)
+ tubes_chan = channel
+ elif ctype == telepathy.CHANNEL_TYPE_TEXT:
+ self._logger.debug('Found our Text channel at %s', channel_path)
+ text_chan = channel
+
+ if room is None:
+ self._logger.error("Presence service didn't create a room")
+ return
+ if text_chan is None:
+ self._logger.error("Presence service didn't create a text channel")
+ return
+
+ # Make sure we have a Tubes channel - PS doesn't yet provide one
+ if tubes_chan is None:
+ self._logger.debug("Didn't find our Tubes channel, requesting one...")
+ tubes_chan = self.conn.request_channel(telepathy.CHANNEL_TYPE_TUBES,
+ telepathy.HANDLE_TYPE_ROOM, room, True)
+
+ self.tubes_chan = tubes_chan
+ self.text_chan = text_chan
+
+ tubes_chan[telepathy.CHANNEL_TYPE_TUBES].connect_to_signal('NewTube',
+ self._new_tube_cb)
+
+ def _list_tubes_reply_cb(self, tubes):
+ for tube_info in tubes:
+ self._new_tube_cb(*tube_info)
+
+ def _list_tubes_error_cb(self, e):
+ self._logger.error('ListTubes() failed: %s', e)
+
+ def _joined_cb(self, activity):
+ """Callback for completion of joining the activity."""
+ if not self._shared_activity:
+ return
+
+ # Find out who's already in the shared activity:
+ for buddy in self._shared_activity.get_joined_buddies():
+ self._logger.debug('Buddy %s is already in the activity' % buddy.props.nick)
+
+ self._logger.debug('Joined an existing shared activity')
+ self.initiating = False
+ self._setup()
+
+ self._logger.debug('This is not my activity: waiting for a tube...')
+ self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].ListTubes(
+ reply_handler=self._list_tubes_reply_cb,
+ error_handler=self._list_tubes_error_cb)
+
+ def _new_tube_cb(self, id, initiator, type, service, params, state):
+ """Callback for when we have a Tube."""
+ self._logger.debug('New tube: ID=%d initator=%d type=%d service=%s '
+ 'params=%r state=%d', id, initiator, type, service,
+ params, state)
+
+ if (type == telepathy.TUBE_TYPE_DBUS and
+ service == SERVICE):
+ if state == telepathy.TUBE_STATE_LOCAL_PENDING:
+ self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].AcceptTube(id)
+
+ tube_conn = TubeConnection(self.conn,
+ self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES],
+ id, group_iface=self.text_chan[telepathy.CHANNEL_INTERFACE_GROUP])
+ self.poll_session = PollSession(tube_conn, self.initiating, self._get_buddy, self)
+
+ def _buddy_joined_cb (self, activity, buddy):
+ self._logger.debug('Buddy %s joined' % buddy.props.nick)
+
+ def _buddy_left_cb (self, activity, buddy):
+ self._logger.debug('Buddy %s left' % buddy.props.nick)
+
+ def _get_buddy(self, cs_handle):
+ """Get a Buddy from a channel specific handle."""
+ self._logger.debug('Trying to find owner of handle %u...', cs_handle)
+ group = self.text_chan[telepathy.CHANNEL_INTERFACE_GROUP]
+ my_csh = group.GetSelfHandle()
+ self._logger.debug('My handle in that group is %u', my_csh)
+ if my_csh == cs_handle:
+ handle = self.conn.GetSelfHandle()
+ self._logger.debug('CS handle %u belongs to me, %u', cs_handle, handle)
+ elif group.GetGroupFlags() & telepathy.CHANNEL_GROUP_FLAG_CHANNEL_SPECIFIC_HANDLES:
+ handle = group.GetHandleOwners([cs_handle])[0]
+ self._logger.debug('CS handle %u belongs to %u', cs_handle, handle)
+ else:
+ handle = cs_handle
+ logger.debug('non-CS handle %u belongs to itself', handle)
+
+ # XXX: deal with failure to get the handle owner
+ assert handle != 0
+
+ # XXX: we're assuming that we have Buddy objects for all contacts -
+ # this might break when the server becomes scalable.
+ return self.pservice.get_buddy_by_telepathy_handle(self.tp_conn_name,
+ self.tp_conn_path, handle)
+
+
+class PollSession(ExportedGObject):
+ """The bit that talks over the TUBES!!!"""
+
+ def __init__(self, tube, is_initiator, get_buddy, activity):
+ """Initialise the PollSession.
+
+ tube -- TubeConnection
+ is_initiator -- boolean, True = we are sharing, False = we are joining
+ get_buddy -- function
+ activity -- PollBuilder (sugar.activity.Activity)
+ """
+ super(PollSession, self).__init__(tube, PATH)
+ self._logger = logging.getLogger('poll-activity.PollSession')
+ self.tube = tube
+ self.is_initiator = is_initiator
+ self.entered = False # Have we set up the tube?
+ self._get_buddy = get_buddy # Converts handle to Buddy object
+ self.activity = activity # PollBuilder
+ self.tube.watch_participants(self.participant_change_cb)
+
+ def participant_change_cb(self, added, removed):
+ """Callback when tube participants change."""
+ self._logger.debug('Adding participants: %r' % added)
+ self._logger.debug('Removing participants: %r' % removed)
+ for handle, bus_name in added:
+ buddy = self._get_buddy(handle)
+ if buddy is not None:
+ self._logger.debug('Buddy %s was added' % buddy.props.nick)
+ for handle in removed:
+ buddy = self._get_buddy(handle)
+ if buddy is not None:
+ self._logger.debug('Buddy %s was removed' % buddy.props.nick)
+ try:
+ self.ordered_bus_names.remove(self.tube.participants[handle])
+ except ValueError:
+ # already absent
+ pass
+ if not self.entered:
+ #self.tube.add_signal_receiver(self.insert_cb, 'Insert', IFACE,
+ # path=PATH, sender_keyword='sender')
+ if self.is_initiator:
+ self._logger.debug("I'm initiating the tube, will "
+ "watch for hellos.")
+ self.add_hello_handler()
+ self.ordered_bus_names = [self.tube.get_unique_name()]
+ else:
+ self._logger.debug('Hello, everyone! What did I miss?')
+ self.Hello()
+ self.entered = True
+
+
+
+def justify(textdict, choice):
+ """Take a {} of numbers, and right justify the chosen item.
+
+ textdict is a dict of {n: m} where n and m are integers.
+ choice is one of textdict.keys()
+
+ Returns a string of ' m' with m right-justified
+ so that the longest value in the dict can fit.
+ """
+ max_len = 0
+ for num in textdict.values():
+ if len(str(num)) > max_len:
+ max_len = len(str(num))
+ value = str(textdict[choice])
+ return value.rjust(max_len)
+
+
+class LessonPlanWidget (gtk.Notebook):
+ def __init__ (self, basepath):
+ super(LessonPlanWidget, self).__init__()
+ lessons = filter(lambda x: os.path.isdir(os.path.join(basepath, 'lessons', x)), os.listdir(os.path.join(basepath, 'lessons')))
+ lessons.sort()
+ for lesson in lessons:
+ self._load_lesson(os.path.join(basepath, 'lessons', lesson), _(lesson))
+
+ def _load_lesson (self, path, name):
+ code, encoding = locale.getdefaultlocale()
+ canvas = AbiCanvas()
+ 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)
+ # On jhbuild, the first works, on XO the second works:
+ try:
+ canvas.load_file('file://%s' % files[0], 'text/plain')
+ except:
+ canvas.load_file('file://%s' % files[0])
+ canvas.view_online_layout()
+ canvas.zoom_width()
+ canvas.set_show_margin(False)
+ self.append_page(canvas, gtk.Label(name))
diff --git a/setup.py b/setup.py
new file mode 100755
index 0000000..77fda74
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,4 @@
+#!/usr/bin/env python
+from sugar.activity import bundlebuilder
+if __name__ == "__main__":
+ bundlebuilder.start()
diff --git a/tubeconn.py b/tubeconn.py
new file mode 100644
index 0000000..d1c1403
--- /dev/null
+++ b/tubeconn.py
@@ -0,0 +1,107 @@
+# This should eventually land in telepathy-python, so has the same license:
+
+# Copyright (C) 2007 Collabora Ltd. <http://www.collabora.co.uk/>
+#
+# This program 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 program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+__all__ = ('TubeConnection',)
+__docformat__ = 'reStructuredText'
+
+
+import logging
+
+from dbus.connection import Connection
+
+
+logger = logging.getLogger('telepathy.tubeconn')
+
+
+class TubeConnection(Connection):
+
+ def __new__(cls, conn, tubes_iface, tube_id, address=None,
+ group_iface=None, mainloop=None):
+ if address is None:
+ address = tubes_iface.GetDBusServerAddress(tube_id)
+ self = super(TubeConnection, cls).__new__(cls, address,
+ mainloop=mainloop)
+
+ self._tubes_iface = tubes_iface
+ self.tube_id = tube_id
+ self.participants = {}
+ self.bus_name_to_handle = {}
+ self._mapping_watches = []
+
+ if group_iface is None:
+ method = conn.GetSelfHandle
+ else:
+ method = group_iface.GetSelfHandle
+ method(reply_handler=self._on_get_self_handle_reply,
+ error_handler=self._on_get_self_handle_error)
+
+ return self
+
+ def _on_get_self_handle_reply(self, handle):
+ self.self_handle = handle
+ match = self._tubes_iface.connect_to_signal('DBusNamesChanged',
+ self._on_dbus_names_changed)
+ self._tubes_iface.GetDBusNames(self.tube_id,
+ reply_handler=self._on_get_dbus_names_reply,
+ error_handler=self._on_get_dbus_names_error)
+ self._dbus_names_changed_match = match
+
+ def _on_get_self_handle_error(self, e):
+ logging.basicConfig()
+ logger.error('GetSelfHandle failed: %s', e)
+
+ def close(self):
+ self._dbus_names_changed_match.remove()
+ self._on_dbus_names_changed(self.tube_id, (), self.participants.keys())
+ super(TubeConnection, self).close()
+
+ def _on_get_dbus_names_reply(self, names):
+ self._on_dbus_names_changed(self.tube_id, names, ())
+
+ def _on_get_dbus_names_error(self, e):
+ logging.basicConfig()
+ logger.error('GetDBusNames failed: %s', e)
+
+ def _on_dbus_names_changed(self, tube_id, added, removed):
+ if tube_id == self.tube_id:
+ for handle, bus_name in added:
+ if handle == self.self_handle:
+ # I've just joined - set my unique name
+ self.set_unique_name(bus_name)
+ self.participants[handle] = bus_name
+ self.bus_name_to_handle[bus_name] = handle
+
+ # call the callback while the removed people are still in
+ # participants, so their bus names are available
+ for callback in self._mapping_watches:
+ callback(added, removed)
+
+ for handle in removed:
+ bus_name = self.participants.pop(handle, None)
+ self.bus_name_to_handle.pop(bus_name, None)
+
+ def watch_participants(self, callback):
+ self._mapping_watches.append(callback)
+ if self.participants:
+ # GetDBusNames already returned: fake a participant add event
+ # immediately
+ added = []
+ for k, v in self.participants.iteritems():
+ added.append((k, v))
+ callback(added, [])