Merge lp:~aelkner/schooltool.gradebook/flourish into lp:schooltool.gradebook/flourish

Proposed by Gediminas Paulauskas
Status: Rejected
Rejected by: Alan Elkner
Proposed branch: lp:~aelkner/schooltool.gradebook/flourish
Merge into: lp:schooltool.gradebook/flourish
Diff against target: 1514 lines (+1162/-21) (has conflicts)
22 files modified
CHANGES.txt (+4/-0)
src/schooltool/gradebook/README.txt (+19/-0)
src/schooltool/gradebook/activity.py (+55/-2)
src/schooltool/gradebook/browser/course_worksheets.py (+452/-0)
src/schooltool/gradebook/browser/flourish.zcml (+180/-10)
src/schooltool/gradebook/browser/gradebook.py (+10/-2)
src/schooltool/gradebook/browser/report_card.py (+14/-0)
src/schooltool/gradebook/browser/resources/f_gradebook.css (+5/-0)
src/schooltool/gradebook/browser/templates/f_course_worksheet_edit.pt (+45/-0)
src/schooltool/gradebook/browser/templates/f_course_worksheet_templates.pt (+26/-0)
src/schooltool/gradebook/browser/templates/f_course_worksheets.pt (+111/-0)
src/schooltool/gradebook/browser/templates/f_deploy_as_course_worksheet.pt (+61/-0)
src/schooltool/gradebook/browser/templates/f_hide_unhide_course_worksheets.pt (+44/-0)
src/schooltool/gradebook/browser/templates/f_manage_course_worksheet_templates.pt (+10/-0)
src/schooltool/gradebook/browser/templates/f_manage_course_worksheets.pt (+21/-0)
src/schooltool/gradebook/browser/templates/f_manage_report_sheet_templates_overview.pt (+12/-0)
src/schooltool/gradebook/browser/templates/f_manage_report_sheets_overview.pt (+2/-2)
src/schooltool/gradebook/browser/templates/f_template_manage.pt (+1/-1)
src/schooltool/gradebook/browser/templates/f_templates_overview.pt (+4/-0)
src/schooltool/gradebook/configure.zcml (+51/-0)
src/schooltool/gradebook/interfaces.py (+28/-3)
src/schooltool/gradebook/tests/test_gradebook.py (+7/-1)
Text conflict in CHANGES.txt
To merge this branch: bzr merge lp:~aelkner/schooltool.gradebook/flourish
Reviewer Review Type Date Requested Status
Gediminas Paulauskas (community) Needs Fixing
Review via email: mp+86728@code.launchpad.net

Description of the change

Don't you think such a new big feature, that no one understands until they see it, implies a need for a merge request?

+ At a time when I have said I am making a 2.0.1 release
+ 3 test failures!
+ Behavior has changed, as evidenced by broken tests

To post a comment you must log in.
Revision history for this message
Gediminas Paulauskas (menesis) wrote :

I have removed your merge from flourish branch.

# Your local branch will conflict. Push it aside
# $ bzr branch . ../flourish-rejected
# and get the real trunk
# $ bzr pull --overwrite lp:schooltool.gradebook

review: Disapprove
Revision history for this message
Gediminas Paulauskas (menesis) wrote :

Tests have to be looked at, and something needs fixing.

I don't see any tests or documentation on this feature.
Except a few lines in src/schooltool/gradebook/README.txt

No "What's this?" description of a new feature.

review: Needs Fixing
Revision history for this message
Tom Hoffman (tom-hoffman) wrote :

This doesn't need to be merged right now -- we'll be returning to these issues after the holidays.

415. By Gediminas Paulauskas

Preparing release 2.0.1

416. By Gediminas Paulauskas

Back to development: 2.0.2

Unmerged revisions

476. By Alan Elkner

merged with trunk

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CHANGES.txt'
2--- CHANGES.txt 2011-12-22 15:15:53 +0000
3+++ CHANGES.txt 2011-12-22 16:21:13 +0000
4@@ -6,7 +6,11 @@
5 ------------------
6
7 - Allow scoresystem point value be equal to the previous grade (https://launchpad.net/bugs/899228)
8+<<<<<<< TREE
9 - Updated translations
10+=======
11+- Added course worksheets feature
12+>>>>>>> MERGE-SOURCE
13
14
15 2.0.0 (2011-11-22)
16
17=== modified file 'src/schooltool/gradebook/README.txt'
18--- src/schooltool/gradebook/README.txt 2011-08-30 17:24:02 +0000
19+++ src/schooltool/gradebook/README.txt 2011-12-22 16:21:13 +0000
20@@ -661,3 +661,22 @@
21 >>> linked_activity.scoresystem.max
22 Decimal("20")
23
24+Course Activities
25+-----------------
26+
27+Course leaders can create a set of worksheets that they can later choose to
28+deploy to all the sections of that course for specific terms or the whole
29+school year. There is an adapter that returns this set, which it locates
30+in the course's annotations.
31+
32+ >>> alg1_act = interfaces.ICourseActivities(alg1)
33+ >>> alg1_act
34+ CourseActivities(u'Course Activities')
35+
36+There is also an adapter that returns the deployed worksheets for the course,
37+also stored as annotations.
38+
39+ >>> alg1_deployed = interfaces.ICourseDeployedWorksheets(alg1)
40+ >>> alg1_deployed
41+ CourseDeployedWorksheets(u'Deployed Worksheets')
42+
43
44=== modified file 'src/schooltool/gradebook/activity.py'
45--- src/schooltool/gradebook/activity.py 2011-09-01 13:46:58 +0000
46+++ src/schooltool/gradebook/activity.py 2011-12-22 16:21:13 +0000
47@@ -37,6 +37,7 @@
48 from schooltool.app.interfaces import ISchoolToolApplication
49 from schooltool.gradebook import GradebookMessage as _
50 from schooltool.requirement import requirement, scoresystem
51+from schooltool.requirement.interfaces import IRangedValuesScoreSystem
52 from schooltool.gradebook import interfaces
53 from schooltool.term.interfaces import IDateManager
54 from schooltool.course.interfaces import ISection
55@@ -44,6 +45,8 @@
56 ACTIVITIES_KEY = 'schooltool.gradebook.activities'
57 CURRENT_WORKSHEET_KEY = 'schooltool.gradebook.currentworksheet'
58 CATEGORY_WEIGHTS_KEY = 'schooltool.gradebook.categoryweights'
59+COURSE_ACTIVITIES_KEY = 'schooltool.gradebook.course_activities'
60+COURSE_DEPLOYED_WORKSHEETS_KEY = 'schooltool.gradebook.course_deployed'
61
62
63 def ensureAtLeastOneWorksheet(activities):
64@@ -170,6 +173,14 @@
65 return []
66
67
68+class CourseActivities(requirement.Requirement):
69+ zope.interface.implements(interfaces.ICourseActivities)
70+
71+
72+class CourseDeployedWorksheets(requirement.Requirement):
73+ zope.interface.implements(interfaces.ICourseDeployedWorksheets)
74+
75+
76 class Worksheet(requirement.Requirement):
77 zope.interface.implements(interfaces.IWorksheet,
78 annotation.interfaces.IAttributeAnnotatable)
79@@ -198,6 +209,12 @@
80 ann[CATEGORY_WEIGHTS_KEY] = persistent.dict.PersistentDict()
81 ann[CATEGORY_WEIGHTS_KEY][category] = weight
82
83+ def canAverage(self):
84+ for activity in self.values():
85+ if IRangedValuesScoreSystem(activity.scoresystem, None) is None:
86+ return False
87+ return True
88+
89
90 class ReportWorksheet(requirement.Requirement):
91 zope.interface.implements(interfaces.IReportWorksheet)
92@@ -205,6 +222,12 @@
93 deployed = False
94
95
96+class CourseWorksheet(requirement.Requirement):
97+ zope.interface.implements(interfaces.ICourseWorksheet)
98+
99+ deployed = False
100+
101+
102 class Activity(requirement.Requirement):
103 zope.interface.implements(interfaces.IActivity)
104
105@@ -237,8 +260,6 @@
106 return annotations[ACTIVITIES_KEY]
107 except KeyError:
108 activities = Activities(_('Activities'))
109- # Make sure that the sections activities include all the activities of
110- # the courses as well
111 annotations[ACTIVITIES_KEY] = activities
112 zope.container.contained.contained(
113 activities, context, 'activities')
114@@ -248,6 +269,38 @@
115 getSectionActivities.factory = Activities
116
117
118+def getCourseActivities(context):
119+ '''IAttributeAnnotatable object to ICourseActivities adapter.'''
120+ annotations = annotation.interfaces.IAnnotations(context)
121+ try:
122+ return annotations[COURSE_ACTIVITIES_KEY]
123+ except KeyError:
124+ activities = CourseActivities(_('Course Activities'))
125+ annotations[COURSE_ACTIVITIES_KEY] = activities
126+ zope.container.contained.contained(
127+ activities, context, 'activities')
128+ return activities
129+
130+# Convention to make adapter introspectable
131+getCourseActivities.factory = CourseActivities
132+
133+
134+def getCourseDeployedWorksheets(context):
135+ '''IAttributeAnnotatable object to ICourseDeployedWorksheets adapter.'''
136+ annotations = annotation.interfaces.IAnnotations(context)
137+ try:
138+ return annotations[COURSE_DEPLOYED_WORKSHEETS_KEY]
139+ except KeyError:
140+ worksheets = CourseDeployedWorksheets(_('Deployed Worksheets'))
141+ annotations[COURSE_DEPLOYED_WORKSHEETS_KEY] = worksheets
142+ zope.container.contained.contained(
143+ worksheets, context, 'deployed_worksheets')
144+ return worksheets
145+
146+# Convention to make adapter introspectable
147+getCourseDeployedWorksheets.factory = CourseDeployedWorksheets
148+
149+
150 class LinkedActivity(Activity):
151 zope.interface.implements(interfaces.ILinkedActivity)
152
153
154=== added file 'src/schooltool/gradebook/browser/course_worksheets.py'
155--- src/schooltool/gradebook/browser/course_worksheets.py 1970-01-01 00:00:00 +0000
156+++ src/schooltool/gradebook/browser/course_worksheets.py 2011-12-22 16:21:13 +0000
157@@ -0,0 +1,452 @@
158+#
159+# SchoolTool - common information systems platform for school administration
160+# Copyright (c) 2005 Shuttleworth Foundation
161+#
162+# This program is free software; you can redistribute it and/or modify
163+# it under the terms of the GNU General Public License as published by
164+# the Free Software Foundation; either version 2 of the License, or
165+# (at your option) any later version.
166+#
167+# This program is distributed in the hope that it will be useful,
168+# but WITHOUT ANY WARRANTY; without even the implied warranty of
169+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
170+# GNU General Public License for more details.
171+#
172+# You should have received a copy of the GNU General Public License
173+# along with this program; if not, write to the Free Software
174+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
175+#
176+"""
177+Course Worksheet Views
178+"""
179+
180+from zope.container.interfaces import INameChooser
181+from zope.browserpage.viewpagetemplatefile import ViewPageTemplateFile
182+from zope.security.checker import canWrite
183+from zope.security.interfaces import Unauthorized
184+from zope.security.proxy import removeSecurityProxy
185+from zope.traversing.api import getName
186+from zope.traversing.browser.absoluteurl import absoluteURL
187+from zope.i18n import translate
188+
189+from z3c.form import form, field, button
190+
191+from schooltool.app.interfaces import ISchoolToolApplication
192+from schooltool.gradebook import GradebookMessage as _
193+from schooltool.common.inlinept import InheritTemplate
194+from schooltool.common.inlinept import InlineViewPageTemplate
195+from schooltool.course.interfaces import ISectionContainer, ISection
196+from schooltool.person.interfaces import IPerson
197+from schooltool.schoolyear.interfaces import ISchoolYear
198+from schooltool.schoolyear.interfaces import ISchoolYearContainer
199+from schooltool.skin import flourish
200+from schooltool.skin.flourish.page import TertiaryNavigationManager
201+from schooltool.term.interfaces import ITerm
202+
203+from schooltool.gradebook.interfaces import (IActivities, ICourseActivities,
204+ ICourseWorksheet, ICourseDeployedWorksheets, IGradebookRoot)
205+from schooltool.gradebook.activity import CourseWorksheet, Activity, Worksheet
206+from schooltool.gradebook.browser.activity import (FlourishActivityAddView,
207+ FlourishActivityEditView)
208+from schooltool.gradebook.browser.report_card import copyActivities
209+
210+
211+class FlourishCourseTemplatesView(flourish.page.Page):
212+ """A flourish view for managing course worksheet templates"""
213+
214+ @property
215+ def title(self):
216+ return self.context.__parent__.title
217+
218+ @property
219+ def worksheets(self):
220+ return tuple(removeSecurityProxy(self.context).values())
221+
222+
223+class FlourishCourseWorksheetsLinks(flourish.page.RefineLinksViewlet):
224+ """flourish course worksheet templates add links viewlet."""
225+
226+
227+class FlourishCourseWorksheetAddView(flourish.form.AddForm):
228+ """flourish view for adding a course worksheet."""
229+
230+ fields = field.Fields(ICourseWorksheet).select('title')
231+ template = InheritTemplate(flourish.page.Page.template)
232+ label = None
233+ legend = _('Course Worksheet Details')
234+
235+ @property
236+ def title(self):
237+ return self.context.__parent__.title
238+
239+ @button.buttonAndHandler(_('Submit'), name='add')
240+ def handleAdd(self, action):
241+ super(FlourishCourseWorksheetAddView, self).handleAdd.func(self, action)
242+
243+ @button.buttonAndHandler(_("Cancel"))
244+ def handle_cancel_action(self, action):
245+ url = absoluteURL(self.context, self.request)
246+ self.request.response.redirect(url)
247+
248+ def create(self, data):
249+ worksheet = CourseWorksheet(data['title'])
250+ return worksheet
251+
252+ def add(self, worksheet):
253+ chooser = INameChooser(self.context)
254+ name = chooser.chooseName(worksheet.title, worksheet)
255+ self.context[name] = worksheet
256+ self._worksheet = worksheet
257+ return worksheet
258+
259+ def nextURL(self):
260+ return absoluteURL(self.context, self.request)
261+
262+ def updateActions(self):
263+ super(FlourishCourseWorksheetAddView, self).updateActions()
264+ self.actions['add'].addClass('button-ok')
265+ self.actions['cancel'].addClass('button-cancel')
266+
267+
268+class FlourishCourseWorksheetEditView(flourish.form.Form, form.EditForm):
269+
270+ template = InheritTemplate(flourish.page.Page.template)
271+ label = None
272+ legend = _('Course Worksheet Template Information')
273+ fields = field.Fields(ICourseWorksheet).select('title')
274+
275+ @property
276+ def title(self):
277+ return self.context.title
278+
279+ def update(self):
280+ if 'form-submitted' in self.request:
281+ for activity in self.context.values():
282+ name = 'delete.%s' % activity.__name__
283+ if name in self.request:
284+ del self.context[activity.__name__]
285+ break
286+ return form.EditForm.update(self)
287+
288+ @button.buttonAndHandler(_('Submit'), name='apply')
289+ def handleApply(self, action):
290+ super(FlourishCourseWorksheetEditView, self).handleApply.func(self, action)
291+ # XXX: hacky sucessful submit check
292+ if (self.status == self.successMessage or
293+ self.status == self.noChangesMessage):
294+ self.request.response.redirect(self.nextURL())
295+
296+ @button.buttonAndHandler(_("Cancel"))
297+ def handle_cancel_action(self, action):
298+ self.request.response.redirect(self.nextURL())
299+
300+ def nextURL(self):
301+ return absoluteURL(self.context.__parent__, self.request)
302+
303+ def updateActions(self):
304+ super(FlourishCourseWorksheetEditView, self).updateActions()
305+ self.actions['apply'].addClass('button-ok')
306+ self.actions['cancel'].addClass('button-cancel')
307+
308+
309+class CourseWorksheetAddLinks(flourish.page.RefineLinksViewlet):
310+ """Course worksheet add links viewlet."""
311+
312+
313+class FlourishCourseActivityAddView(FlourishActivityAddView):
314+ legend = _('Course Activity Details')
315+
316+
317+class CourseActivityAddTertiaryNavigationManager(
318+ flourish.page.TertiaryNavigationManager):
319+
320+ template = InlineViewPageTemplate("")
321+
322+
323+class FlourishCourseActivityEditView(FlourishActivityEditView):
324+ legend = _('Course Activity Details')
325+
326+ def nextURL(self):
327+ return absoluteURL(self.context.__parent__, self.request)
328+
329+
330+class FlourishCourseWorksheetsBase(object):
331+
332+ @property
333+ def course(self):
334+ return self.context
335+
336+ @property
337+ def schoolyear(self):
338+ return ISchoolYear(self.course)
339+
340+ @property
341+ def deployed(self):
342+ return ICourseDeployedWorksheets(self.course)
343+
344+ @property
345+ def activities(self):
346+ return ICourseActivities(self.course)
347+
348+ def sheets(self):
349+ return [sheet for sheet in self.all_sheets() if not sheet['checked']]
350+
351+ def all_sheets(self):
352+ schoolyear = self.schoolyear
353+ deployments = {}
354+ for nm, sheet in self.deployed.items():
355+ sheet = removeSecurityProxy(sheet)
356+ index = int(sheet.__name__[sheet.__name__.rfind('_') + 1:])
357+ deployment = deployments.setdefault(index, {
358+ 'obj': sheet,
359+ 'index': str(index),
360+ 'checked': sheet.hidden,
361+ 'terms': [False] * len(schoolyear),
362+ })
363+ for index, term in enumerate(schoolyear.values()):
364+ prefix = 'course_%s_%s' % (self.course.__name__, term.__name__)
365+ if sheet.__name__.startswith(prefix):
366+ deployment['terms'][index] = True
367+ sheets = [v for k, v in sorted(deployments.items())]
368+ return ([sheet for sheet in sheets if not sheet['checked']] +
369+ [sheet for sheet in sheets if sheet['checked']])
370+
371+ @property
372+ def terms(self):
373+ result = [{
374+ 'name': '',
375+ 'title': _('-- Entire year --'),
376+ 'selected': 'selected',
377+ }]
378+ for term in self.schoolyear.values():
379+ result.append({
380+ 'name': term.__name__,
381+ 'title': term.title,
382+ 'selected': '',
383+ })
384+ return result
385+
386+ def getNewIndex(self, sheet, template_title):
387+ if sheet.title.startswith(template_title):
388+ rest = sheet.title[len(template_title):]
389+ if not rest:
390+ return 1
391+ elif len(rest) > 1 and rest[0] == '-' and rest[1:].isdigit():
392+ return int(rest[1:])
393+ return 0
394+
395+ def deploy(self, term, template):
396+ # get the next index and title
397+ highest, title_index = 0, 0
398+ template_title = self.alternate_title
399+ for sheet in self.deployed.values():
400+ index = int(sheet.__name__[sheet.__name__.rfind('_') + 1:])
401+ if index > highest:
402+ highest = index
403+ new_index = self.getNewIndex(sheet, template_title)
404+ if new_index > title_index:
405+ title_index = new_index
406+ root = IGradebookRoot(ISchoolToolApplication(None))
407+ prefix = self.schoolyear.__name__ + '_'
408+ for sheet in root.deployed.values():
409+ if sheet.__name__.startswith(prefix):
410+ new_index = self.getNewIndex(sheet, template_title)
411+ if new_index > title_index:
412+ title_index = new_index
413+ title = template_title
414+ if title_index:
415+ title += '-%s' % (title_index + 1)
416+
417+ # copy worksheet template to the term or whole year
418+ if term:
419+ terms = [term]
420+ else:
421+ terms = self.schoolyear.values()
422+ for term in terms:
423+ deployedKey = 'course_%s_%s_%s' % (self.course.__name__,
424+ term.__name__, highest + 1)
425+ deployedWorksheet = Worksheet(title)
426+ self.deployed[deployedKey] = deployedWorksheet
427+ copyActivities(removeSecurityProxy(template), deployedWorksheet)
428+
429+ # now copy the template to all sections in the term
430+ sections = ISectionContainer(term)
431+ for section in sections.values():
432+ if self.course not in section.courses:
433+ continue
434+ worksheetCopy = Worksheet(deployedWorksheet.title)
435+ worksheetCopy.deployed = True
436+ IActivities(section)[deployedWorksheet.__name__] = worksheetCopy
437+ copyActivities(deployedWorksheet, worksheetCopy)
438+
439+
440+class FlourishManageCourseWorksheetTemplatesOverview(flourish.page.Content):
441+ """A flourish viewlet for showing worksheet templates in course view"""
442+
443+ body_template = ViewPageTemplateFile(
444+ 'templates/f_manage_course_worksheet_templates.pt')
445+
446+
447+class FlourishManageCourseSheetsOverview(FlourishCourseWorksheetsBase,
448+ flourish.page.Content):
449+ """A flourish viewlet for showing deployed worksheets in course view"""
450+
451+ body_template = ViewPageTemplateFile(
452+ 'templates/f_manage_course_worksheets.pt')
453+
454+
455+class FlourishCourseWorksheetsView(FlourishCourseWorksheetsBase,
456+ flourish.page.Page):
457+ """A flourish view for managing corse worksheet deployment"""
458+
459+ def __init__(self, context, request):
460+ super(FlourishCourseWorksheetsView, self).__init__(context, request)
461+ self.alternate_title = self.request.get('alternate_title')
462+
463+ @property
464+ def subtitle(self):
465+ subtitle = _(u'Worksheets for ${year}',
466+ mapping={'year': self.schoolyear.title})
467+ return translate(subtitle, context=self.request)
468+
469+ @property
470+ def has_error(self):
471+ return self.no_template or self.no_title
472+
473+ @property
474+ def no_template(self):
475+ return 'SUBMIT' in self.request and not self.request.get('template')
476+
477+ @property
478+ def no_title(self):
479+ return ('SUBMIT' in self.request and
480+ not self.request.get('alternate_title'))
481+
482+ @property
483+ def templates(self):
484+ result = [{
485+ 'name': '',
486+ 'title': _('-- Select a template --'),
487+ 'selected': 'selected',
488+ }]
489+ for template in self.activities.values():
490+ result.append({
491+ 'name': template.__name__,
492+ 'title': template.title,
493+ 'selected': '',
494+ })
495+ return result
496+
497+ def update(self):
498+ if 'CANCEL' in self.request:
499+ self.request.response.redirect(self.nextURL())
500+ if 'SUBMIT' in self.request:
501+ if self.request.get('template') and self.alternate_title:
502+ template = self.activities[self.request['template']]
503+ term = self.request.get('term')
504+ if term:
505+ term = self.schoolyear[term]
506+ self.deploy(term, template)
507+ self.alternate_title = ''
508+
509+ def nextURL(self):
510+ return absoluteURL(self.context, self.request)
511+
512+
513+class CourseWorksheetsActionLinks(flourish.page.RefineLinksViewlet):
514+ """Course worksheets view action links viewlet."""
515+
516+
517+class FlourishHideUnhideCourseWorkheetsView(FlourishCourseWorksheetsBase,
518+ flourish.page.Page):
519+ """A flourish view for hiding/unhiding course worksheet deployments"""
520+
521+ @property
522+ def subtitle(self):
523+ title = _(u'Hide/unhide Deployed Worksheets for ${year}',
524+ mapping={'year': self.schoolyear.title})
525+ return translate(title, context=self.request)
526+
527+ def update(self):
528+ if 'CANCEL' in self.request:
529+ self.request.response.redirect(self.nextURL())
530+ elif 'SUBMIT' in self.request:
531+ hidden = self.request.get('hidden', [])
532+ schoolyear = self.schoolyear
533+ for nm, sheet in self.deployed.items():
534+ sheet = removeSecurityProxy(sheet)
535+ index = sheet.__name__[sheet.__name__.rfind('_') + 1:]
536+ self.handleSheet(sheet, index, hidden)
537+ self.request.response.redirect(self.nextURL())
538+
539+ def handleSheet(self, sheet, index, hidden):
540+ if index in hidden and not sheet.hidden:
541+ sheet.hidden = True
542+ elif index not in hidden and sheet.hidden:
543+ sheet.hidden = False
544+ else:
545+ return
546+ schoolyear = self.schoolyear
547+ for term in schoolyear.values():
548+ deployedKey = 'course_%s_%s_%s' % (self.context.__name__,
549+ term.__name__, index)
550+ if sheet.__name__ == deployedKey:
551+ for section in ISectionContainer(term).values():
552+ if self.context not in section.courses:
553+ continue
554+ activities = IActivities(section)
555+ activities[deployedKey].hidden = sheet.hidden
556+ return
557+
558+ def nextURL(self):
559+ url = absoluteURL(self.context, self.request)
560+ return url + '/deployed_worksheets.html'
561+
562+
563+class FlourishDeployAsCourseWorksheetView(FlourishCourseWorksheetsBase,
564+ flourish.page.Page):
565+ """A flourish view for deploying current gradebook worksheet as a
566+ course worksheet. If form data is valid, it creates a course
567+ worksheet template as a copy of the context and then deploys that
568+ to the course for the given term.."""
569+
570+ @property
571+ def course(self):
572+ courses = list(ISection(self.context).courses)
573+ if not courses:
574+ return None
575+ return courses[0]
576+
577+ @property
578+ def has_error(self):
579+ return self.no_title
580+
581+ @property
582+ def no_title(self):
583+ return 'SUBMIT' in self.request and not self.alternate_title
584+
585+ @property
586+ def alternate_title(self):
587+ if 'alternate_title' in self.request:
588+ return self.request['alternate_title']
589+ return self.context.title
590+
591+ def update(self):
592+ if 'CANCEL' in self.request:
593+ self.request.response.redirect(self.nextURL())
594+ if 'SUBMIT' in self.request:
595+ if not self.has_error:
596+ template = Worksheet(self.alternate_title)
597+ chooser = INameChooser(self.activities)
598+ name = chooser.chooseName(template.title, template)
599+ self.activities[name] = template
600+ copyActivities(removeSecurityProxy(self.context), template)
601+ term = self.request.get('term')
602+ if term:
603+ term = self.schoolyear[term]
604+ self.deploy(term, template)
605+ self.request.response.redirect(self.nextURL())
606+
607+ def nextURL(self):
608+ return absoluteURL(self.context, self.request) + '/gradebook'
609+
610
611=== modified file 'src/schooltool/gradebook/browser/flourish.zcml'
612--- src/schooltool/gradebook/browser/flourish.zcml 2011-11-07 06:19:05 +0000
613+++ src/schooltool/gradebook/browser/flourish.zcml 2011-12-22 16:21:13 +0000
614@@ -140,6 +140,17 @@
615 />
616
617 <flourish:viewlet
618+ name="gradebook_actions"
619+ after="gradebook_settings"
620+ manager="schooltool.skin.flourish.page.IPageRefineManager"
621+ class=".gradebook.FlourishGradebookActionsLinks"
622+ for="..interfaces.IGradebook"
623+ title="Actions"
624+ permission="schooltool.edit"
625+ view=".gradebook.FlourishGradebookOverview"
626+ />
627+
628+ <flourish:viewlet
629 name="select_year"
630 class=".gradebook.FlourishGradebookYearNavigationViewlet"
631 manager=".gradebook.FlourishGradebookYearNavigation"
632@@ -372,8 +383,17 @@
633
634 <!-- Report Sheets -->
635 <flourish:viewlet
636+ name="manage-report-sheet-templates-overview"
637+ after="manage-resources-overview"
638+ view="schooltool.app.browser.app.ManageSchool"
639+ permission="schooltool.edit"
640+ manager="schooltool.skin.flourish.page.IPageContentManager"
641+ class=".report_card.FlourishManageReportSheetTemplatesOverview"
642+ />
643+
644+ <flourish:viewlet
645 name="manage-report-sheets-overview"
646- after="manage-resources-overview"
647+ after="manage-report-sheet-templates-overview"
648 view="schooltool.app.browser.app.ManageSchool"
649 permission="schooltool.edit"
650 manager="schooltool.skin.flourish.page.IPageContentManager"
651@@ -518,15 +538,6 @@
652 />
653 </configure>
654
655- <flourish:viewlet
656- name="gradebook/templates"
657- before="report_card_layout"
658- title="Report Sheet Templates"
659- class="schooltool.skin.flourish.page.LinkViewlet"
660- manager="schooltool.app.browser.app.CustomizeSchoolLinks"
661- permission="schooltool.edit"
662- />
663-
664 <flourish:page
665 name="report_sheets"
666 for="schooltool.app.interfaces.ISchoolToolApplication"
667@@ -958,4 +969,163 @@
668 />
669 </configure>
670
671+ <!-- Course Worksheets -->
672+ <flourish:viewlet
673+ name="manage-course-worksheet-templates"
674+ before="manage-course-worksheets"
675+ view="schooltool.course.browser.course.FlourishCourseView"
676+ permission="schooltool.edit"
677+ manager="schooltool.skin.flourish.page.IPageContentManager"
678+ class=".course_worksheets.FlourishManageCourseWorksheetTemplatesOverview"
679+ />
680+
681+ <flourish:viewlet
682+ name="manage-course-worksheets"
683+ view="schooltool.course.browser.course.FlourishCourseView"
684+ permission="schooltool.edit"
685+ manager="schooltool.skin.flourish.page.IPageContentManager"
686+ class=".course_worksheets.FlourishManageCourseSheetsOverview"
687+ />
688+
689+ <flourish:page
690+ name="index.html"
691+ for="schooltool.gradebook.interfaces.ICourseActivities"
692+ class=".course_worksheets.FlourishCourseTemplatesView"
693+ content_template="templates/f_course_worksheet_templates.pt"
694+ permission="schooltool.edit"
695+ subtitle="Worksheet Templates"
696+ />
697+
698+ <flourish:viewlet
699+ name="course-worksheets"
700+ manager="schooltool.skin.flourish.page.IPageRefineManager"
701+ class=".course_worksheets.FlourishCourseWorksheetsLinks"
702+ for="schooltool.gradebook.interfaces.ICourseActivities"
703+ title="Add"
704+ permission="schooltool.edit"
705+ view=".course_worksheets.FlourishCourseTemplatesView"
706+ />
707+
708+ <flourish:viewlet
709+ name="addCourseWorksheet.html"
710+ title="Course Worksheet"
711+ class="schooltool.skin.flourish.page.LinkViewlet"
712+ manager=".course_worksheets.FlourishCourseWorksheetsLinks"
713+ permission="schooltool.edit"
714+ />
715+
716+ <configure package="schooltool.skin.flourish">
717+ <flourish:page
718+ name="addCourseWorksheet.html"
719+ for="schooltool.gradebook.interfaces.ICourseActivities"
720+ subtitle="New Course Worksheet"
721+ class="schooltool.gradebook.browser.course_worksheets.FlourishCourseWorksheetAddView"
722+ content_template="templates/z3c-schooltool-form.pt"
723+ permission="schooltool.edit"
724+ />
725+
726+ <flourish:page
727+ name="addCourseActivity.html"
728+ for="schooltool.gradebook.interfaces.ICourseWorksheet"
729+ subtitle="New Course Activity"
730+ class="schooltool.gradebook.browser.course_worksheets.FlourishCourseActivityAddView"
731+ content_template="templates/z3c-schooltool-form.pt"
732+ permission="schooltool.edit"
733+ />
734+ </configure>
735+
736+ <flourish:page
737+ name="index.html"
738+ for="schooltool.gradebook.interfaces.ICourseWorksheet"
739+ subtitle="Edit"
740+ class=".course_worksheets.FlourishCourseWorksheetEditView"
741+ content_template="templates/f_course_worksheet_edit.pt"
742+ permission="schooltool.edit"
743+ />
744+
745+ <flourish:viewlet
746+ name="course-worksheet-add-links"
747+ manager="schooltool.skin.flourish.page.IPageRefineManager"
748+ class=".course_worksheets.CourseWorksheetAddLinks"
749+ view=".course_worksheets.FlourishCourseWorksheetEditView"
750+ title="Add"
751+ permission="schooltool.edit"
752+ />
753+
754+ <flourish:viewlet
755+ name="addCourseActivity.html"
756+ title="Course Activity"
757+ class="schooltool.skin.flourish.page.LinkViewlet"
758+ manager=".course_worksheets.CourseWorksheetAddLinks"
759+ permission="schooltool.edit"
760+ />
761+
762+ <flourish:viewletManager
763+ name="tertiary_navigation"
764+ provides="schooltool.skin.flourish.page.ITertiaryNavigationManager"
765+ class=".course_worksheets.CourseActivityAddTertiaryNavigationManager"
766+ view=".course_worksheets.FlourishCourseActivityAddView"
767+ permission="zope.Public"
768+ />
769+
770+ <flourish:page
771+ name="editCourseActivity.html"
772+ for="..interfaces.IActivity"
773+ subtitle="Edit"
774+ content_template="templates/f_add_edit_activity.pt"
775+ class=".course_worksheets.FlourishCourseActivityEditView"
776+ permission="schooltool.edit"
777+ />
778+
779+ <flourish:page
780+ name="deployed_worksheets.html"
781+ for="schooltool.course.interfaces.ICourse"
782+ class=".course_worksheets.FlourishCourseWorksheetsView"
783+ content_template="templates/f_course_worksheets.pt"
784+ permission="schooltool.edit"
785+ />
786+
787+ <flourish:viewlet
788+ name="course-worksheets-action-links"
789+ manager="schooltool.skin.flourish.page.IPageRefineManager"
790+ class=".course_worksheets.CourseWorksheetsActionLinks"
791+ view=".course_worksheets.FlourishCourseWorksheetsView"
792+ title="Action"
793+ permission="schooltool.edit"
794+ />
795+
796+ <flourish:viewlet
797+ name="hide_unhide_worksheets.html"
798+ title="Hide/unhide Worksheets"
799+ class="schooltool.skin.flourish.page.LinkViewlet"
800+ manager=".course_worksheets.CourseWorksheetsActionLinks"
801+ permission="schooltool.edit"
802+ />
803+
804+ <flourish:page
805+ name="hide_unhide_worksheets.html"
806+ for="schooltool.course.interfaces.ICourse"
807+ class=".course_worksheets.FlourishHideUnhideCourseWorkheetsView"
808+ content_template="templates/f_hide_unhide_course_worksheets.pt"
809+ permission="schooltool.edit"
810+ />
811+
812+ <flourish:viewlet
813+ name="../deploy_as_course_worksheet.html"
814+ title="Deploy as Course Worksheet"
815+ class="schooltool.skin.flourish.page.LinkViewlet"
816+ manager=".gradebook.FlourishGradebookActionsLinks"
817+ permission="schooltool.edit"
818+ />
819+
820+ <flourish:page
821+ name="deploy_as_course_worksheet.html"
822+ for="..interfaces.IWorksheet"
823+ subtitle="Deploy as Course Worksheet"
824+ class=".course_worksheets.FlourishDeployAsCourseWorksheetView"
825+ content_template="templates/f_deploy_as_course_worksheet.pt"
826+ permission="schooltool.edit"
827+ />
828+
829 </configure>
830+
831
832=== modified file 'src/schooltool/gradebook/browser/gradebook.py'
833--- src/schooltool/gradebook/browser/gradebook.py 2011-12-20 19:41:39 +0000
834+++ src/schooltool/gradebook/browser/gradebook.py 2011-12-22 16:21:13 +0000
835@@ -415,7 +415,7 @@
836 self.due_date_hide = prefs.get('hide', False)
837
838 self.apply_all_colspan = 1
839- if gradebook.context.deployed:
840+ if not gradebook.context.canAverage():
841 self.total_hide = True
842 self.average_hide = True
843 if not self.absences_hide:
844@@ -1057,6 +1057,10 @@
845 """flourish Gradebook Settings links viewlet."""
846
847
848+class FlourishGradebookActionsLinks(flourish.page.RefineLinksViewlet):
849+ """flourish Gradebook Actions links viewlet."""
850+
851+
852 class GradebookTertiaryNavigationManager(flourish.page.TertiaryNavigationManager):
853
854 template = InlineViewPageTemplate("""
855@@ -1075,8 +1079,11 @@
856 current = gradebook.context.__name__
857 for worksheet in gradebook.worksheets:
858 url = '%s/gradebook' % absoluteURL(worksheet, self.request)
859+ classes = worksheet.__name__ == current and ['active'] or []
860+ if worksheet.deployed:
861+ classes.append('deployed')
862 result.append({
863- 'class': worksheet.__name__ == current and 'active' or None,
864+ 'class': classes and ' '.join(classes) or None,
865 'viewlet': u'<a href="%s">%s</a>' % (url, worksheet.title[:15]),
866 })
867 return result
868@@ -1902,3 +1909,4 @@
869 return None
870 can_view = flourish.canView(self.gradebook)
871 return can_view
872+
873
874=== modified file 'src/schooltool/gradebook/browser/report_card.py'
875--- src/schooltool/gradebook/browser/report_card.py 2011-11-12 04:02:28 +0000
876+++ src/schooltool/gradebook/browser/report_card.py 2011-12-22 16:21:13 +0000
877@@ -221,6 +221,14 @@
878 return []
879
880
881+class FlourishManageReportSheetTemplatesOverview(FlourishReportSheetsBase,
882+ flourish.page.Content):
883+ """A flourish viewlet for showing report sheet templates in school view"""
884+
885+ body_template = ViewPageTemplateFile(
886+ 'templates/f_manage_report_sheet_templates_overview.pt')
887+
888+
889 class FlourishManageReportSheetsOverview(FlourishReportSheetsBase,
890 flourish.page.Content):
891 """A flourish viewlet for showing deployed report sheets in school view"""
892@@ -500,6 +508,12 @@
893 def title(self):
894 return self.context.title
895
896+ def display_scoresystem(self, activity):
897+ ss = activity.scoresystem
898+ if IRangedValuesScoreSystem.providedBy(ss):
899+ return '%s - %s' % (ss.min, ss.max)
900+ return ss.title
901+
902 def update(self):
903 if 'form-submitted' in self.request:
904 for activity in self.context.values():
905
906=== modified file 'src/schooltool/gradebook/browser/resources/f_gradebook.css'
907--- src/schooltool/gradebook/browser/resources/f_gradebook.css 2011-08-31 20:16:11 +0000
908+++ src/schooltool/gradebook/browser/resources/f_gradebook.css 2011-12-22 16:21:13 +0000
909@@ -33,3 +33,8 @@
910 height: 18px;
911 width: 104px;
912 }
913+
914+li.deployed a {
915+ font-style: italic;
916+}
917+
918
919=== added file 'src/schooltool/gradebook/browser/templates/f_course_worksheet_edit.pt'
920--- src/schooltool/gradebook/browser/templates/f_course_worksheet_edit.pt 1970-01-01 00:00:00 +0000
921+++ src/schooltool/gradebook/browser/templates/f_course_worksheet_edit.pt 2011-12-22 16:21:13 +0000
922@@ -0,0 +1,45 @@
923+<div i18n:domain="schooltool.gradebook">
924+ <div metal:use-macro="macro:form">
925+ <metal:block fill-slot="bottom">
926+ <input type="hidden" name="form-submitted" value="" />
927+ <h2 i18n:translate="">Course Activities</h2>
928+ <table>
929+ <thead>
930+ <tr>
931+ <th i18n:translate="">Title</th>
932+ <th i18n:translate="">Score System</th>
933+ <th i18n:translate="">Delete?</th>
934+ </tr>
935+ </thead>
936+ <tal:block repeat="activity context/values">
937+ <tr>
938+ <td>
939+ <span tal:content="activity/title" />
940+ <a class="modify" href="" title="Edit"
941+ tal:attributes="href string:${activity/@@absolute_url}/editCourseActivity.html"
942+ i18n:attributes="title">
943+ <img tal:attributes="src context/++resource++schooltool.skin.flourish/edit-icon.png"
944+ alt="Edit"
945+ i18n:attributes="alt" />
946+ </a>
947+ </td>
948+ <td tal:content="string: ${activity/scoresystem/min} - ${activity/scoresystem/max}"/>
949+ <td>
950+ <button class="image" type="submit" title="Delete" value="1"
951+ tal:attributes="name string:delete.${activity/__name__};"
952+ i18n:attributes="title">
953+ <img alt="Delete" i18n:attributes="alt"
954+ tal:attributes="src context/++resource++schooltool.skin.flourish/remove-icon.png" />
955+ </button>
956+ </td>
957+ </tr>
958+ </tal:block>
959+ </table>
960+ <h3>
961+ <a tal:attributes="href view/nextURL"
962+ i18n:translate="">Done</a>
963+ </h3>
964+ </metal:block>
965+ </div>
966+</div>
967+
968
969=== added file 'src/schooltool/gradebook/browser/templates/f_course_worksheet_templates.pt'
970--- src/schooltool/gradebook/browser/templates/f_course_worksheet_templates.pt 1970-01-01 00:00:00 +0000
971+++ src/schooltool/gradebook/browser/templates/f_course_worksheet_templates.pt 2011-12-22 16:21:13 +0000
972@@ -0,0 +1,26 @@
973+<div tal:define="worksheets view/worksheets" i18n:domain="schooltool.gradebook">
974+ <form method="post"
975+ tal:attributes="action string:${context/@@absolute_url}/worksheet_templates.html">
976+ <input type="hidden" name="form-submitted" value="" />
977+ <table>
978+ <thead>
979+ <tr>
980+ <th i18n:translate="">Title</th>
981+ </tr>
982+ </thead>
983+ <tr tal:repeat="worksheet worksheets">
984+ <td>
985+ <tal:block replace="structure worksheet/@@link" />
986+ </td>
987+ </tr>
988+ <tr tal:condition="python: len(worksheets) == 0">
989+ <td i18n:translate="">This year has no course worksheets set up.</td>
990+ </tr>
991+ </table>
992+ </form>
993+ <h3>
994+ <a tal:attributes="href string:${context/__parent__/@@absolute_url}"
995+ i18n:translate="">Done</a>
996+ </h3>
997+</div>
998+
999
1000=== added file 'src/schooltool/gradebook/browser/templates/f_course_worksheets.pt'
1001--- src/schooltool/gradebook/browser/templates/f_course_worksheets.pt 1970-01-01 00:00:00 +0000
1002+++ src/schooltool/gradebook/browser/templates/f_course_worksheets.pt 2011-12-22 16:21:13 +0000
1003@@ -0,0 +1,111 @@
1004+<div i18n:domain="schooltool.gradebook"
1005+ tal:define="sheets view/sheets; terms view/terms; schoolyear view/schoolyear">
1006+ <script type="text/javascript">
1007+ $(document).ready(function() {
1008+ $('#template').change(function(e) {
1009+ index = e.target.selectedIndex
1010+ $('#alternate_title').val(e.target.options[index].text);
1011+ });
1012+ });
1013+ </script>
1014+ <h3 i18n:translate="">Currently Deployed Worksheets</h3>
1015+ <table>
1016+ <thead>
1017+ <tr>
1018+ <th i18n:translate="">Workheet</th>
1019+ <tal:block repeat="term schoolyear/values">
1020+ <th tal:content="term/title" />
1021+ </tal:block>
1022+ </tr>
1023+ </thead>
1024+ <tr tal:repeat="sheet sheets">
1025+ <td tal:content="sheet/obj/title" />
1026+ <tal:block repeat="term sheet/terms">
1027+ <td>
1028+ <span tal:condition="term" class="ui-icon ui-icon-check ui-icon-center"></span>
1029+ </td>
1030+ </tal:block>
1031+ </tr>
1032+ <tr tal:condition="not: sheets">
1033+ <td tal:attributes="colspan python:len(schoolyear)+1" i18n:translate="">
1034+ This year has no worksheets deployed.
1035+ </td>
1036+ </tr>
1037+ </table>
1038+ <form method="post" class="standalone"
1039+ tal:attributes="action request/getURL">
1040+ <div class="viewspace">
1041+ <div class="status" tal:condition="view/has_error">
1042+ <div class="summary ui-state-error ui-corner-all">
1043+ <span class="ui-icon ui-icon-alert">icon</span>
1044+ <span i18n:domain="schooltool" i18n:translate="">Please correct the marked fields below.</span>
1045+ </div>
1046+ </div>
1047+ <fieldset>
1048+ <legend>
1049+ <span i18n:translate="">Select worksheet to deploy</span>
1050+ </legend>
1051+ <div class="row">
1052+ <div class="label">
1053+ <label for="term">
1054+ <span i18n:translate="">Term or Year</span>
1055+ </label>
1056+ </div>
1057+ <p class="hint" i18n:translate="">
1058+ Select a term or deploy to the entire year.
1059+ </p>
1060+ <div class="widget">
1061+ <select id="term" name="term">
1062+ <tal:block repeat="term terms">
1063+ <option tal:attributes="value term/name; selected term/selected"
1064+ tal:content="term/title" />
1065+ </tal:block>
1066+ </select>
1067+ </div>
1068+ </div>
1069+ <div class="row">
1070+ <div class="label">
1071+ <label for="template">
1072+ <span i18n:translate="">Worksheet Template</span>
1073+ </label>
1074+ </div>
1075+ <div class="error" tal:condition="view/no_template">
1076+ <div class="error" i18n:translate="">Required input is missing.</div>
1077+ </div>
1078+ <div class="widget">
1079+ <select id="template" name="template">
1080+ <tal:block repeat="template view/templates">
1081+ <option tal:attributes="value template/name; selected template/selected"
1082+ tal:content="template/title" />
1083+ </tal:block>
1084+ </select>
1085+ </div>
1086+ </div>
1087+ <div class="row">
1088+ <div class="label">
1089+ <label for="term">
1090+ <span i18n:translate="">Title</span>
1091+ </label>
1092+ </div>
1093+ <p class="hint" i18n:translate="">
1094+ If you deploy the same template multiple times, give each deployment
1095+ an easily distinguishable name.
1096+ </p>
1097+ <div class="error" tal:condition="view/no_title">
1098+ <div class="error" i18n:translate="">Required input is missing.</div>
1099+ </div>
1100+ <div class="widget">
1101+ <input type="text" name="alternate_title" id="alternate_title"
1102+ tal:attributes="value view/alternate_title" />
1103+ </div>
1104+ </div>
1105+ </fieldset>
1106+ </div>
1107+ <div class="buttons controls">
1108+ <input type="submit" class="button-ok" name="SUBMIT" value="Submit"
1109+ i18n:attributes="value" />
1110+ <tal:block metal:use-macro="view/@@standard_macros/cancel-button" />
1111+ </div>
1112+ </form>
1113+</div>
1114+
1115
1116=== added file 'src/schooltool/gradebook/browser/templates/f_deploy_as_course_worksheet.pt'
1117--- src/schooltool/gradebook/browser/templates/f_deploy_as_course_worksheet.pt 1970-01-01 00:00:00 +0000
1118+++ src/schooltool/gradebook/browser/templates/f_deploy_as_course_worksheet.pt 2011-12-22 16:21:13 +0000
1119@@ -0,0 +1,61 @@
1120+<div i18n:domain="schooltool.gradebook"
1121+ tal:define="terms view/terms">
1122+ <form method="post" class="standalone"
1123+ tal:attributes="action request/getURL">
1124+ <div class="viewspace">
1125+ <div class="status" tal:condition="view/has_error">
1126+ <div class="summary ui-state-error ui-corner-all">
1127+ <span class="ui-icon ui-icon-alert">icon</span>
1128+ <span i18n:domain="schooltool" i18n:translate="">Please correct the marked fields below.</span>
1129+ </div>
1130+ </div>
1131+ <fieldset>
1132+ <legend>
1133+ <span i18n:translate="">Select term or year to deploy</span>
1134+ </legend>
1135+ <div class="row">
1136+ <div class="label">
1137+ <label for="term">
1138+ <span i18n:translate="">Term or Year</span>
1139+ </label>
1140+ </div>
1141+ <p class="hint" i18n:translate="">
1142+ Select a term or deploy to the entire year.
1143+ </p>
1144+ <div class="widget">
1145+ <select id="term" name="term">
1146+ <tal:block repeat="term terms">
1147+ <option tal:attributes="value term/name; selected term/selected"
1148+ tal:content="term/title" />
1149+ </tal:block>
1150+ </select>
1151+ </div>
1152+ </div>
1153+ <div class="row">
1154+ <div class="label">
1155+ <label for="term">
1156+ <span i18n:translate="">Title</span>
1157+ </label>
1158+ </div>
1159+ <p class="hint" i18n:translate="">
1160+ If you deploy the same template multiple times, give each deployment
1161+ an easily distinguishable name.
1162+ </p>
1163+ <div class="error" tal:condition="view/no_title">
1164+ <div class="error" i18n:translate="">Required input is missing.</div>
1165+ </div>
1166+ <div class="widget">
1167+ <input type="text" name="alternate_title" id="alternate_title"
1168+ tal:attributes="value view/alternate_title" />
1169+ </div>
1170+ </div>
1171+ </fieldset>
1172+ </div>
1173+ <div class="buttons controls">
1174+ <input type="submit" class="button-ok" name="SUBMIT" value="Submit"
1175+ i18n:attributes="value" />
1176+ <tal:block metal:use-macro="view/@@standard_macros/cancel-button" />
1177+ </div>
1178+ </form>
1179+</div>
1180+
1181
1182=== added file 'src/schooltool/gradebook/browser/templates/f_hide_unhide_course_worksheets.pt'
1183--- src/schooltool/gradebook/browser/templates/f_hide_unhide_course_worksheets.pt 1970-01-01 00:00:00 +0000
1184+++ src/schooltool/gradebook/browser/templates/f_hide_unhide_course_worksheets.pt 2011-12-22 16:21:13 +0000
1185@@ -0,0 +1,44 @@
1186+<div i18n:domain="schooltool.gradebook"
1187+ tal:define="sheets view/all_sheets; schoolyear view/schoolyear">
1188+ <h3 i18n:translate="">Currently Deployed WorkSheets</h3>
1189+ <form method="post" class="standalone"
1190+ tal:attributes="action request/getURL">
1191+ <table>
1192+ <thead>
1193+ <tr>
1194+ <th i18n:translate="">Deployed Worksheet</th>
1195+ <th i18n:translate="">Index</th>
1196+ <tal:block repeat="term schoolyear/values">
1197+ <th tal:content="term/title" />
1198+ </tal:block>
1199+ <th i18n:translate="">Hidden?</th>
1200+ </tr>
1201+ </thead>
1202+ <tr tal:repeat="sheet sheets">
1203+ <td tal:content="sheet/obj/title" />
1204+ <td tal:content="sheet/index" />
1205+ <tal:block repeat="term sheet/terms">
1206+ <td>
1207+ <span tal:condition="term" class="ui-icon ui-icon-check ui-icon-center"></span>
1208+ </td>
1209+ </tal:block>
1210+ <td>
1211+ <input type="checkbox" name="hidden:list"
1212+ tal:attributes="value sheet/index;
1213+ checked sheet/checked" />
1214+ </td>
1215+ </tr>
1216+ <tr tal:condition="not: sheets">
1217+ <td tal:attributes="colspan python:len(schoolyear)+3" i18n:translate="">
1218+ This year has no worksheets deployed.
1219+ </td>
1220+ </tr>
1221+ </table>
1222+ <div class="buttons controls">
1223+ <input type="submit" class="button-ok" name="SUBMIT" value="Submit"
1224+ i18n:attributes="value" />
1225+ <tal:block metal:use-macro="view/@@standard_macros/cancel-button" />
1226+ </div>
1227+ </form>
1228+</div>
1229+
1230
1231=== added file 'src/schooltool/gradebook/browser/templates/f_manage_course_worksheet_templates.pt'
1232--- src/schooltool/gradebook/browser/templates/f_manage_course_worksheet_templates.pt 1970-01-01 00:00:00 +0000
1233+++ src/schooltool/gradebook/browser/templates/f_manage_course_worksheet_templates.pt 2011-12-22 16:21:13 +0000
1234@@ -0,0 +1,10 @@
1235+<div class="manage-view" i18n:domain="schooltool">
1236+ <h3>
1237+ <a title="Manage Worksheet Templates"
1238+ tal:attributes="href string:${context/@@absolute_url}/activities"
1239+ i18n:attributes="title"
1240+ i18n:translate="">
1241+ Worksheet Templates
1242+ </a>
1243+ </h3>
1244+</div>
1245
1246=== added file 'src/schooltool/gradebook/browser/templates/f_manage_course_worksheets.pt'
1247--- src/schooltool/gradebook/browser/templates/f_manage_course_worksheets.pt 1970-01-01 00:00:00 +0000
1248+++ src/schooltool/gradebook/browser/templates/f_manage_course_worksheets.pt 2011-12-22 16:21:13 +0000
1249@@ -0,0 +1,21 @@
1250+<div class="manage-view" i18n:domain="schooltool"
1251+ tal:define="sheets view/sheets">
1252+ <h3>
1253+ <a title="Manage Deployed Worksheets"
1254+ tal:attributes="href string:${context/@@absolute_url}/deployed_worksheets.html"
1255+ i18n:attributes="title"
1256+ i18n:translate="">
1257+ Deployed Worksheets
1258+ </a>
1259+ </h3>
1260+ <p i18n:translate="" tal:condition="sheets">
1261+ There are
1262+ <metal:block tal:replace="python:len(sheets)" i18n:name="count"/>
1263+ worksheets deployed in
1264+ <metal:block tal:replace="view/schoolyear/title" i18n:name="schoolyear"/>
1265+ </p>
1266+ <p i18n:translate="" tal:condition="not: sheets">
1267+ There are no worksheets deployed in
1268+ <metal:block tal:replace="view/schoolyear/title" i18n:name="schoolyear"/>
1269+ </p>
1270+</div>
1271
1272=== added file 'src/schooltool/gradebook/browser/templates/f_manage_report_sheet_templates_overview.pt'
1273--- src/schooltool/gradebook/browser/templates/f_manage_report_sheet_templates_overview.pt 1970-01-01 00:00:00 +0000
1274+++ src/schooltool/gradebook/browser/templates/f_manage_report_sheet_templates_overview.pt 2011-12-22 16:21:13 +0000
1275@@ -0,0 +1,12 @@
1276+<div class="manage-view" i18n:domain="schooltool"
1277+ tal:condition="view/has_schoolyear"
1278+ tal:define="sheets view/sheets">
1279+ <h3>
1280+ <a title="Manage Report Sheet Templates"
1281+ tal:attributes="href string:${context/@@absolute_url}/gradebook/templates"
1282+ i18n:attributes="title"
1283+ i18n:translate="">
1284+ Report Sheet Templates
1285+ </a>
1286+ </h3>
1287+</div>
1288
1289=== modified file 'src/schooltool/gradebook/browser/templates/f_manage_report_sheets_overview.pt'
1290--- src/schooltool/gradebook/browser/templates/f_manage_report_sheets_overview.pt 2011-08-29 01:25:08 +0000
1291+++ src/schooltool/gradebook/browser/templates/f_manage_report_sheets_overview.pt 2011-12-22 16:21:13 +0000
1292@@ -2,11 +2,11 @@
1293 tal:condition="view/has_schoolyear"
1294 tal:define="sheets view/sheets">
1295 <h3>
1296- <a title="Manage Report Sheets"
1297+ <a title="Manage Deployed Report Sheets"
1298 tal:attributes="href string:${context/@@absolute_url}/report_sheets"
1299 i18n:attributes="title"
1300 i18n:translate="">
1301- Report Sheets
1302+ Deployed Report Sheets
1303 </a>
1304 </h3>
1305 <p i18n:translate="" tal:condition="sheets">
1306
1307=== modified file 'src/schooltool/gradebook/browser/templates/f_template_manage.pt'
1308--- src/schooltool/gradebook/browser/templates/f_template_manage.pt 2011-10-01 07:08:33 +0000
1309+++ src/schooltool/gradebook/browser/templates/f_template_manage.pt 2011-12-22 16:21:13 +0000
1310@@ -23,7 +23,7 @@
1311 i18n:attributes="alt" />
1312 </a>
1313 </td>
1314- <td tal:content="activity/scoresystem/title "/>
1315+ <td tal:content="python: view.display_scoresystem(activity)" />
1316 <td>
1317 <button class="image" type="submit" title="Delete" value="1"
1318 tal:attributes="name string:delete.${activity/__name__};"
1319
1320=== modified file 'src/schooltool/gradebook/browser/templates/f_templates_overview.pt'
1321--- src/schooltool/gradebook/browser/templates/f_templates_overview.pt 2011-09-26 18:30:13 +0000
1322+++ src/schooltool/gradebook/browser/templates/f_templates_overview.pt 2011-12-22 16:21:13 +0000
1323@@ -15,5 +15,9 @@
1324 </tr>
1325 </table>
1326 </form>
1327+ <h3>
1328+ <a tal:attributes="href string:${context/schooltool:app/@@absolute_url}/manage"
1329+ i18n:translate="">Done</a>
1330+ </h3>
1331 </div>
1332
1333
1334=== modified file 'src/schooltool/gradebook/configure.zcml'
1335--- src/schooltool/gradebook/configure.zcml 2011-11-22 17:30:59 +0000
1336+++ src/schooltool/gradebook/configure.zcml 2011-12-22 16:21:13 +0000
1337@@ -57,6 +57,18 @@
1338 factory=".activity.getSectionActivities"
1339 trusted="true"
1340 />
1341+ <adapter
1342+ for="schooltool.course.interfaces.ICourse"
1343+ provides=".interfaces.ICourseActivities"
1344+ factory=".activity.getCourseActivities"
1345+ trusted="true"
1346+ />
1347+ <adapter
1348+ for="schooltool.course.interfaces.ICourse"
1349+ provides=".interfaces.ICourseDeployedWorksheets"
1350+ factory=".activity.getCourseDeployedWorksheets"
1351+ trusted="true"
1352+ />
1353
1354 <!-- Activity Content and Security -->
1355 <class class=".gradebook_init.GradebookRoot">
1356@@ -109,6 +121,26 @@
1357 set_schema=".interfaces.IActivities"
1358 />
1359 </class>
1360+ <class class=".activity.CourseActivities">
1361+ <require
1362+ permission="schooltool.view"
1363+ interface=".interfaces.ICourseActivities"
1364+ />
1365+ <require
1366+ permission="schooltool.edit"
1367+ set_schema=".interfaces.ICourseActivities"
1368+ />
1369+ </class>
1370+ <class class=".activity.CourseDeployedWorksheets">
1371+ <require
1372+ permission="schooltool.view"
1373+ interface=".interfaces.ICourseDeployedWorksheets"
1374+ />
1375+ <require
1376+ permission="schooltool.edit"
1377+ set_schema=".interfaces.ICourseDeployedWorksheets"
1378+ />
1379+ </class>
1380 <class class=".activity.Worksheet">
1381 <allow interface="zope.interface.common.mapping.IReadMapping" />
1382 <require
1383@@ -136,6 +168,19 @@
1384 attributes="changePosition"
1385 />
1386 </class>
1387+ <class class=".activity.CourseWorksheet">
1388+ <allow interface="zope.interface.common.mapping.IReadMapping" />
1389+ <require
1390+ permission="schooltool.view"
1391+ attributes="keys __iter__ values items __len__ title deployed"
1392+ />
1393+ <require
1394+ permission="schooltool.edit"
1395+ interface="zope.interface.common.mapping.IWriteMapping"
1396+ set_schema=".interfaces.ICourseWorksheet"
1397+ attributes="changePosition"
1398+ />
1399+ </class>
1400 <class class=".activity.Activity">
1401 <allow interface="zope.interface.common.mapping.IReadMapping" />
1402 <require
1403@@ -304,6 +349,12 @@
1404 name="activities"
1405 adapter="schooltool.gradebook.interfaces.IActivities"
1406 />
1407+ <adapterTraverserPlugin
1408+ for="schooltool.course.interfaces.ICourse"
1409+ layer="zope.publisher.interfaces.http.IHTTPRequest"
1410+ name="activities"
1411+ adapter="schooltool.gradebook.interfaces.ICourseActivities"
1412+ />
1413
1414 <!-- special traversal adapter for traversing from worksheet to gradebook -->
1415 <adapter
1416
1417=== modified file 'src/schooltool/gradebook/interfaces.py'
1418--- src/schooltool/gradebook/interfaces.py 2011-08-30 16:15:01 +0000
1419+++ src/schooltool/gradebook/interfaces.py 2011-12-22 16:21:13 +0000
1420@@ -89,6 +89,18 @@
1421 contains('.IWorksheet')
1422
1423
1424+class ICourseActivities(interfaces.IRequirement):
1425+ """Container of Course Worksheet Templates that can be deployed"""
1426+
1427+ contains('.ICourseWorksheet')
1428+
1429+
1430+class ICourseDeployedWorksheets(interfaces.IRequirement):
1431+ """Container of Deployed Course Worksheets (by term)"""
1432+
1433+ contains('.IWorksheet')
1434+
1435+
1436 class IWorksheet(interfaces.IRequirement):
1437 '''A list of activities that must be fulfilled in a course or section.'''
1438
1439@@ -111,12 +123,15 @@
1440 """Set the weight for the given category. Any numeric type is
1441 acceptable"""
1442
1443+ def canAverage():
1444+ """return True if activities have scoresystems that can be averaged"""
1445+
1446 containers(IActivities)
1447 contains('.IActivity')
1448
1449
1450 class IReportWorksheet(interfaces.IRequirement):
1451- '''A list of report card activities that get copied into sections.'''
1452+ '''A worksheet template to get copied into section gradebooks.'''
1453
1454 containers(IGradebookTemplates, IGradebookDeployed)
1455 contains('.IReportActivity')
1456@@ -126,13 +141,23 @@
1457 description=_(u'Identifies the report sheet in teacher gradebooks.'))
1458
1459
1460+class ICourseWorksheet(interfaces.IRequirement):
1461+ '''A worksheet template to get copied into section gradebooks.'''
1462+
1463+ contains('.IActivity')
1464+
1465+ title = zope.schema.TextLine(
1466+ title=_(u'Title'),
1467+ description=_(u'Identifies the course worksheet in gradebooks.'))
1468+
1469+
1470 class IActivity(interfaces.IRequirement):
1471 '''An activity to be graded'''
1472
1473 due_date = zope.schema.Date(
1474 title=_("Due Date"),
1475 description=_("The date the activity is due to be graded."),
1476- required=True)
1477+ required=False)
1478
1479 label = zope.schema.TextLine(
1480 title=_(u"Label"),
1481@@ -164,7 +189,7 @@
1482
1483
1484 class IReportActivity(IActivity):
1485- '''An activity to be deployed to section activities'''
1486+ '''A report card activity to be deployed to section activities'''
1487
1488 containers(IReportWorksheet)
1489
1490
1491=== modified file 'src/schooltool/gradebook/tests/test_gradebook.py'
1492--- src/schooltool/gradebook/tests/test_gradebook.py 2011-08-30 16:15:01 +0000
1493+++ src/schooltool/gradebook/tests/test_gradebook.py 2011-12-22 16:21:13 +0000
1494@@ -28,7 +28,7 @@
1495 from zope.component import provideAdapter, provideUtility
1496 from zope.interface import classImplements
1497
1498-from schooltool.course.interfaces import ISection
1499+from schooltool.course.interfaces import ICourse, ISection
1500 from schooltool.relationship.tests import setUpRelationships
1501 from schooltool.person.person import Person
1502 from schooltool.requirement import testing
1503@@ -48,6 +48,12 @@
1504 provideAdapter(
1505 activity.getSectionActivities,
1506 (ISection,), interfaces.IActivities)
1507+ provideAdapter(
1508+ activity.getCourseActivities,
1509+ (ICourse,), interfaces.ICourseActivities)
1510+ provideAdapter(
1511+ activity.getCourseDeployedWorksheets,
1512+ (ICourse,), interfaces.ICourseDeployedWorksheets)
1513
1514 provideAdapter(gradebook.Gradebook)
1515

Subscribers

People subscribed via source and target branches

to all changes: