diff options
Diffstat (limited to 'reviewpanel.py')
-rw-r--r-- | reviewpanel.py | 308 |
1 files changed, 308 insertions, 0 deletions
diff --git a/reviewpanel.py b/reviewpanel.py new file mode 100644 index 0000000..a65c855 --- /dev/null +++ b/reviewpanel.py @@ -0,0 +1,308 @@ +# -*- coding: utf-8 -*- +#Copyright (c) 2010, Kirk Winans + +# 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 3 of the License, or +# (at your option) any later version. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. +import gtk +from os import environ +from os.path import join, basename +import hippo + +import shutil +import tempfile +from gettext import gettext as _ +import logging +from gobject import SIGNAL_RUN_FIRST, TYPE_PYOBJECT +from sugar.graphics import style +from sugar.graphics.toolbutton import ToolButton +from sugar.graphics.icon import Icon +from sugar.graphics.palette import Palette +from port.widgets import ToggleToolButton +from port.widgets import CanvasRoundBox, ToolComboBox +#from port import chooser + +from sugar.datastore import datastore +import xml.etree.ElementTree +from datetime import date +import time +_logger = logging.getLogger("test-activity") + +_1_DAY = 60 * 60 * 24 +_2_DAYS = _1_DAY * 2 +_4_DAYS = _2_DAYS * 2 +_1_WEEK = _1_DAY * 7 +_2_WEEKS = _1_WEEK * 2 +_1_MONTH = _2_WEEKS * 2 + +# +# Review Panel for the Flashcard Activity +# +class ReviewPanel(gtk.VBox): + + def __init__(self, box, catagory, expired_only): + gtk.VBox.__init__(self) + + self.catagory = catagory + self.box_number = self.get_box_number(box) + self.expired_only = expired_only + + self.view_box = gtk.HBox() + self.entry_box = gtk.HBox() + self.button_box = gtk.HButtonBox() + self.answer_box = gtk.HBox() + + self.frontlabel = gtk.Label(_('Front:')) + + self.viewcard = gtk.TextView() + self.textbuffer = self.viewcard.get_buffer() + self.viewcard.set_editable(False) + self.viewcard.set_wrap_mode(gtk.WRAP_WORD) + self.viewcard.set_justification(gtk.JUSTIFY_CENTER) + self.viewcard.set_pixels_above_lines(40) + + self.entrylabel = gtk.Label(_('Back:')) + + self.answer_entry = gtk.Entry() + + self.answerlabel = gtk.Label(_('The answer was:')) + + self.correct = gtk.TextView() + self.correcttextbuffer = self.correct.get_buffer() + self.correct.set_editable(False) + self.correct.set_wrap_mode(gtk.WRAP_WORD) + self.correct.set_justification(gtk.JUSTIFY_CENTER) + self.correct.set_pixels_above_lines(40) + + _checkbutton = ToolButton(tooltip=_('Check Answer!')) + _checkbutton.connect('clicked', self._check_answer_cb) + _checkbutton.set_icon_widget( + self.make_label('next', ' ' + _('Check Answer!'))) + + self.view_box.pack_start(self.frontlabel) + self.view_box.pack_start(self.viewcard) + + self.entry_box.pack_start(self.entrylabel) + self.entry_box.pack_start(self.answer_entry) + + self.button_box.pack_start(_checkbutton) + + self.answer_box.pack_start(self.answerlabel) + self.answer_box.pack_start(self.correct) + + + self.pack_start(self.view_box) + self.pack_start(self.entry_box) + self.pack_start(self.answer_box) + self.pack_start(self.button_box) + + self.frontlabel.show() + self.viewcard.show() + + self.entrylabel.show() + self.answer_entry.show() + + self.answerlabel.show() + self.correct.show() + + _checkbutton.show() + + self.view_box.show() + self.entry_box.show() + self.answer_box.show() + self.button_box.show() + + self.current_date = time.time() + + self.testfile = "testfile.xml" + + self.tree = xml.etree.ElementTree.parse(self.testfile) + + self.deck = self.get_selected_deck() + + self.current_card_index = 0 + + self.card = self.next_card() + + self.textbuffer.set_text(self.card.find("front").text) + + # Returns the box number of the selected box + def get_box_number(self, box): + if box == "Every Day": + return "0" + elif box == "Every 2 Days": + return "1" + elif box == "Every 4 Days": + return "2" + elif box == "Every Week": + return "3" + elif box == "Every 2 Weeks": + return "4" + elif box == "Every Month": + return "5" + else: + return box + + + # Check answer callback + def _check_answer_cb(self, button): + self.correcttextbuffer.set_text(self.check_answer()) + self.answer_entry.set_text("") + self.card = self.next_card() + self.textbuffer.set_text(self.card.find("front").text) + + + # Checks the answer submitted, returns "Correct" or the back of the card + def check_answer(self): + if self.answer_entry.get_text() == self.card.find("back").text: + if self.expired_only: + new_stage = int(self.card.find("stage").text) + 1 + self.update_card(new_stage) + return "Correct!" + + else: + if self.expired_only: + self.update_card(0) + return self.card.find("back").text + + # Returns the selected deck, based on expiration, + # the box, and the category + def get_selected_deck(self): + if self.expired_only: + selected_deck = self.get_all_expired() + + else: + selected_deck = self.tree.getroot() + + selected_deck = self.get_selected_box(selected_deck) + + selected_deck = self.get_selected_catagory(selected_deck) + + return selected_deck + + + # Returns all the expired cards + def get_all_expired(self): + deck = self.tree.getroot() + expired_deck = [] + for card in deck: + if self.card_is_expired(card): + expired_deck = expired_deck + [card] + return expired_deck + + # Returns True if the card is expired + def card_is_expired(self, card): + card_stage = card.find("stage").text + card_date = float(card.find("last_reviewed").text) + date_difference = self.current_date - card_date + if (card_stage == "0") and (date_difference > _1_DAY): + return True + + elif (card_stage == "1") and (date_difference > _2_DAYS): + return True + + elif (card_stage == "2") and (date_difference > _4_DAYS): + return True + + elif (card_stage == "3") and (date_difference > _1_WEEK): + return True + + elif (card_stage == "4") and (date_difference > _2_WEEKS): + return True + + elif (card_stage == "5") and (date_differnce > _1_MONTH): + return True + + else: + return False + + # Modifies the deck for the selected box, returns the deck + def get_selected_box(self, selected_deck): + if self.box_number != "All": + selected_box = [] + for card in selected_deck: + if card.find("stage").text == self.box_number: + selected_box = selected_box + [card] + return selected_box + else: + return selected_deck + + # Modifies the deck for teh selected category, returns the deck + def get_selected_catagory(self, selected_deck): + catagory_deck = [] + if self.catagory != "All": + for card in selected_deck: + if card.find("catagory").text == self.catagory: + catagory_deck = catagory_deck + [card] + return catagory_deck + else: + return selected_deck + + # returns the next card to be reviewed, if there are no more, + # returns an empty card + def next_card(self): + if len(self.deck) > 0 and self.current_card_index < len(self.deck): + next_card = self.deck[self.current_card_index] + + self.current_card_index += 1 + + return next_card + + else: + return self.gen_empty_card() + + + # Returns an empty card that states there are no Cards to Review + def gen_empty_card(self): + + empty_card = xml.etree.ElementTree.Element("card") + + e_c_front = xml.etree.ElementTree.Element("front") + e_c_back = xml.etree.ElementTree.Element("back") + e_c_last = xml.etree.ElementTree.Element("last_reviewed") + e_c_stage = xml.etree.ElementTree.Element("stage") + e_c_catagory = xml.etree.ElementTree.Element("catagory") + + e_c_front.text = "No Cards to Review!" + e_c_back.text = "None" + e_c_last.text = str(time.time()) + e_c_stage.text = "0" + e_c_catagory.text = "None" + + empty_card.append(e_c_front) + empty_card.append(e_c_back) + empty_card.append(e_c_last) + empty_card.append(e_c_stage) + empty_card.append(e_c_catagory) + + return empty_card + + # updates the card after it has been reviewed to reflect + # the new box and its last reviewed date + def update_card(self, stage): + + self.card.find("last_reviewed").text = str(time.time()) + self.card.find("stage").text = str(stage) + + self.tree.write(self.testfile) + + # Gets the icon for the button and makes the label + # Written by Simon Schampijer + def make_label(self, icon_name, label): + label_box = gtk.HBox() + icon = Icon( + icon_name=icon_name, + icon_size=gtk.ICON_SIZE_LARGE_TOOLBAR) + label_box.pack_start(icon, False) + label = gtk.Label(label) + label.modify_fg(gtk.STATE_NORMAL, + style.COLOR_TOOLBAR_GREY.get_gdk_color()) + label_box.pack_start(label) + label_box.show_all() + return label_box |