#!/usr/bin/env python # vi: sw=4 et # Copyright 2008 by Kate Scheppke and Wade Brainerd. # This file is part of Typing Turtle. # # Typing Turtle 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 3 of the License, or # (at your option) any later version. # # Typing Turtle 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 Typing Turtle. If not, see . # Import standard Python modules. import logging, os, math, time, copy, locale, datetime, random, re from gettext import gettext as _ # Import PyGTK. import gobject, pygtk, gtk, pango # Import Sugar UI modules. import sugar.activity.activity import sugar.graphics.style import sugar.graphics.icon class EditLessonScreen(gtk.VBox): def __init__(self, activity, lesson): gtk.VBox.__init__(self) self.set_border_width(10) self.activity = activity self.lesson = lesson self.in_build = False # Add the header. title = gtk.Label() title.set_markup("" + _("Edit a Lesson") + "") title.set_alignment(1.0, 0.0) stoplabel = gtk.Label(_('Go Back')) stopbtn = gtk.Button() stopbtn.add(stoplabel) stopbtn.connect('clicked', self.stop_clicked_cb) titlebox = gtk.HBox() titlebox.pack_start(stopbtn, False, False, 10) titlebox.pack_end(title, False, False, 10) self.vp = gtk.Viewport() self.scroll = gtk.ScrolledWindow() self.scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self.scroll.add(self.vp) self.pack_start(titlebox, False, False, 10) self.pack_start(gtk.HSeparator(), False, False, 0) self.pack_start(self.scroll, True, True, 0) self.build() self.show_all() def build_step(self, step, idx): stepbox = gtk.VBox() steplabel = gtk.Label() steplabel.set_markup("" + (_('Step #%d') % (idx+1)) + "") steplabel.set_alignment(0.0, 0.5) steplabel.set_padding(10, 0) #generatelabel = gtk.Label() #generatelabel.set_markup(_('Generate')) #generatebtn = gtk.Button() #generatebtn.add(generatelabel) delstepbtn = gtk.Button() delstepbtn.add(sugar.graphics.icon.Icon(icon_name='list-remove')) delstepbtn.connect('clicked', self.del_step_clicked_cb, idx) addstepbtn = gtk.Button() addstepbtn.add(sugar.graphics.icon.Icon(icon_name='list-add')) addstepbtn.connect('clicked', self.add_step_clicked_cb, idx) moveupbtn = gtk.Button() moveupbtn.add(sugar.graphics.icon.Icon(icon_name='go-up')) moveupbtn.connect('clicked', self.move_step_up_clicked_cb, idx) movedownbtn = gtk.Button() movedownbtn.add(sugar.graphics.icon.Icon(icon_name='go-down')) movedownbtn.connect('clicked', self.move_step_down_clicked_cb, idx) if idx == 0: moveupbtn.set_sensitive(False) if idx == len(self.lesson['steps']) - 1: movedownbtn.set_sensitive(False) btnbox = gtk.HBox() btnbox.pack_start(steplabel, False, False) btnbox.pack_end(addstepbtn, False, False) btnbox.pack_end(delstepbtn, False, False) btnbox.pack_end(moveupbtn, False, False) btnbox.pack_end(movedownbtn, False, False) #btnbox.pack_end(generatebtn, False, False) instlabel = gtk.Label() instlabel.set_markup("" + _('Instructions') + "") instlabel.set_alignment(0.0, 0.5) instlabel.set_padding(20, 0) self.labelsizegroup.add_widget(instlabel) stepbox.insttext = gtk.TextView(gtk.TextBuffer()) stepbox.insttext.props.wrap_mode = gtk.WRAP_WORD instscroll = gtk.ScrolledWindow() instscroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) instscroll.add(stepbox.insttext) instscroll.set_size_request(-1, 75) stepbox.insttext.get_buffer().set_text(step['instructions']) instbox = gtk.HBox() instbox.pack_start(instlabel, False, False) instbox.pack_start(instscroll, True, True) textlabel = gtk.Label() textlabel.set_markup("" + _('Text') + "") textlabel.set_alignment(0.0, 0.5) textlabel.set_padding(20, 0) self.labelsizegroup.add_widget(textlabel) stepbox.texttext = gtk.TextView(gtk.TextBuffer()) stepbox.texttext.props.wrap_mode = gtk.WRAP_WORD textscroll = gtk.ScrolledWindow() textscroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) textscroll.add(stepbox.texttext) textscroll.set_size_request(-1, 100) stepbox.texttext.get_buffer().set_text(step['text']) textbox = gtk.HBox() textbox.pack_start(textlabel, False, False) textbox.pack_start(textscroll, True, True) sizegroup = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL) sizegroup.add_widget(instlabel) sizegroup.add_widget(textlabel) stepbox.pack_start(btnbox, False, False, 10) stepbox.pack_start(instbox, False, False, 10) stepbox.pack_start(textbox, False, False, 10) return stepbox def build_medal(self, medal, name): box = gtk.HBox() label = gtk.Label() label.set_markup("" + name + "") label.set_alignment(0.0, 0.5) label.set_padding(20, 0) self.labelsizegroup.add_widget(label) box.pack_start(label, False, False) if self.lesson['type'] == 'normal': acclabel = gtk.Label(_('Accuracy')) wpmlabel = gtk.Label(_('WPM')) box.accent = gtk.Entry() box.wpment = gtk.Entry() box.accent.set_text(str(medal['accuracy'])) box.wpment.set_text(str(medal['wpm'])) box.pack_start(acclabel, False, False, 10) box.pack_start(box.accent, False, False) box.pack_start(wpmlabel, False, False, 10) box.pack_start(box.wpment, False, False) elif self.lesson['type'] == 'balloon': scorelabel = gtk.Label(_('Score')) box.scoreent = gtk.Entry() box.scoreent.set_text(str(medal['score'])) box.pack_start(scorelabel, False, False, 10) box.pack_start(box.scoreent, False, False) return box def build(self): self.in_build = True self.vbox = gtk.VBox() self.vbox.set_border_width(20) self.labelsizegroup = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL) # Lesson details widgets. detailslabel = gtk.Label() detailslabel.set_markup("" + _('Lesson Details') + "") detailslabel.set_alignment(0.0, 0.5) detailslabel.set_padding(10, 0) namelabel = gtk.Label() namelabel.set_markup("" + _('Name') + "") namelabel.set_alignment(0.0, 0.5) namelabel.set_padding(20, 0) self.nameent = gtk.Entry() self.nameent.set_text(self.lesson['name']) namebox = gtk.HBox() namebox.pack_start(namelabel, False, False) namebox.pack_start(self.nameent, True, True) typelabel = gtk.Label() typelabel.set_markup("" + _('Type') + "") typelabel.set_alignment(0.0, 0.5) typelabel.set_padding(20, 0) self.textradio = gtk.RadioButton(None, _('Normal Lesson')) self.textradio.connect('toggled', self.type_toggled_cb) self.balloonradio = gtk.RadioButton(self.textradio, _('Balloon Game')) self.balloonradio.connect('toggled', self.type_toggled_cb) self.textradio.set_active(self.lesson['type'] == 'normal') self.balloonradio.set_active(self.lesson['type'] == 'balloon') typebox = gtk.HBox() typebox.pack_start(typelabel, False, False) typebox.pack_start(self.textradio, False, False) typebox.pack_start(self.balloonradio, False, False) desclabel = gtk.Label() desclabel.set_markup("" + _('Description') + "") desclabel.set_alignment(0.0, 0.5) desclabel.set_padding(20, 0) self.desctext = gtk.TextView(gtk.TextBuffer()) self.desctext.props.wrap_mode = gtk.WRAP_WORD descscroll = gtk.ScrolledWindow() descscroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) descscroll.add(self.desctext) descscroll.set_size_request(-1, 75) self.desctext.get_buffer().set_text(self.lesson['description']) descbox = gtk.HBox() descbox.pack_start(desclabel, False, False) descbox.pack_start(descscroll, True, True) self.labelsizegroup.add_widget(namelabel) self.labelsizegroup.add_widget(typelabel) self.labelsizegroup.add_widget(desclabel) self.vbox.pack_start(detailslabel, False, False, 10) self.vbox.pack_start(namebox, False, False, 10) self.vbox.pack_start(typebox, False, False, 10) self.vbox.pack_start(descbox, False, False, 10) self.vbox.pack_start(gtk.HSeparator(), False, False, 0) # Steps or words widgets. if self.lesson['type'] == 'normal': if not self.lesson.has_key('steps') or len(self.lesson['steps']) == 0: step = { 'instructions': '', 'text': '' } self.lesson['steps'] = [ step ] self.vbox.pack_start(gtk.HSeparator(), False, False, 0) self.stepboxes = [] for step in self.lesson['steps']: stepbox = self.build_step(step, len(self.stepboxes)) self.stepboxes.append(stepbox) self.vbox.pack_start(stepbox, False, False, 0) if self.lesson['type'] == 'balloon': if not self.lesson.has_key('words') or len(self.lesson['words']) == 0: self.lesson['words'] = [] self.vbox.pack_start(gtk.HSeparator(), False, False, 0) textlabel = gtk.Label() textlabel.set_markup("" + _('Words') + "") textlabel.set_alignment(0.0, 0.5) textlabel.set_padding(20, 0) self.labelsizegroup.add_widget(textlabel) self.wordstext = gtk.TextView(gtk.TextBuffer()) self.wordstext.props.wrap_mode = gtk.WRAP_WORD textscroll = gtk.ScrolledWindow() textscroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) textscroll.add(self.wordstext) textscroll.set_size_request(-1, 200) self.wordstext.get_buffer().set_text(' '.join(self.lesson['words'])) textbox = gtk.HBox() textbox.pack_start(textlabel, False, False) textbox.pack_start(textscroll, True, True) self.vbox.pack_start(textbox, False, False, 10) # Medal requirements widgets. medalslabel = gtk.Label() medalslabel.set_markup("" + _('Medal Requirements') + "") medalslabel.set_alignment(0.0, 0.5) medalslabel.set_padding(10, 0) self.vbox.pack_start(gtk.HSeparator(), False, False, 0) self.vbox.pack_start(medalslabel, False, False, 10) self.medalboxes = [] self.medalboxes.append(self.build_medal(self.lesson['medals'][0], _('Bronze'))) self.medalboxes.append(self.build_medal(self.lesson['medals'][1], _('Silver'))) self.medalboxes.append(self.build_medal(self.lesson['medals'][2], _('Gold'))) self.vbox.pack_start(self.medalboxes[0], False, False, 10) self.vbox.pack_start(self.medalboxes[1], False, False, 10) self.vbox.pack_start(self.medalboxes[2], False, False, 10) self.vbox.show_all() self.in_build = False # Remove any existing controls. if self.vp.get_child(): self.vp.remove(self.vp.get_child()) self.vp.add(self.vbox) def stop_clicked_cb(self, btn): self.save() self.activity.pop_screen() def save(self): self.lesson['name'] = self.nameent.get_text() buf = self.desctext.get_buffer() self.lesson['description'] = buf.get_text(buf.get_start_iter(), buf.get_end_iter()) if self.textradio.get_active(): self.lesson['type'] = 'normal' steps = [] for sb in self.stepboxes: step = {} buf = sb.insttext.get_buffer() step['instructions'] = buf.get_text(buf.get_start_iter(), buf.get_end_iter()) buf = sb.texttext.get_buffer() step['text'] = buf.get_text(buf.get_start_iter(), buf.get_end_iter()) steps.append(step) self.lesson['steps'] = steps for i in range(0, 3): self.lesson['medals'][i]['accuracy'] = int(self.medalboxes[i].accent.get_text()) self.lesson['medals'][i]['wpm'] = int(self.medalboxes[i].wpment.get_text()) if self.balloonradio.get_active(): self.lesson['type'] = 'balloon' buf = self.wordstext.get_buffer() text = buf.get_text(buf.get_start_iter(), buf.get_end_iter()) self.lesson['words'] = text.split(' ') for i in range(0, 3): self.lesson['medals'][i]['score'] = int(self.medalboxes[i].scoreent.get_text()) def add_step_clicked_cb(self, btn, index): step = { 'instructions': '', 'text': '' } self.lesson['steps'].insert(index, step) self.build() def del_step_clicked_cb(self, btn, index): self.lesson['steps'].pop(index) self.build() def move_step_up_clicked_cb(self, btn, index): if index > 0: step = self.lesson['steps'].pop(index) self.lesson['steps'].insert(index-1, step) self.build() def move_step_down_clicked_cb(self, btn, index): if index < len(self.lesson['steps']) - 1: step = self.lesson['steps'].pop(index) self.lesson['steps'].insert(index+1, step) self.build() def type_toggled_cb(self, btn): # Prevent infinite recursion if self.in_build: return if self.textradio.get_active(): self.lesson['type'] = 'normal' if self.balloonradio.get_active(): self.lesson['type'] = 'balloon' self.build()