# -*- 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 _REVIEWED = False # # Review Panel for the Flashcard Activity # class ReviewPanel(gtk.VBox): def __init__(self, deckfile, 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!'))) _nextcard = ToolButton(tooltip=_('Next Card')) _nextcard.connect('clicked', self._next_card_cb) _nextcard.set_icon_widget( self.make_label('next', ' ' + _('Next Card'))) 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.button_box.pack_start(_nextcard) 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() _nextcard.show() self.view_box.show() self.entry_box.show() self.answer_box.show() self.button_box.show() self.current_date = time.time() self.deckfile = deckfile self.tree = xml.etree.ElementTree.parse(self.deckfile) self.deck = self.get_selected_deck() self.current_card_index = 0 self.card = self.next_card() self.card_reviewed = False 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.card_reviewed = True def _next_card_cb(self, button): if self.card_reviewed: self.answer_entry.set_text("") self.card = self.next_card() self.textbuffer.set_text(self.card.find("front").text) self.correcttextbuffer.set_text("") self.card_reviewed = False # 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.deckfile) # 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