--- loncom/homework/grades.pm 2005/09/21 21:44:55 1.286 +++ loncom/homework/grades.pm 2005/12/02 19:40:47 1.300 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # The LON-CAPA Grading handler # -# $Id: grades.pm,v 1.286 2005/09/21 21:44:55 albertel Exp $ +# $Id: grades.pm,v 1.300 2005/12/02 19:40:47 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -334,7 +334,16 @@ COMMONJSFUNCTIONS #--- section, ids and fullnames for each user. sub getclasslist { my ($getsec,$filterlist) = @_; - $getsec = $getsec eq '' ? 'all' : $getsec; + my @getsec; + if (!ref($getsec)) { + if ($getsec ne '' && $getsec ne 'all') { + @getsec=($getsec); + } + } else { + @getsec=@{$getsec}; + } + if (grep(/^all$/,@getsec)) { undef(@getsec); } + my $classlist=&Apache::loncoursedata::get_classlist(); # Bail out if we were unable to get the classlist return if (! defined($classlist)); @@ -363,7 +372,7 @@ sub getclasslist { } $section = ($section ne '' ? $section : 'none'); if (&canview($section)) { - if ($getsec eq 'all' || $getsec eq $section) { + if (!@getsec || grep(/^\Q$section\E$/,@getsec)) { $sections{$section}++; $fullnames{$student}=$fullname; } else { @@ -536,7 +545,13 @@ sub verifyreceipt { if ($env{"course.$courseid.receiptalg"} eq 'receipt2') { $receiptparts=1; } my $parts=['0']; if ($receiptparts) { ($parts)=&response_type($url,$symb); } - foreach (sort {lc($$fullname{$a}) cmp lc($$fullname{$b}) } keys %$fullname) { + foreach (sort + { + if (lc($$fullname{$a}) ne lc($$fullname{$b})) { + return (lc($$fullname{$a}) cmp lc($$fullname{$b})); + } + return $a cmp $b; + } (keys(%$fullname))) { my ($uname,$udom)=split(/\:/); foreach my $part (@$parts) { if ($receipt eq &Apache::lonnet::ireceipt($uname,$udom,$courseid,$symb,$part)) { @@ -702,7 +717,14 @@ LISTJAVASCRIPT $gradeTable.='</tr>'."\n"; my $ctr = 0; - foreach my $student (sort {lc($$fullname{$a}) cmp lc($$fullname{$b}) } keys %$fullname) { + foreach my $student (sort + { + if (lc($$fullname{$a}) ne lc($$fullname{$b})) { + return (lc($$fullname{$a}) cmp lc($$fullname{$b})); + } + return $a cmp $b; + } + (keys(%$fullname))) { my ($uname,$udom) = split(/:/,$student); my %status = (); if ($env{'form.showgrading'} eq 'yes' && $submitonly ne 'all') { @@ -1370,10 +1392,10 @@ sub gradeBox { my $ctr = 0; $result.='<table border="0"><tr>'."\n"; # display radio buttons in a nice table 10 across while ($ctr<=$wgt) { - $result.= '<td><nobr><input type="radio" name="RADVAL'.$counter.'_'.$partid.'" '. + $result.= '<td><nobr><label><input type="radio" name="RADVAL'.$counter.'_'.$partid.'" '. 'onclick="javascript:writeBox(this.form,\''.$counter.'_'.$partid.'\','. $ctr.')" value="'.$ctr.'" '. - ($score eq $ctr ? 'checked':'').' /> '.$ctr."</nobr></td>\n"; + ($score eq $ctr ? 'checked':'').' /> '.$ctr."</label></nobr></td>\n"; $result.=(($ctr+1)%10 == 0 ? '</tr><tr>' : ''); $ctr++; } @@ -1822,13 +1844,24 @@ KEYWORDS '<input type="hidden" name="newmsg'.$counter.'" value="" />'."\n"; $result.=' <a href="javascript:msgCenter(document.SCORE,'.$counter. ',\''.$msgfor.'\')"; TARGET=_self>'. - 'Compose Message to student'.(scalar(@col_fullnames) >= 1 ? 's' : '').'</a> '. + &mt('Compose message to student').(scalar(@col_fullnames) >= 1 ? 's' : '').'</a> ('. + &mt('incl. grades').' <input type="checkbox" name="withgrades'.$counter.'" />)'. '<img src="'.$request->dir_config('lonIconsURL'). '/mailbkgrd.gif" width="14" height="10" name="mailicon'.$counter.'" />'."\n". - '<br /> (Message will be sent when you click on Save & Next below.)'."\n" - if ($env{'form.handgrade'} eq 'yes'); + '<br /> ('. + &mt('Message will be sent when you click on Save & Next below.').")\n"; $request->print($result); } + if ($perm{'vgr'}) { + $request->print('<br />'. + &Apache::loncommon::track_student_link(&mt('View recent activity'), + $uname,$udom,'check')); + } + if ($perm{'opa'}) { + $request->print('<br />'. + &Apache::loncommon::pprmlink(&mt('Set/Change parameters'), + $uname,$udom,$symb,'check')); + } my %seen = (); my @partlist; @@ -1944,18 +1977,24 @@ sub processHandGrade { my $includemsg = $env{'form.includemsg'.$ctr}; my ($subject,$message,$msgstatus) = ('','',''); if ($includemsg =~ /savemsg|newmsg\Q$ctr\E/) { - $subject = $env{'form.msgsub'} if ($includemsg =~ /^msgsub/); + $subject = $env{'form.msgsub'} if ($includemsg =~ /msgsub/); + unless ($subject=~/\w/) { $subject=&mt('Grading Feedback'); } my (@msgnum) = split(/,/,$includemsg); foreach (@msgnum) { $message.=$env{'form.'.$_} if ($_ =~ /savemsg|newmsg/ && $_ ne ''); } $message =&Apache::lonfeedback::clear_out_html($message); - $message.="\n\nPoint".($pts > 1 ? 's':'').' awarded = '.$pts.' out of '.$wgt; - $message.=" for <a href=\"". + if ($env{'form.withgrades'.$ctr}) { + $message.="\n\nPoint".($pts > 1 ? 's':'').' awarded = '.$pts.' out of '.$wgt; + $message.=" for <a href=\"". &Apache::lonnet::clutter($url). "?symb=$symb\">$env{'form.probTitle'}</a>"; + } $msgstatus = &Apache::lonmsg::user_normal_msg ($uname,$udom, - $env{'form.msgsub'},$message); + $subject.' ['. + &Apache::lonnet::declutter($url).']',$message); + $request->print('<br />'.&mt('Sending message to [_1]@[_2]',$uname,$udom).': '. + $msgstatus); } if ($env{'form.collaborator'.$ctr}) { my @collabstrs=&Apache::loncommon::get_env_multiple("form.collaborator$ctr"); @@ -2064,7 +2103,13 @@ sub processHandGrade { my (@parsedlist,@nextlist); my ($nextflg) = 0; - foreach (sort {lc($$fullname{$a}) cmp lc($$fullname{$b}) } keys %$fullname) { + foreach (sort + { + if (lc($$fullname{$a}) ne lc($$fullname{$b})) { + return (lc($$fullname{$a}) cmp lc($$fullname{$b})); + } + return $a cmp $b; + } (keys(%$fullname))) { if ($nextflg == 1 && $button =~ /Next$/) { push @parsedlist,$_; } @@ -2394,6 +2439,7 @@ sub viewgrades_js { } for (i=0;i<document.classgrade.total.value;i++) { var user = document.classgrade["ctr"+i].value; + user = user.replace(new RegExp(':', 'g'),"_"); var scorename = document.classgrade["GD_"+user+"_"+partid+"_awarded"]; var saveval = document.classgrade["GD_"+user+"_"+partid+"_solved_s"].value; var selname = document.classgrade["GD_"+user+"_"+partid+"_solved"]; @@ -2421,6 +2467,7 @@ sub viewgrades_js { for (i=0;i<document.classgrade.total.value;i++) { var user = document.classgrade["ctr"+i].value; + user = user.replace(new RegExp(':', 'g'),"_"); var scorename = document.classgrade["GD_"+user+"_"+partid+"_awarded"]; var saveval = document.classgrade["GD_"+user+"_"+partid+"_solved_s"].value; var selname = document.classgrade["GD_"+user+"_"+partid+"_solved"]; @@ -2438,6 +2485,7 @@ sub viewgrades_js { } else { for (i=0;i<document.classgrade.total.value;i++) { var user = document.classgrade["ctr"+i].value; + user = user.replace(new RegExp(':', 'g'),"_"); var scorename = document.classgrade["GD_"+user+"_"+partid+"_awarded"]; var saveval = document.classgrade["GD_"+user+"_"+partid+"_solved_s"].value; var selname = document.classgrade["GD_"+user+"_"+partid+"_solved"]; @@ -2496,6 +2544,7 @@ sub viewgrades_js { for (i=0;i<document.classgrade.total.value;i++) { var user = document.classgrade["ctr"+i].value; + user = user.replace(new RegExp(':', 'g'),"_"); var resetscore = document.classgrade["GD_"+user+"_"+partid+"_awarded"]; resetscore.value = document.classgrade["GD_"+user+"_"+partid+"_awarded_s"].value; var resettries = document.classgrade["GD_"+user+"_"+partid+"_tries"]; @@ -2579,9 +2628,9 @@ sub viewgrades { $result.='<table border="0"><tr>'; my $ctr = 0; while ($ctr<=$weight{$partid}) { # display radio buttons in a nice table 10 across - $result.= '<td><input type="radio" name="RADVAL_'.$partid.'" '. + $result.= '<td><label><input type="radio" name="RADVAL_'.$partid.'" '. 'onclick="javascript:writePoint(\''.$partid.'\','.$weight{$partid}. - ','.$ctr.')" />'.$ctr."</td>\n"; + ','.$ctr.')" />'.$ctr."</label></td>\n"; $result.=(($ctr+1)%10 == 0 ? '</tr><tr>' : ''); $ctr++; } @@ -2638,7 +2687,13 @@ sub viewgrades { #list all the students - with points and grade status my (undef,undef,$fullname) = &getclasslist($env{'form.section'},'1'); my $ctr = 0; - foreach (sort {lc($$fullname{$a}) cmp lc($$fullname{$b}) } keys %$fullname) { + foreach (sort + { + if (lc($$fullname{$a}) ne lc($$fullname{$b})) { + return (lc($$fullname{$a}) cmp lc($$fullname{$b})); + } + return $a cmp $b; + } (keys(%$fullname))) { $ctr++; $result.=&viewstudentgrade($url,$symb,$env{'request.course.id'}, $_,$$fullname{$_},\@parts,\%weight,$ctr,\%last_resets); @@ -2822,13 +2877,14 @@ sub editgrades { my $dropMenu = $env{'form.GD_'.$user.'_'.$_.'_solved'}; $score = 'excused' if (($dropMenu eq 'excused') && ($score ne 'excused')); + $newrecord{'resource.'.$_.'.regrader'}= + "$env{'user.name'}:$env{'user.domain'}"; if ($dropMenu eq 'reset status' && $old_score ne '') { # ignore if no previous attempts => nothing to reset - $newrecord{'resource.'.$_.'.tries'} = 0; + $newrecord{'resource.'.$_.'.tries'} = ''; $newrecord{'resource.'.$_.'.solved'} = ''; $newrecord{'resource.'.$_.'.award'} = ''; - $newrecord{'resource.'.$_.'.awarded'} = 0; - $newrecord{'resource.'.$_.'.regrader'}="$env{'user.name'}:$env{'user.domain'}"; + $newrecord{'resource.'.$_.'.awarded'} = ''; $updateflag = 1; if ($env{'form.GD_'.$user.'_'.$_.'_aggtries'} > 0) { my $aggtries = $env{'form.GD_'.$user.'_'.$_.'_aggtries'}; @@ -3162,7 +3218,6 @@ sub csvuploadoptions { <form method="post" enctype="multipart/form-data" action="/adm/grades" name="gradesupload"> <h3><font color="#339933">Uploading Class Grade Options</font></h3> <input type="hidden" name="command" value="csvuploadassign" /> -<input type="submit" value="Assign Grades" /><br /> <p> <label> <input type="checkbox" name="show_full_results" /> @@ -3190,7 +3245,8 @@ ENDPICK } # FIXME do a check for any duplicated user ids... # FIXME do a check for any invalid user ids?... - $request->print("<hr /></form>\n"); + $request->print('<input type="submit" value="Assign Grades" /><br /> +<hr /></form>'."\n"); $request->print(&show_grading_menu_form($symb,$url)); return ''; } @@ -3365,13 +3421,13 @@ LISTJAVASCRIPT $result.='<input type="hidden" name="page" />'."\n". '<input type="hidden" name="title" />'."\n"; - $result.=' <b>View Problems Text: </b><input type="radio" name="vProb" value="no" checked="on" /> no '."\n". - '<input type="radio" name="vProb" value="yes" /> yes '."<br>\n"; + $result.=' <b>View Problems Text: </b><label><input type="radio" name="vProb" value="no" checked="on" /> no </label>'."\n". + '<label><input type="radio" name="vProb" value="yes" /> yes </label>'."<br />\n"; $result.=' <b>Submission Details: </b>'. - '<input type="radio" name="lastSub" value="none" /> none'."\n". - '<input type="radio" name="lastSub" value="datesub" checked /> by dates and submissions'."\n". - '<input type="radio" name="lastSub" value="all" /> all details'."\n"; + '<label><input type="radio" name="lastSub" value="none" /> none</label>'."\n". + '<label><input type="radio" name="lastSub" value="datesub" checked /> by dates and submissions</label>'."\n". + '<label><input type="radio" name="lastSub" value="all" /> all details</label>'."\n"; $result.='<input type="hidden" name="section" value="'.$getsec.'" />'."\n". '<input type="hidden" name="Status" value="'.$env{'form.Status'}.'" />'."\n". @@ -3395,12 +3451,18 @@ LISTJAVASCRIPT my (undef,undef,$fullname) = &getclasslist($getsec,'1'); my $ptr = 1; - foreach my $student (sort {lc($$fullname{$a}) cmp lc($$fullname{$b}) } keys %$fullname) { + foreach my $student (sort + { + if (lc($$fullname{$a}) ne lc($$fullname{$b})) { + return (lc($$fullname{$a}) cmp lc($$fullname{$b})); + } + return $a cmp $b; + } (keys(%$fullname))) { my ($uname,$udom) = split(/:/,$student); $studentTable.=($ptr%2 == 1 ? '<tr bgcolor="#ffffe6">' : '</td>'); $studentTable.='<td align="right">'.$ptr.' </td>'; - $studentTable.='<td> <input type="radio" name="student" value="'.$student.'" /> ' - .&nameUserString(undef,$$fullname{$student},$uname,$udom)."\n"; + $studentTable.='<td> <label><input type="radio" name="student" value="'.$student.'" /> ' + .&nameUserString(undef,$$fullname{$student},$uname,$udom)."</label>\n"; $studentTable.=($ptr%2 == 0 ? '</td></tr>' : ''); $ptr++; } @@ -3472,7 +3534,11 @@ sub displayPage { my $navmap = Apache::lonnavmaps::navmap->new(); my ($mapUrl, $id, $resUrl)=&Apache::lonnet::decode_symb($env{'form.page'}); my $map = $navmap->getResourceByUrl($resUrl); # add to navmaps - + if (!$map) { + $request->print('<font color="red">Unable to view requested sequence. ('.$resUrl.')</font>'); + $request->print(&show_grading_menu_form($symb,$url)); + return; + } my $iterator = $navmap->getIterator($map->map_start(), $map->map_finish()); @@ -3678,7 +3744,12 @@ sub updateGradeByPage { my $navmap = Apache::lonnavmaps::navmap->new(); my ($mapUrl, $id, $resUrl) = &Apache::lonnet::decode_symb( $env{'form.page'}); my $map = $navmap->getResourceByUrl($resUrl); # add to navmaps - + if (!$map) { + $request->print('<font color="red">Unable to grade requested sequence. ('.$resUrl.')</font>'); + my ($symb,$url)=&get_symb_and_url($request); + $request->print(&show_grading_menu_form($symb,$url)); + return; + } my $iterator = $navmap->getIterator($map->map_start(), $map->map_finish()); @@ -4018,7 +4089,7 @@ SCANTRONFORM </tr> <tr bgcolor="#ffffe6"> <td colspan="2"> - <input type="submit" value="Show List of Files" /> + <input type="submit" value="Download: Show List of Associated Files" /> </td> </tr> </table> @@ -4324,7 +4395,7 @@ sub scantron_process_corrections { } } if ($err) { - $r->print("Unable to accept last correction, an error occurred :$errmsg:"); + $r->print("<font color='red'>Unable to accept last correction, an error occurred :$errmsg:</font>"); } else { &scantron_put_line($scanlines,$scan_data,$which,$line,$skip); &scantron_putfile($scanlines,$scan_data); @@ -5390,10 +5461,10 @@ GRADINGMENUJS $result.='</td></tr>'; - $result.='<tr bgcolor="#ffffe6"valign="top"><td>'. + $result.='<tr bgcolor="#ffffe6"valign="top"><td><label>'. '<input type="radio" name="radioChoice" value="submission" '. ($saveCmd eq 'submission' ? 'checked' : '').'> '.'<b>'.&mt('Current Resource').':</b> '.&mt('For one or more students'). - ' <select name="submitonly">'. + '</label> <select name="submitonly">'. '<option value="yes" '. ($saveSub eq 'yes' ? 'selected="on"' : '').'>with submissions</option>'. '<option value="graded" '. @@ -5404,14 +5475,14 @@ GRADINGMENUJS ($saveSub eq 'all' ? 'selected="on"' : '').'>with any status</option></select></td></tr>'."\n"; $result.='<tr bgcolor="#ffffe6"valign="top"><td>'. - '<input type="radio" name="radioChoice" value="viewgrades" '. + '<label><input type="radio" name="radioChoice" value="viewgrades" '. ($saveCmd eq 'viewgrades' ? 'checked' : '').'> '. - '<b>Current Resource:</b> For all students in selected section or course</td></tr>'."\n"; + '<b>Current Resource:</b> For all students in selected section or course</label></td></tr>'."\n"; $result.='<tr bgcolor="#ffffe6" valign="top"><td>'. - '<input type="radio" name="radioChoice" value="pickStudentPage" '. + '<label><input type="radio" name="radioChoice" value="pickStudentPage" '. ($saveCmd eq 'pickStudentPage' ? 'checked' : '').'> '. - 'The <b>complete</b> set/page/sequence: For one student</td></tr>'."\n"; + 'The <b>complete</b> set/page/sequence: For one student</label></td></tr>'."\n"; $result.='<tr bgcolor="#ffffe6"><td><br />'. '<input type="button" onClick="javascript:checkChoice(this.form,\'2\');" value="Next->" />'. @@ -5455,18 +5526,18 @@ sub reset_perm { sub init_perm { &reset_perm(); - if (!($perm{'vgr'}=&Apache::lonnet::allowed('vgr',$env{'request.course.id'}))) { - if ($perm{'vgr'}=&Apache::lonnet::allowed('vgr',$env{'request.course.id'}.'/'.$env{'request.course.sec'})) { - $perm{'vgr_section'}=$env{'request.course.sec'}; - } else { - delete($perm{'vgr'}); - } - } - if (!($perm{'mgr'}=&Apache::lonnet::allowed('mgr',$env{'request.course.id'}))) { - if ($perm{'mgr'}=&Apache::lonnet::allowed('mgr',$env{'request.course.id'}.'/'.$env{'request.course.sec'})) { - $perm{'mgr_section'}=$env{'request.course.sec'}; - } else { - delete($perm{'mgr'}); + foreach my $test_perm ('vgr','mgr','opa') { + + my $scope = $env{'request.course.id'}; + if (!($perm{$test_perm}=&Apache::lonnet::allowed($test_perm,$scope))) { + + $scope .= '/'.$env{'request.course.sec'}; + if ( $perm{$test_perm}= + &Apache::lonnet::allowed($test_perm,$scope)) { + $perm{$test_perm.'_section'}=$env{'request.course.sec'}; + } else { + delete($perm{$test_perm}); + } } } }