# Copyright 2011-2012 Almira Cayetano # Copyright 2011-2012 Christian Joy Aranas # Copyright 2011-2012 Ma. Rowena Solamo # Copyright 2011-2012 Rommel Feria # # University of the Philippines # College of Engineering # Department of Computer Science # # 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 # # Copyright 2007-2008 One Laptop Per Child Chat Activity for the method on # connecting sugar activities # Copyright 2008 Sven Festersen for the pygtk_chart library import pygtk pygtk.require('2.0') import gtk, gobject from Models import * from Template import Template import datetime import pango from Bundler import Bundler from pygtk_chart import multi_bar_chart import cjson import logging import telepathy from dbus.service import method, signal from dbus.gobject_service import ExportedGObject from sugar.activity.activity import Activity, ActivityToolbox from sugar.activity import activity from sugar.graphics.alert import NotifyAlert from sugar.presence import presenceservice from sugar.presence.tubeconn import TubeConnection from telepathy.interfaces import ( CHANNEL_INTERFACE, CHANNEL_INTERFACE_GROUP, CHANNEL_TYPE_TEXT, CONN_INTERFACE_ALIASING) from telepathy.constants import ( CHANNEL_GROUP_FLAG_CHANNEL_SPECIFIC_HANDLES, CHANNEL_TEXT_MESSAGE_TYPE_NORMAL) from telepathy.client import Connection, Channel SERVICE = "org.laptop.ScorePad" IFACE = SERVICE PATH = "/org/laptop/ScorePad" BORDER_COLOR = '#FFDE00' BACKGROUND_COLOR = '#66CC00' BUTTON_COLOR = '#097054' WHITE = '#FFFFFF' BLUE = '#82CAFA' lessonplan_path = 'LessonPlanTemplate.txt' PROJECTLIST = [] TITLELIST = [] FRIENDSTITLELIST = [] FRIENDSPROJECTLIST = [] RUBRICLIST = [] RUBRICTITLE = [] OTHER_RUBRICLIST = [] OTHER_RUBRICTITLE = [] def xpm_label_box(xpm_filename, label_text): box1 = gtk.HBox(False, 0) image = gtk.Image() image.set_from_file(xpm_filename) label = gtk.Label(label_text) box1.pack_start(image, False, False, 0) if label_text != "": box1.pack_start(label, False, False, 3) image.show() label.show() return box1 def theme_button(button): button.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(BUTTON_COLOR)) return button def theme_box(box, color): eb = gtk.EventBox() box.set_border_width(5) eb.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(color)) eb.add(box) return eb class ScorePadActivity(activity.Activity): def __init__(self, handle): Activity.__init__(self, handle) self.set_title('ScorePad Activity') toolbox = ActivityToolbox(self) self.set_toolbox(toolbox) toolbox.show() self.pservice = presenceservice.get_instance() owner = self.pservice.get_owner() self.owner = owner self.owner_nick = owner.props.nick main_canvas = self.build_root() self.set_canvas(main_canvas) main_canvas.show_all() self.is_shared = False self.text_channel = None if self.shared_activity: self.connect('joined', self._joined_cb) if self.get_shared(): self._joined_cb(self) else: self.connect('shared', self._shared_cb) def build_root(self): self.scorepadDB = ScorePadDB(self.owner_nick) try: self.scorepadDB.create_tables() template = Template(self.owner_nick) template.save_template() except: print "tables exist" list = self.scorepadDB.queryall_rubric(1) for temp in list: RUBRICLIST.append(temp) RUBRICTITLE.append(temp.title) list = self.scorepadDB.queryall_rubric(0) for temp in list: OTHER_RUBRICLIST.append(temp) OTHER_RUBRICTITLE.append(temp.title) list = self.scorepadDB.queryall_project(1) for temp in list: PROJECTLIST.append(temp) TITLELIST.append(temp.title) list = self.scorepadDB.queryall_project(0) for temp in list: FRIENDSPROJECTLIST.append(temp) FRIENDSTITLELIST.append(temp.title) print "friends :" +str(temp.title) self.is_owned = True self.category_titles = [] #submit grades self.is_exists = False self.main_table = gtk.HPaned() self.main_table.set_position(270) self.main_table.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(BACKGROUND_COLOR)) self.main_table.modify_bg(gtk.STATE_ACTIVE, gtk.gdk.Color(BACKGROUND_COLOR)) menupanel = self.build_menupanel() self.main_table.add1(menupanel) self.build_startpage("Start Page") main_table_eb = theme_box(self.main_table, BACKGROUND_COLOR) return main_table_eb def build_menupanel(self): menupanel = gtk.Table(2,1, True) menupanel.set_border_width(2) logo = gtk.Image() logo.set_from_file("images/hello2.png") logo.show() project_button = gtk.Button("Projects") project_button = theme_button(project_button) project_button.connect("clicked", self.project_cb, "Projects") create_button = gtk.Button("Create New Project") create_button = theme_button(create_button) create_button.connect("clicked", self.addproject_cb, "Create new project") rubrics_button = gtk.Button("Rubrics") rubrics_button = theme_button(rubrics_button) rubrics_button.connect("clicked", self.rubrics_cb, "Rubrics") lessonplan_button = gtk.Button("Lesson Plan") lessonplan_button = theme_button(lessonplan_button) lessonplan_button.connect("clicked", self.lessonplan_cb) tutorial_button = gtk.Button("Tutorial") tutorial_button = theme_button(tutorial_button) tutorial_button.connect("clicked", self.tutorial_cb) button_array = [project_button, create_button, rubrics_button, lessonplan_button, tutorial_button] menupanel.attach(logo,0,1,0,1) menu_table_box = gtk.VBox(False,0) for i in range(5) : button = theme_box(button_array[i], BORDER_COLOR) menu_table_box.add(button) menupanel.attach(menu_table_box,0,1,1,2) return menupanel def build_startpage(self,label): self.build_processframe(label) logo = gtk.Image() logo.set_from_file("images/wel2.png") self.processtable.attach(logo, 0,2,0,12) self.main_table.show_all() def build_processframe(self,label): self.processtable = gtk.Table(12,2,True) self.processpanel = gtk.Frame() self.processpanel.add(self.processtable) self.processpanel.set_label(label) self.main_table.add2(self.processpanel) self.main_table.show_all() def addproject_cb(self,widget,label): entries = self.build_projectentry(label) finalize_button = gtk.Button(" Finalize ") finalize_button = theme_button(finalize_button) finalize_button.connect("clicked", self.finalize_cb, entries) box = gtk.HBox(False,0) box.pack_start(finalize_button,False,False,0) box = theme_box(box, BORDER_COLOR) self.processtable.attach(box, 0,3, 11,12) self.main_table.show_all() def build_projectentry(self,label): self.processpanel.destroy() self.build_processframe(label) title_label = gtk.Label("Project Title") author_label = gtk.Label("Author") description_label = gtk.Label("Project Description") subject_label = gtk.Label("Subject") date_label = gtk.Label("Date") rubric_label = gtk.Label("Rubric Name") title = gtk.Entry(50) author = gtk.Entry(50) description = gtk.TextView() description.set_wrap_mode(gtk.WRAP_WORD) description.modify_base(gtk.STATE_NORMAL, gtk.gdk.Color(BLUE)) description.set_border_width(3) subject = gtk.Entry(50) publish_date = gtk.Entry(50) rubric_combobox = gtk.ComboBox() rubric_list = gtk.ListStore(str) cell = gtk.CellRendererText() rubric_combobox.pack_start(cell) rubric_combobox.add_attribute(cell, 'text', 0) today = datetime.date.today() publish_date.set_text(str(today)) for i in range(len(RUBRICTITLE)): rubric_list.append([RUBRICTITLE[i]]) rubric_combobox.set_model(rubric_list) rubric_combobox.set_active(0) label = [title_label, author_label,description_label,subject_label,date_label,rubric_label] entries = [title, author, description,subject,publish_date,rubric_combobox] j = 0 for i in range(6): if j == 2: self.processtable.attach(label[i],0,1,j,5) entry = entries[i] entry.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(BUTTON_COLOR)) self.processtable.attach(entries[i],1,3,j,5) j = 4 else : if i == 5: self.processtable.attach(label[i],0,1,j,j+1) entry = entries[i] entry.modify_bg(gtk.STATE_NORMAL,gtk.gdk.Color(BORDER_COLOR)) self.processtable.attach(entry,1,3,j,j+1) else : self.processtable.attach(label[i],0,1,j,j+1) entry = entries[i] entry.modify_bg(gtk.STATE_NORMAL,gtk.gdk.Color(BORDER_COLOR)) self.processtable.attach(entries[i],1,3,j,j+1) j = j+1 return entries def finalize_cb(self,widget,entries): project = self.get_entries(entries) if self.scorepadDB.project_exists(project.project_sha, project.author): md = gtk.MessageDialog(parent = None, buttons = gtk.BUTTONS_OK, \ flags = gtk.DIALOG_DESTROY_WITH_PARENT, \ type = gtk.MESSAGE_INFO,\ message_format = "Error. Duplicated project.") md.run() md.destroy() else: self.scorepadDB.insert_project(project) project_id = self.scorepadDB.query_maxproject() project.project_id = project_id rubric_id = project.rubric_id rubric = self.scorepadDB.query_rubric(rubric_id) categories = self.scorepadDB.queryall_category(rubric_id) self.initialize_score(project, rubric, categories) TITLELIST.append(project.title) PROJECTLIST.append(project) self.processpanel.destroy() self.build_processframe("Projects") tuplelist1 = (TITLELIST, PROJECTLIST) tuplelist2 = (FRIENDSTITLELIST, FRIENDSPROJECTLIST) projectlist = self.build_projectpanel(tuplelist1, tuplelist2) self.processtable.attach(projectlist,0,2,0,11) actionpanel = self.build_project_actionpanel() self.processtable.attach(actionpanel,0,2,11,12) self.main_table.show_all() def editproject_cb(self, widget, label): try: if self.is_owned: project = PROJECTLIST[self.selected_project] entries = self.build_projectentry(label) update_button = gtk.Button(" Update ") update_button = theme_button(update_button) update_button.connect("clicked", self.update_cb, entries) box = gtk.HBox(False,0) box.pack_start(update_button, False,False,0) box = theme_box(box,BORDER_COLOR) self.processtable.attach(box, 0,3, 11,12) self.set_entries(entries, project) self.main_table.show_all() else: md = gtk.MessageDialog(parent = None, buttons = gtk.BUTTONS_OK, \ flags = gtk.DIALOG_DESTROY_WITH_PARENT, \ type = gtk.MESSAGE_INFO,\ message_format = "Sorry. You cannot edit your friend's project.") md.run() md.destroy() except: md = gtk.MessageDialog(parent = None, buttons = gtk.BUTTONS_OK, \ flags = gtk.DIALOG_DESTROY_WITH_PARENT, \ type = gtk.MESSAGE_INFO,\ message_format = "Error. No project selected.") md.run() md.destroy() def update_cb(self,widget,entries): modified_project = self.get_entries(entries) project = PROJECTLIST[self.selected_project] modified_project.project_id = project.project_id self.scorepadDB.update_project(modified_project) TITLELIST[self.selected_project] = modified_project.title PROJECTLIST[self.selected_project] = modified_project self.processpanel.destroy() self.build_processframe("Projects") tuplelist1 = (TITLELIST, PROJECTLIST) tuplelist2 = (FRIENDSTITLELIST, FRIENDSPROJECTLIST) projectlist = self.build_projectpanel(tuplelist1, tuplelist2) self.processtable.attach(projectlist,0,2,0,11) actionpanel = self.build_project_actionpanel() self.processtable.attach(actionpanel,0,2,11,12) self.main_table.show_all() def set_entries(self,entries,project): entries[0].set_text(project.title) entries[1].set_text(project.author) buffer = entries[2].get_buffer() buffer.set_text(project.description) entries[3].set_text(project.subject) rubric = self.scorepadDB.query_rubric(project.rubric_id) for i in range(len(RUBRICTITLE)): if str(rubric.title) == str(RUBRICTITLE[i]): active_rubric = i entries[4].set_text(project.publish_date) entries[5].set_active(active_rubric) def get_entries(self,entries): title = entries[0].get_text() author = entries[1].get_text() description_buffer = entries[2].get_buffer() start = description_buffer.get_start_iter() end = description_buffer.get_end_iter() description = description_buffer.get_text(start,end,True) subject = entries[3].get_text() publish_date = entries[4].get_text() model = entries[5].get_model() chosen_rubric = entries[5].get_active() rubric = model[chosen_rubric][0] for r in RUBRICLIST: if str(r.title) == str(rubric): rubric_id = r.rubric_id is_shared = 0 is_owned = 1 project = Project(None,title,author,description,subject,publish_date,is_owned,is_shared,rubric_id, self.owner_nick,"") return project def viewproject_details(self,widget,row,col,tuple): buffer = tuple[0] projectlist = tuple[1] buffer.set_text("") r = row[0] self.selected_project = r self.is_owned = tuple[2] print self.selected_project project = projectlist[r] print "rubric id : "+str(project.rubric_id) print "project id :"+str(project.project_id) rubric = self.scorepadDB.query_rubric(project.rubric_id) details ="===PROJECT DETAILS===\n\n"+"Title :\n -"+project.title+"\n"+\ "Author :\n -"+project.author+"\n"+\ "Description :\n -"+project.description+"\n"+\ "Subject :\n -"+project.subject+"\n"+\ "Date :\n -"+str(project.publish_date)+"\n"+\ "Rubric :\n -"+rubric.title+"\n" buffer.set_text(details) def deleteproject_cb(self,widget,data=None): try: if self.is_owned == True: project_id = PROJECTLIST[self.selected_project].project_id else: project_id = FRIENDSPROJECTLIST[self.selected_project].project_id warning = gtk.MessageDialog(parent = None,buttons = gtk.BUTTONS_YES_NO, \ flags =gtk.DIALOG_DESTROY_WITH_PARENT,\ type = gtk.MESSAGE_WARNING,\ message_format = "Are you sure you want to delete the project?") result = warning.run() if result == gtk.RESPONSE_YES: print "Yes was clicked" if self.is_owned == True: self.scorepadDB.delete_project(project_id) TITLELIST.remove(TITLELIST[self.selected_project]) PROJECTLIST.remove(PROJECTLIST[self.selected_project]) else: self.scorepadDB.delete_project(project_id) FRIENDSTITLELIST.remove(TITLELIST[self.selected_project]) FRIENDSPROJECTLIST.remove(PROJECTLIST[self.selected_project]) warning.destroy() elif result == gtk.RESPONSE_NO: print "No was clicked" warning.destroy() self.processpanel.destroy() self.build_processframe("Projects") tuplelist1 = (TITLELIST, PROJECTLIST) tuplelist2 = (FRIENDSTITLELIST, FRIENDSPROJECTLIST) projectlist = self.build_projectpanel(tuplelist1, tuplelist2) self.processtable.attach(projectlist,0,2,0,11) actionpanel = self.build_project_actionpanel() self.processtable.attach(actionpanel,0,2,11,12) self.main_table.show_all() except: md = gtk.MessageDialog(parent = None, buttons = gtk.BUTTONS_OK, \ flags = gtk.DIALOG_DESTROY_WITH_PARENT, \ type = gtk.MESSAGE_INFO,\ message_format = "Error. No project selected.") md.run() md.destroy() def share_cb(self,widget,data=None): if self.is_shared : if self.is_owned: project = PROJECTLIST[self.selected_project] print "selected " + str(self.selected_project) bundler = Bundler() project_bundle = bundler.bundle_project(project) rubric_id = project.rubric_id rubric = self.scorepadDB.query_rubric(rubric_id) rubric_bundle = bundler.bundle_rubric(rubric) categories = self.scorepadDB.queryall_category(rubric_id) category_bundle = bundler.bundle_category(categories) level_bundle_list = [] for category in categories: levels = self.scorepadDB.query_level(category.category_id) level_bundle = bundler.bundle_level(levels) level_bundle_list.append(level_bundle) self.sendbundle_cb(rubric_bundle) self.sendbundle_cb(project_bundle) for i in range(len(category_bundle)): self.sendbundle_cb(category_bundle[i]) level_temp = level_bundle_list[i] for level in level_temp: self.sendbundle_cb(level) self.currently_shared = project.project_sha md = gtk.MessageDialog(parent = None, buttons = gtk.BUTTONS_OK, \ flags = gtk.DIALOG_DESTROY_WITH_PARENT, \ type = gtk.MESSAGE_INFO,\ message_format = "Project shared") md.run() md.destroy() else: md = gtk.MessageDialog(parent = None, buttons = gtk.BUTTONS_OK, \ flags = gtk.DIALOG_DESTROY_WITH_PARENT, \ type = gtk.MESSAGE_INFO,\ message_format = "Cannot send other's project") md.run() md.destroy() else: md = gtk.MessageDialog(parent = None, buttons = gtk.BUTTONS_OK, \ flags = gtk.DIALOG_DESTROY_WITH_PARENT, \ type = gtk.MESSAGE_INFO,\ message_format = "Cannot share. You are not connected to anybody.") md.run() md.destroy() def project_cb(self,widget,label): self.processpanel.destroy() self.build_processframe(label) tuplelist1 = (TITLELIST, PROJECTLIST) tuplelist2 = (FRIENDSTITLELIST, FRIENDSPROJECTLIST) panel = self.build_projectpanel(tuplelist1, tuplelist2) panel.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(BACKGROUND_COLOR)) panel.set_border_width(5) self.processtable.attach(panel,0,2,0,11) actionpanel = self.build_project_actionpanel() self.processtable.attach(actionpanel,0,2,11,12) self.main_table.show_all() def build_projectpanel(self, tuplelist1, tuplelist2): vpanel = gtk.VPaned() vpanel.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(BACKGROUND_COLOR)) vpanel.modify_bg(gtk.STATE_ACTIVE, gtk.gdk.Color(BACKGROUND_COLOR)) panel = gtk.HPaned() mytitlelist = tuplelist1[0] myprojectlist = tuplelist1[1] friendstitlelist = tuplelist2[0] friendsprojectlist = tuplelist2[1] tree_store1 = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_BOOLEAN) for project in mytitlelist: tree_store1.append(None, (project,None)) tree_view1 = gtk.TreeView(tree_store1) tree_view1.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse(BLUE)) tree_view1.set_rules_hint(True) renderer1 = gtk.CellRendererText() project_column1 = gtk.TreeViewColumn("Projects", renderer1, text = 0) tree_view1.append_column(project_column1) tree_view1_scroll = gtk.ScrolledWindow() tree_view1_scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) tree_view1_scroll.add(tree_view1) vpanel.add1(tree_view1_scroll) tree_store2 = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_BOOLEAN) for friendsproject in friendstitlelist: tree_store2.append(None, (friendsproject,None)) tree_view2 = gtk.TreeView(tree_store2) tree_view2.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse(BLUE)) tree_view2.set_rules_hint(True) renderer2 = gtk.CellRendererText() project_column2 = gtk.TreeViewColumn("Friends Projects", renderer2, text = 0) tree_view2.append_column(project_column2) tree_view2_scroll = gtk.ScrolledWindow() tree_view2_scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) tree_view2_scroll.add(tree_view2) vpanel.set_position(300) vpanel.add2(tree_view2_scroll) sw = gtk.ScrolledWindow() sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) project_view = gtk.TextView() project_view.set_wrap_mode(gtk.WRAP_WORD) project_view.modify_base(gtk.STATE_NORMAL, gtk.gdk.Color(BLUE)) buffer = project_view.get_buffer() sw.add(project_view) sw = theme_box(sw, BUTTON_COLOR) panel.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(BACKGROUND_COLOR)) panel.modify_base(gtk.STATE_NORMAL, gtk.gdk.Color(BLUE)) panel.set_position(410) panel.add1(vpanel) panel.add2(sw) tuple1 = (buffer, myprojectlist,True) tuple2 = (buffer, friendsprojectlist,False) tree_view1.connect("row-activated", self.viewproject_details, tuple1) tree_view2.connect("row-activated", self.viewproject_details, tuple2) return panel def build_project_actionpanel(self): actionpanel = gtk.HBox(False, 20) leftpanel = gtk.HBox(False,5) rightpanel = gtk.HBox(False,5) edit_button = gtk.Button("Edit") edit_button = theme_button(edit_button) edit_button.connect("clicked", self.editproject_cb, "Edit Project") share_button = gtk.Button("Share") share_button = theme_button(share_button) share_button.connect("clicked", self.share_cb) evaluate_button = gtk.Button("Evaluate") evaluate_button = theme_button(evaluate_button) evaluate_button.connect("clicked", self.evaluate_cb) grades_button = gtk.Button("See Grades") grades_button = theme_button(grades_button) grades_button.connect("clicked", self.seegrades_cb) delete_button = gtk.Button("Delete") delete_button = theme_button(delete_button) delete_button.connect("clicked", self.deleteproject_cb) leftpanel.add(edit_button) leftpanel.add(share_button) rightpanel.add(evaluate_button) rightpanel.add(grades_button) rightpanel.add(delete_button) leftpanel = theme_box(leftpanel, BORDER_COLOR) rightpanel = theme_box(rightpanel, BORDER_COLOR) actionpanel.add(leftpanel) actionpanel.add(rightpanel) actionpanel.set_border_width(5) return actionpanel def evaluate_cb(self, widget): try: if self.is_owned == True: project = PROJECTLIST[self.selected_project] else: project = FRIENDSPROJECTLIST[self.selected_project] rubric = self.scorepadDB.query_rubric(project.rubric_id) self.processpanel.destroy() self.build_processframe(project.title+" by "+project.author) upperbox = self.build_upper_evalbox(project) upperbox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(BACKGROUND_COLOR)) self.processtable.attach(upperbox,0,2,0,2) lowerbox = gtk.VPaned() lowerbox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(BACKGROUND_COLOR)) lowerbox.modify_bg(gtk.STATE_ACTIVE, gtk.gdk.Color(BACKGROUND_COLOR)) rubricsbox = self.build_lower_evalbox(rubric) sw = gtk.ScrolledWindow() sw.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC) sw.add_with_viewport(rubricsbox) sw = theme_box(sw, BUTTON_COLOR) sw.set_border_width(5) lowerbox.add1(sw) sw2 = gtk.ScrolledWindow() sw2.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self.level_view = gtk.TextView() self.level_view.set_wrap_mode(gtk.WRAP_WORD) self.level_view.modify_base(gtk.STATE_NORMAL, gtk.gdk.Color(BLUE)) buffer1 = self.level_view.get_buffer() buffer1.set_text("Rubric description") sw2.add(self.level_view) sw2 = theme_box(sw2, BUTTON_COLOR) lowerbox.set_position(380) lowerbox.add2(sw2) tuple = [rubric, project] box = gtk.HBox(False,0) submit_button = gtk.Button(" Submit ") submit_button = theme_button(submit_button) submit_button.connect("clicked", self.submitgrade_cb, tuple) box.pack_start(submit_button, False, False, 0) box = theme_box(box, BORDER_COLOR) self.processtable.attach(lowerbox,0,2,2,11) self.processtable.attach(box,0,2,11,12) self.main_table.show_all() except: md = gtk.MessageDialog(parent = None, buttons = gtk.BUTTONS_OK, \ flags = gtk.DIALOG_DESTROY_WITH_PARENT, \ type = gtk.MESSAGE_INFO,\ message_format = "Error. No project selected.") md.run() md.destroy() def build_upper_evalbox(self,project): hpaned = gtk.HPaned() leftbox = gtk.Table(2,1,False) sw = gtk.ScrolledWindow() sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) description = gtk.TextView() description.set_wrap_mode(gtk.WRAP_WORD) description.modify_base(gtk.STATE_NORMAL, gtk.gdk.Color(BLUE)) buffer = description.get_buffer() buffer.set_text(project.description) sw.set_border_width(3) sw.add(description) leftbox.attach(sw,0,1,0,2) hpaned.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(BACKGROUND_COLOR)) hpaned.modify_bg(gtk.STATE_ACTIVE, gtk.gdk.Color(BACKGROUND_COLOR)) hpaned.set_position(450) leftbox = theme_box(leftbox, BORDER_COLOR) hpaned.add1(leftbox) rightbox = gtk.VBox(False,0) rubric = self.scorepadDB.query_rubric(project.rubric_id) rubric_label = gtk.Label("Rubric") rubric_entry = gtk.Entry() rubric_entry.set_text(rubric.title) rbox = gtk.HBox() rbox.add(rubric_label) rbox.add(rubric_entry) rightbox.add(rbox) date_label = gtk.Label("Date") date_entry = gtk.Entry() date_entry.set_text(project.publish_date) dbox = gtk.HBox() dbox.add(date_label) dbox.add(date_entry) rightbox.add(dbox) rightbox = theme_box(rightbox, BORDER_COLOR) hpaned.add2(rightbox) hpaned.set_border_width(5) return hpaned def build_lower_evalbox(self, rubric): rubric_id = rubric.rubric_id category = self.scorepadDB.queryall_category(rubric_id) row = len(category)+1 category_id = category[0].category_id column = len(self.scorepadDB.query_level(category_id))+1 column_names = self.scorepadDB.query_level(category_id) levels = [] for i in range(column-1): level = [] for j in range(row-1): category_id = category[j].category_id level_temp = self.scorepadDB.query_level(category_id) level.append(level_temp[i].description) levels.append(level) view = self.build_category_column(rubric, levels, column_names) return view def build_category_column(self, rubric, levels,column_names): self.tree_store = gtk.TreeStore( gobject.TYPE_STRING,gobject.TYPE_BOOLEAN,gobject.TYPE_BOOLEAN, gobject.TYPE_BOOLEAN,gobject.TYPE_BOOLEAN) column = [None, None, None, None] for i in range(len(levels)): column[i] = levels[i] rubric_id = rubric.rubric_id category = self.scorepadDB.queryall_category(rubric_id) for i in range(len(category)): self.tree_store.append( None, (category[i].name, None, None, None, None) ) view = gtk.TreeView(self.tree_store) view.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse(BLUE)) view.set_rules_hint(True) renderer = gtk.CellRendererText() column0 = gtk.TreeViewColumn("Category", renderer, text=0) column0.set_resizable(True) view.append_column(column0) view.connect("row-activated", self.viewlevel_details, rubric_id, category) renderlist = [] self.number_of_level = len(levels) for i in range(len(levels)): render = gtk.CellRendererToggle() render.set_property('indicator-size', 20) render.set_property('activatable', True) render.connect( 'toggled', self.col1_toggled_cb, i+1 ) renderlist.append(render) column = gtk.TreeViewColumn(column_names[i].name, renderlist[i]) column.add_attribute( renderlist[i], "active", i+1) column.set_resizable(True) view.append_column(column) return view def col1_toggled_cb( self, cell, path, col ): for i in range(self.number_of_level+1): if ( (self.tree_store[path][i] == True) and (i!=col) ): self.tree_store[path][i] = False self.tree_store[path][col] = not self.tree_store[path][col] return def viewlevel_details(self, widget, row, col, rubric_id, categories): selected_row = row[0] category_id = categories[selected_row].category_id category_name = categories[selected_row].name levels = self.scorepadDB.query_level(category_id) buffer = self.level_view.get_buffer() buffer.set_text("") details = "===" + str(category_name)+ "===\n\n" for level in levels: details = details + level.name + "\n" + \ " - " + level.description + "\n\n" buffer.set_text(details) def lessonplan_cb(self,widget,data= None): self.processpanel.destroy() self.build_processframe("Lesson Plan") update_lesson = gtk.Button(" Update ") update_lesson = theme_button(update_lesson) hbox = gtk.HBox(False,0) box = gtk.HBox(False,0) box.pack_start(update_lesson, False, False, 0) box = theme_box(box,BORDER_COLOR) lesson_field = gtk.TextView() lesson_field.modify_base(gtk.STATE_NORMAL, gtk.gdk.Color(BLUE)) lesson_field.set_wrap_mode(gtk.WRAP_WORD) lesson_field.set_border_width(5) lesson_buffer = lesson_field.get_buffer() self.load_lessonplan(lesson_buffer) lesson_field.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(BUTTON_COLOR)) hbox.add(lesson_field) hbox.set_border_width(5) self.processtable.attach(hbox,0,2,0,11) self.processtable.attach(box,0,2,11,12) self.main_table.show_all() def load_lessonplan(self, lesson_buffer): fp = open(lessonplan_path, 'r') lines = fp.readlines() iter = lesson_buffer.get_iter_at_offset(0) for line in lines: lesson_buffer.insert(iter, line) def rubrics_cb(self,widget,label): self.processpanel.destroy() self.build_processframe(label) hpaned = gtk.HPaned() hpaned.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(BACKGROUND_COLOR)) hpaned.modify_bg(gtk.STATE_ACTIVE, gtk.gdk.Color(BACKGROUND_COLOR)) hpaned.set_border_width(5) rubrics = RUBRICLIST title = RUBRICTITLE box1 = self.create_rubriclist(rubrics, title, "Predefined Rubrics") rubrics = OTHER_RUBRICLIST title = OTHER_RUBRICTITLE box2 = self.create_rubriclist(rubrics, title, "Other Rubrics") hpaned.set_position(450) hpaned.add1(box1) hpaned.add2(box2) self.processtable.attach(hpaned,0,2,0,12) self.main_table.show_all() def create_rubriclist(self, rubrics, title, label): rubricsbox = gtk.VBox(False,0) buttons = [] separator0 = gtk.HSeparator() rubricsbox.pack_start(separator0, False,False,2) label = gtk.Label(label) rubricsbox.pack_start(label, False,False,0) separator1 = gtk.HSeparator() rubricsbox.pack_start(separator1, False,False,2) for i in range(len(title)): for r in rubrics: if str(title[i]) == str(r.title): rubric = r button = gtk.Button() box = xpm_label_box( "images/green_button2.png", title[i]) button.add(box) button = theme_button(button) button.connect("clicked", self.viewrubric_cb, rubric) buttons.append(button) rubricsbox.pack_start(button,False, False,2) rubricsbox = theme_box(rubricsbox, BACKGROUND_COLOR) return rubricsbox def viewrubric_cb(self, widget, rubric): self.processpanel.destroy() self.build_processframe("Rubric") box = self.build_rubriclist(rubric) sw = gtk.ScrolledWindow() sw.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC) sw.add_with_viewport(box) sw.set_border_width(5) sw = theme_box(sw, BUTTON_COLOR) self.processtable.attach(sw,0,2,0,12) self.main_table.show_all() def build_rubriclist(self, rubric): rubric_id = rubric.rubric_id category = self.scorepadDB.queryall_category(rubric_id) row = len(category)+1 category_id = category[0].category_id column = len(self.scorepadDB.query_level(category_id))+1 column_names = self.scorepadDB.query_level(category_id) levels = [] for i in range(column-1): level = [] for j in range(row-1): category_id = category[j].category_id level_temp = self.scorepadDB.query_level(category_id) level.append(level_temp[i].description) levels.append(level) view = self.build_categorylist(rubric, levels, column_names) return view def build_categorylist(self, rubric, levels,column_names): tree_store = gtk.TreeStore( gobject.TYPE_STRING,gobject.TYPE_STRING,gobject.TYPE_STRING, gobject.TYPE_STRING,gobject.TYPE_STRING) column = [None, None, None, None] for i in range(len(levels)): column[i] = levels[i] rubric_id = rubric.rubric_id category = self.scorepadDB.queryall_category(rubric_id) for i in range(len(category)): tree_store.append( None, (category[i].name, column[0][i], column[1][i], column[2][i],column[3][i]) ) view = gtk.TreeView(tree_store) view.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse(BLUE)) view.set_rules_hint(True) renderer = gtk.CellRendererText() column0 = gtk.TreeViewColumn("Category", renderer, text=0) column0.set_resizable(True) view.append_column(column0) for i in range(len(levels)): render = gtk.CellRendererText() column = gtk.TreeViewColumn(column_names[i].name, render, text=i+1) column.set_resizable(True) view.append_column(column) return view def submitgrade_cb(self, widget, tuple): rubric = tuple[0] project = tuple[1] project_id = project.project_id rubric_id = rubric.rubric_id categories = self.scorepadDB.queryall_category(rubric_id) self.initialize_score(project, rubric, categories) category_id = categories[0].category_id level_list = self.scorepadDB.query_level(category_id) level_name = "" for i in range(len(categories)): category_id = categories[i].category_id for j in range(len(level_list)+1): if (self.tree_store[i][j] == True): level_name = level_list[j-1].name level_id = self.scorepadDB.querylevel_id(category_id, level_name) score_id = self.scorepadDB.increment_scorecount(project_id, rubric_id, category_id, level_id) score = self.scorepadDB.query_score2(project_id, rubric_id, category_id, level_id) bundler = Bundler() score_bundle = bundler.bundle_score(score) is_send = False if self.is_shared: self.sendbundle_cb(score_bundle) is_send = True if is_send: md = gtk.MessageDialog(parent = None, buttons = gtk.BUTTONS_OK, \ flags = gtk.DIALOG_DESTROY_WITH_PARENT, \ type = gtk.MESSAGE_INFO,\ message_format = "Evaluation sent!") md.run() md.destroy() self.processpanel.destroy() self.build_processframe("Projects") tuplelist1 = (TITLELIST, PROJECTLIST) tuplelist2 = (FRIENDSTITLELIST, FRIENDSPROJECTLIST) panel = self.build_projectpanel(tuplelist1, tuplelist2) panel.set_border_width(5) self.processtable.attach(panel,0,2,0,11) actionpanel = self.build_project_actionpanel() self.processtable.attach(actionpanel,0,2,11,12) self.main_table.show_all() def initialize_score(self, project, rubric, categories): project_id = project.project_id rubric_id = rubric.rubric_id for category in categories: category_id = category.category_id levels = self.scorepadDB.query_level(category_id) for level in levels: level_id = level.level_id if self.scorepadDB.score_exists(project_id, rubric_id, category_id, level_id): print 'score row exists' else: project_sha = self.scorepadDB.query_project_sha(project_id) rubric_sha = self.scorepadDB.query_rubric_sha(rubric_id) category_sha = self.scorepadDB.query_category_sha(category_id) level_sha = self.scorepadDB.query_level_sha(level_id) score = Score(None, project_id, rubric_id, category_id, level_id, str(project_sha), str(rubric_sha),str(category_sha),str(level_sha), 0) self.scorepadDB.insert_score(score) def seegrades_cb(self, widget, data =None): try: if self.is_owned == True: project = PROJECTLIST[self.selected_project] rubric = self.scorepadDB.query_rubric(project.rubric_id) self.processpanel.destroy() self.build_processframe(project.title+" by "+project.author) upperbox = self.build_upper_evalbox(project) upperbox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(BACKGROUND_COLOR)) self.processtable.attach(upperbox,0,2,0,2) self.build_lower_gradebox(project, rubric) else: md = gtk.MessageDialog(parent = None, buttons = gtk.BUTTONS_OK, \ flags = gtk.DIALOG_DESTROY_WITH_PARENT, \ type = gtk.MESSAGE_INFO,\ message_format = "Sorry. You cannot display your friend's grade") md.run() except: md = gtk.MessageDialog(parent = None, buttons = gtk.BUTTONS_OK, \ flags = gtk.DIALOG_DESTROY_WITH_PARENT, \ type = gtk.MESSAGE_INFO,\ message_format = "Error. No project selected.") md.run() md.destroy() md.destroy() def build_lower_gradebox(self, project, rubric): project_id = project.project_id rubric_id = rubric.rubric_id categories = self.scorepadDB.queryall_category(rubric_id) category_id = categories[0].category_id navpanel = gtk.HBox(False) left_arrow = gtk.Button("Left") left_arrow = theme_button(left_arrow) right_arrow = gtk.Button("Right") right_arrow = theme_button(right_arrow) navpanel.add(left_arrow) navpanel.add(right_arrow) navpanel = theme_box(navpanel, BORDER_COLOR) self.processtable.attach(navpanel,1,2,11,12) category_list = "" for category in categories: category_list = category_list + str(category.name) +" " level_list = "" levels = self.scorepadDB.query_level(category_id) for level in levels: level_list = level_list + str(level.name) + " " self.category_length = len(categories) self.number_of_click = 3 if self.category_length == (1 or 2 or 3): barchart = self.build_barchart(category_list, categories, level_list, project_id, rubric_id) else : partial_cat_list = "" partial_cat_list = str(categories[0].name) + " " + str(categories[1].name) + " " + str(categories[2].name) partial_cat = [] partial_cat.append(categories[0]) partial_cat.append(categories[1]) partial_cat.append(categories[2]) barchart = self.build_barchart(partial_cat_list, partial_cat, level_list, project_id, rubric_id) self.chartbox = gtk.VBox() self.chartbox.set_border_width(5) self.chartbox.add(barchart) self.chartbox = theme_box(self.chartbox, BUTTON_COLOR) self.processtable.attach(self.chartbox, 0,2,2,11) self.main_table.show_all() navparam = [categories, level_list, project_id, rubric_id] right_arrow.connect("clicked", self.navigate_cb, "0", navparam) left_arrow.connect("clicked", self.navigate_cb, "1", navparam) def navigate_cb(self, widget,position, navparam): categories = navparam[0] #b level_list = navparam[1] #c project_id = navparam[2] #d rubric_id = navparam[3] #e self.chartbox.destroy() self.chartbox = gtk.VBox() self.chartbox.set_border_width(5) if position == "0": self.number_of_click = self.number_of_click + 3 else : self.number_of_click = self.number_of_click -3 if self.number_of_click <= self.category_length and self.number_of_click != 0: a = "" a = str(categories[self.number_of_click-3].name) + " " + str(categories[self.number_of_click-2].name) + " " \ + str(categories[self.number_of_click-1].name) b = [] b.append(categories[self.number_of_click-3]) b.append(categories[self.number_of_click-2]) b.append(categories[self.number_of_click-1]) barchart = self.build_barchart(a,b,level_list,project_id,rubric_id) self.chartbox.add(barchart) self.chartbox = theme_box(self.chartbox, BUTTON_COLOR) self.processtable.attach(self.chartbox, 0,2,2,11) self.main_table.show_all() else: if ((self.number_of_click - self.category_length) == 2): a = "" a = str(categories[self.category_length-1].name) b = [] b.append(categories[self.category_length-1]) barchart = self.build_barchart(a,b,level_list,project_id,rubric_id) self.chartbox.add(barchart) self.chartbox = theme_box(self.chartbox, BUTTON_COLOR) self.processtable.attach(self.chartbox, 0,2,2,11) self.main_table.show_all() if ((self.number_of_click - self.category_length) == 1): a = "" a = str(categories[self.category_length-2].name) + " " + str(categories[self.number_of_click-1].name) b = [] b.append(categories[self.category_length-2]) b.append(categories[self.category_length-1]) barchart = self.build_barchart(a,b,level_list,project_id,rubric_id) self.chartbox.add(barchart) self.chartbox = theme_box(self.chartbox, BUTTON_COLOR) self.processtable.attach(self.chartbox, 0,2,2,11) self.main_table.show_all() else: print "Out of bounds" def build_barchart(self,category_list, categories, level_list, project_id, rubric_id): barchart = multi_bar_chart.MultiBarChart() barchart.title.set_text('Grades') barchart.set_mode(multi_bar_chart.MODE_HORIZONTAL) i = 0 for categoryname in category_list.split(): categoryname_label = categoryname.capitalize() multibar = multi_bar_chart.BarGroup(categoryname, categoryname_label) category_id = categories[i].category_id levels_temp = self.scorepadDB.query_level(category_id) j = 0 for levelname in level_list.split(): count = 0 level_id = levels_temp[j].level_id count = self.scorepadDB.query_score(project_id, rubric_id, category_id, level_id) levelname_label = levelname.capitalize() sub_bar = multi_bar_chart.Bar(levelname, count, levelname_label) multibar.add_bar(sub_bar) print "count : " + str(count) j = j+1 barchart.add_bar(multibar) i = i + 1 return barchart def tutorial_cb(self, widget, data=None): md = gtk.MessageDialog(parent = None, buttons = gtk.BUTTONS_OK, \ flags = gtk.DIALOG_DESTROY_WITH_PARENT, \ type = gtk.MESSAGE_INFO,\ message_format = "Under construction.") md.run() md.destroy() def update_status(self, nick, text): text = text.split("|") model_name = text[0] if model_name == "Project": self._alert("Project was shared by", nick) if self.is_exists: rubric_id = self.rubric_exists else: rubric_id = self.scorepadDB.query_maxrubric() project = Project(None, text[2], text[3], text[4], text[5],text[6],\ 0, 1, rubric_id, text[10], text[11]) if self.scorepadDB.project_exists(project.project_sha, project.author): print "project exists" else: self.scorepadDB.insert_project(project) project_id = self.scorepadDB.query_maxproject() project = self.scorepadDB.query_project(project_id) FRIENDSPROJECTLIST.append(project) FRIENDSTITLELIST.append(project.title) self.currently_shared = project.project_sha tuplelist1 = (TITLELIST, PROJECTLIST) tuplelist2 = (FRIENDSTITLELIST, FRIENDSPROJECTLIST) self.processpanel.destroy() self.build_processframe("Projects") panel = self.build_projectpanel(tuplelist1, tuplelist2) panel.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(BACKGROUND_COLOR)) panel.set_border_width(5) self.processtable.attach(panel,0,2,0,11) actionpanel = self.build_project_actionpanel() self.processtable.attach(actionpanel,0,2,11,12) self.main_table.show_all() if model_name == "Rubric": rubric = Rubric(None, text[2], text[3], text[4], 0, text[6], text[7]) self.rubric_exists = self.scorepadDB.rubric_exists(rubric.rubric_sha, rubric.description) if self.rubric_exists == None: self.scorepadDB.insert_rubric(rubric) rubric_id = self.scorepadDB.query_maxrubric() rubric = self.scorepadDB.query_rubric(rubric_id) OTHER_RUBRICLIST.append(rubric) OTHER_RUBRICTITLE.append(rubric.title) self.is_exists = False else: self.is_exists = True if model_name == "Category": if self.is_exists == False: rubric_id = self.scorepadDB.query_maxrubric() category = Category(None, text[2], rubric_id, text[4]) self.scorepadDB.insert_category(category) if model_name == "Level": if self.is_exists == False: rubric_id = self.scorepadDB.query_maxrubric() category_id = self.scorepadDB.query_maxcategory() level = Level(None, text[2], text[3], category_id, rubric_id, text[6]) self.scorepadDB.insert_level(level) if model_name == "Score": self._alert("Score received from", nick) project_sha = text[6] rubric_sha = text[7] category_sha = text[8] level_sha = text[9] score_id = self.scorepadDB.query_score_id(project_sha, rubric_sha, category_sha, level_sha) attr = self.scorepadDB.query_score_attr(score_id) self.scorepadDB.increment_scorecount(attr[0], attr[1], attr[2], attr[3]) def _alert(self, title, text=None): alert = NotifyAlert(timeout=5) alert.props.title = title alert.props.msg = text self.add_alert(alert) alert.connect('response', self._alert_cancel_cb) alert.show() def _alert_cancel_cb(self, alert, response_id): self.remove_alert(alert) def _shared_cb(self, sender): self._setup() self.is_shared = True self._alert('Shared', 'The activity is shared') def _setup(self): self.text_channel = TextChannelWrapper( self.shared_activity.telepathy_text_chan, self.shared_activity.telepathy_conn) self.text_channel.set_received_callback(self._received_cb) self._alert("Activity Shared", "Connected") self.shared_activity.connect('buddy-joined', self._buddy_joined_cb) self.shared_activity.connect('buddy-left', self._buddy_left_cb) def _joined_cb(self, sender): if not self.shared_activity: return for buddy in self.shared_activity.get_joined_buddies(): self._buddy_already_exists(buddy) self.is_shared = True self._setup() self._alert("Joined", "Joined Scorepad Activity") def _received_cb(self, buddy, text): if buddy: if type(buddy) is dict: nick = buddy['nick'] else: nick = buddy.props.nick else: nick = '???' self.update_status(str(nick),text) def _buddy_joined_cb(self, sender, buddy): if buddy == self.owner: return self._alert(str(buddy.props.nick), "joined the activity") def _buddy_left_cb(self, sender, buddy): if buddy == self.owner: return self._alert(str(buddy.props.nick), "left") def _buddy_already_exists(self, buddy): if buddy == self.owner: return self._alert(str(buddy.props.nick), "is here") def sendbundle_cb(self, bundle): text = bundle if text: if self.text_channel: self.text_channel.send(text) else: print "Not connected" self._alert("Bundle", "sent!") class TextChannelWrapper(object): def __init__(self, text_chan, conn): self._activity_cb = None self._text_chan = text_chan self._conn = conn self._signal_matches = [] def send(self, text): if self._text_chan is not None: self._text_chan[CHANNEL_TYPE_TEXT].Send( CHANNEL_TEXT_MESSAGE_TYPE_NORMAL, text) def set_received_callback(self, callback): if self._text_chan is None: return self._activity_cb = callback m = self._text_chan[CHANNEL_TYPE_TEXT].connect_to_signal('Received', self._received_cb) self._signal_matches.append(m) def _received_cb(self, identity, timestamp, sender, type_, flags, text): if self._activity_cb: try: self._text_chan[CHANNEL_INTERFACE_GROUP] except Exception: nick = self._conn[ CONN_INTERFACE_ALIASING].RequestAliases([sender])[0] buddy = {'nick': nick, 'color': '#000000,#808080'} else: buddy = self._get_buddy(sender) self._activity_cb(buddy, text) self._text_chan[ CHANNEL_TYPE_TEXT].AcknowledgePendingMessages([identity]) else: print "Disconnected" def _get_buddy(self, cs_handle): pservice = presenceservice.get_instance() tp_name, tp_path = pservice.get_preferred_connection() conn = Connection(tp_name, tp_path) group = self._text_chan[CHANNEL_INTERFACE_GROUP] my_csh = group.GetSelfHandle() if my_csh == cs_handle: handle = conn.GetSelfHandle() elif group.GetGroupFlags() & \ CHANNEL_GROUP_FLAG_CHANNEL_SPECIFIC_HANDLES: handle = group.GetHandleOwners([cs_handle])[0] else: handle = cs_handle assert handle != 0 return pservice.get_buddy_by_telepathy_handle( tp_name, tp_path, handle) def destroy(self, widget, data=None): gtk.main_quit() def main(self): gtk.main()