--- loncom/homework/grades.pm 2006/03/02 18:01:41 1.325 +++ loncom/homework/grades.pm 2006/05/30 12:45:36 1.359 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # The LON-CAPA Grading handler # -# $Id: grades.pm,v 1.325 2006/03/02 18:01:41 www Exp $ +# $Id: grades.pm,v 1.359 2006/05/30 12:45:36 www Exp $ # # Copyright Michigan State University Board of Trustees # @@ -40,6 +40,9 @@ use Apache::lonmsg qw(:user_normal_msg); use Apache::Constants qw(:common); use Apache::lonlocal; use String::Similarity; +use lib '/home/httpd/lib/perl'; +use LONCAPA; + use POSIX qw(floor); my %oldessays=(); @@ -118,9 +121,10 @@ sub response_type { my %seen = (); my (@partlist,%handgrade,%responseType); foreach (split(/,/,&Apache::lonnet::metadata($url,'packages'))) { - if (/^\w+response_.*/) { + if (/^\w+response_.*/ || /^Task_/) { my ($responsetype,$part) = split(/_/,$_,2); my ($partid,$respid) = split(/_/,$part); + if ($responsetype eq 'Task') { $respid='0'; } if (&Apache::loncommon::check_if_partid_hidden($partid,$symb)) { next; } @@ -205,9 +209,11 @@ sub get_order { return ($analyze{"$partid.$respid.shown"}); } #--- Clean response type for display -#--- Currently filters option/rank/radiobutton/match/essay response types only. +#--- Currently filters option/rank/radiobutton/match/essay/Task +# response types only. sub cleanRecord { - my ($answer,$response,$symb,$partid,$respid,$record,$order,$version) = @_; + my ($answer,$response,$symb,$partid,$respid,$record,$order,$version, + $uname,$udom) = @_; my $grayFont = '<font color="#999999">'; if ($response =~ /^(option|rank)$/) { my %answer=&Apache::lonnet::str2hash($answer); @@ -288,6 +294,37 @@ sub cleanRecord { my $jme=$record->{$version."resource.$partid.$respid.molecule"}; $result.=&Apache::chemresponse::jme_img($jme,$answer,400); return $result; + } elsif ( $response eq 'Task') { + if ( $answer eq 'SUBMITTED') { + my $files = $record->{$version."resource.$respid.$partid.bridgetask.portfiles"}; + my $result = &Apache::bridgetask::file_list($files,$uname,$udom); + return $result; + } elsif ( grep(/^\Q$version\E.*?\.instance$/, keys(%{$record})) ) { + my @matches = grep(/^\Q$version\E.*?\.instance$/, + keys(%{$record})); + return join('<br />',($version,@matches)); + + + } else { + my $result = + '<p>' + .&mt('Overall result: [_1]', + $record->{$version."resource.$respid.$partid.status"}) + .'</p>'; + + $result .= '<ul>'; + my @grade = grep(/^\Q${version}resource.$respid.$partid.\E[^.]*[.]status$/, + keys(%{$record})); + foreach my $grade (sort(@grade)) { + my ($dim) = ($grade =~/[.]([^.]+)[.]status$/); + $result.= '<li>'.&mt("Dimension: [_1], status [_2] ", + $dim, $record->{$grade}). + '</li>'; + } + $result.='</ul>'; + return $result; + } + } return $answer; } @@ -556,7 +593,7 @@ sub verifyreceipt { my $title.='<h3><font color="#339933">Verifying Submission Receipt '. $receipt.'</h3></font>'."\n". - '<font size=+1><b>Resource: </b>'.$env{'form.probTitle'}.'</font><br><br>'."\n"; + '<font size=+1><b>Resource: </b>'.$env{'form.probTitle'}.'</font><br /><br />'."\n"; my ($string,$contents,$matches) = ('','',0); my (undef,undef,$fullname) = &getclasslist('all','0'); @@ -688,7 +725,14 @@ LISTJAVASCRIPT $gradeTable.='<label><input type="radio" name="lastSub" value="lastonly" '.$checklastsub.' /> last submission only </label>'."\n". '<label><input type="radio" name="lastSub" value="last" /> last submission & parts info </label>'."\n". '<label><input type="radio" name="lastSub" value="datesub" /> by dates and submissions </label>'."\n". - '<label><input type="radio" name="lastSub" value="all" /> all details</label>'."\n". + '<label><input type="radio" name="lastSub" value="all" /> all details</label><br />'."\n". + ' <b>Grading Increments:</b> <select name="increment">'. + '<option value="1">Whole Points</option>'. + '<option value=".5">Half Points</option>'. + '<option value=".25">Quarter Points</option>'. + '<option value=".1">Tenths of a Point</option>'. + '</select>'. + '<input type="hidden" name="section" value="'.$getsec.'" />'."\n". '<input type="hidden" name="submitonly" value="'.$submitonly.'" />'."\n". '<input type="hidden" name="handgrade" value="'.$env{'form.handgrade'}.'" /><br />'."\n". @@ -1101,6 +1145,81 @@ sub sub_page_kw_js { my $request = shift; my $iconpath = $request->dir_config('lonIconsURL'); &commonJSfunctions($request); + + my $inner_js_msg_central=<<INNERJS; + <script text="text/javascript"> + function checkInput() { + opener.document.SCORE.msgsub.value = opener.checkEntities(document.msgcenter.msgsub.value); + var nmsg = opener.document.SCORE.savemsgN.value; + var usrctr = document.msgcenter.usrctr.value; + var newval = opener.document.SCORE["newmsg"+usrctr]; + newval.value = opener.checkEntities(document.msgcenter.newmsg.value); + + var msgchk = ""; + if (document.msgcenter.subchk.checked) { + msgchk = "msgsub,"; + } + var includemsg = 0; + for (var i=1; i<=nmsg; i++) { + var opnmsg = opener.document.SCORE["savemsg"+i]; + var frmmsg = document.msgcenter["msg"+i]; + opnmsg.value = opener.checkEntities(frmmsg.value); + var showflg = opener.document.SCORE["shownOnce"+i]; + showflg.value = "1"; + var chkbox = document.msgcenter["msgn"+i]; + if (chkbox.checked) { + msgchk += "savemsg"+i+","; + includemsg = 1; + } + } + if (document.msgcenter.newmsgchk.checked) { + msgchk += "newmsg"+usrctr; + includemsg = 1; + } + imgformname = opener.document.SCORE["mailicon"+usrctr]; + imgformname.src = "$iconpath/"+((includemsg) ? "mailto.gif" : "mailbkgrd.gif"); + var includemsg = opener.document.SCORE["includemsg"+usrctr]; + includemsg.value = msgchk; + + self.close() + + } + </script> +INNERJS + + my $inner_js_highlight_central=<<INNERJS; + <script type="text/javascript"> + function updateChoice(flag) { + opener.document.SCORE.kwclr.value = opener.radioSelection(document.hlCenter.kwdclr); + opener.document.SCORE.kwsize.value = opener.radioSelection(document.hlCenter.kwdsize); + opener.document.SCORE.kwstyle.value = opener.radioSelection(document.hlCenter.kwdstyle); + opener.document.SCORE.refresh.value = "on"; + if (opener.document.SCORE.keywords.value!=""){ + opener.document.SCORE.submit(); + } + self.close() + } +</script> +INNERJS + + my $start_page_msg_central = + &Apache::loncommon::start_page('Message Central',$inner_js_msg_central, + {'js_ready' => 1, + 'only_body' => 1, + 'bgcolor' =>'#FFFFFF',}); + my $end_page_msg_central = + &Apache::loncommon::end_page({'js_ready' => 1}); + + + my $start_page_highlight_central = + &Apache::loncommon::start_page('Highlight Central', + $inner_js_highlight_central, + {'js_ready' => 1, + 'only_body' => 1, + 'bgcolor' =>'#FFFFFF',}); + my $end_page_highlight_central = + &Apache::loncommon::end_page({'js_ready' => 1}); + my $docopen=&Apache::lonhtmlcommon::javascript_docopen(); $docopen=~s/^document\.//; $request->print(<<SUBJAVASCRIPT); @@ -1216,55 +1335,11 @@ sub sub_page_kw_js { pWin.focus(); pDoc = pWin.document; pDoc.$docopen; - pDoc.write("<html><head>"); - pDoc.write("<title>Message Central</title>"); - - pDoc.write("<script language=javascript>"); - pDoc.write("function checkInput() {"); - pDoc.write(" opener.document.SCORE.msgsub.value = opener.checkEntities(document.msgcenter.msgsub.value);"); - pDoc.write(" var nmsg = opener.document.SCORE.savemsgN.value;"); - pDoc.write(" var usrctr = document.msgcenter.usrctr.value;"); - pDoc.write(" var newval = opener.document.SCORE[\\"newmsg\\"+usrctr];"); - pDoc.write(" newval.value = opener.checkEntities(document.msgcenter.newmsg.value);"); - - pDoc.write(" var msgchk = \\"\\";"); - pDoc.write(" if (document.msgcenter.subchk.checked) {"); - pDoc.write(" msgchk = \\"msgsub,\\";"); - pDoc.write(" }"); - pDoc.write(" var includemsg = 0;"); - pDoc.write(" for (var i=1; i<=nmsg; i++) {"); - pDoc.write(" var opnmsg = opener.document.SCORE[\\"savemsg\\"+i];"); - pDoc.write(" var frmmsg = document.msgcenter[\\"msg\\"+i];"); - pDoc.write(" opnmsg.value = opener.checkEntities(frmmsg.value);"); - pDoc.write(" var showflg = opener.document.SCORE[\\"shownOnce\\"+i];"); - pDoc.write(" showflg.value = \\"1\\";"); - pDoc.write(" var chkbox = document.msgcenter[\\"msgn\\"+i];"); - pDoc.write(" if (chkbox.checked) {"); - pDoc.write(" msgchk += \\"savemsg\\"+i+\\",\\";"); - pDoc.write(" includemsg = 1;"); - pDoc.write(" }"); - pDoc.write(" }"); - pDoc.write(" if (document.msgcenter.newmsgchk.checked) {"); - pDoc.write(" msgchk += \\"newmsg\\"+usrctr;"); - pDoc.write(" includemsg = 1;"); - pDoc.write(" }"); - pDoc.write(" imgformname = opener.document.SCORE[\\"mailicon\\"+usrctr];"); - pDoc.write(" imgformname.src = \\"$iconpath/\\"+((includemsg) ? \\"mailto.gif\\" : \\"mailbkgrd.gif\\");"); - pDoc.write(" var includemsg = opener.document.SCORE[\\"includemsg\\"+usrctr];"); - pDoc.write(" includemsg.value = msgchk;"); - - pDoc.write(" self.close()"); - - pDoc.write("}"); - - pDoc.write("<"); - pDoc.write("/script>"); - - pDoc.write("</head><body bgcolor=white>"); + pDoc.write('$start_page_msg_central'); pDoc.write("<form action=\\"inactive\\" name=\\"msgcenter\\">"); pDoc.write("<input value=\\""+usrctr+"\\" name=\\"usrctr\\" type=\\"hidden\\">"); - pDoc.write("<font color=\\"green\\" size=+1> Compose Message for \"+fullname+\"</font><br><br>"); + pDoc.write("<font color=\\"green\\" size=+1> Compose Message for \"+fullname+\"</font><br /><br />"); pDoc.write("<table border=0 width=100%><tr><td bgcolor=\\"#777777\\">"); pDoc.write("<table border=0 width=100%><tr bgcolor=\\"#ddffff\\">"); @@ -1299,9 +1374,9 @@ sub sub_page_kw_js { pDoc.write("</table>"); pDoc.write("</td></tr></table> "); pDoc.write("<input type=\\"button\\" value=\\"Save\\" onClick=\\"javascript:checkInput()\\"> "); - pDoc.write("<input type=\\"button\\" value=\\"Cancel\\" onClick=\\"self.close()\\"><br><br>"); + pDoc.write("<input type=\\"button\\" value=\\"Cancel\\" onClick=\\"self.close()\\"><br /><br />"); pDoc.write("</form>"); - pDoc.write("</body></html>"); + pDoc.write('$end_page_msg_central'); pDoc.close(); } @@ -1347,28 +1422,9 @@ sub sub_page_kw_js { hwdWin.focus(); var hDoc = hwdWin.document; hDoc.$docopen; - hDoc.write("<html><head>"); - hDoc.write("<title>Highlight Central</title>"); - - hDoc.write("<script language=javascript>"); - hDoc.write("function updateChoice(flag) {"); - hDoc.write(" opener.document.SCORE.kwclr.value = opener.radioSelection(document.hlCenter.kwdclr);"); - hDoc.write(" opener.document.SCORE.kwsize.value = opener.radioSelection(document.hlCenter.kwdsize);"); - hDoc.write(" opener.document.SCORE.kwstyle.value = opener.radioSelection(document.hlCenter.kwdstyle);"); - hDoc.write(" opener.document.SCORE.refresh.value = \\"on\\";"); - hDoc.write(" if (opener.document.SCORE.keywords.value!=\\"\\"){"); - hDoc.write(" opener.document.SCORE.submit();"); - hDoc.write(" }"); - hDoc.write(" self.close()"); - hDoc.write("}"); - - hDoc.write("<"); - hDoc.write("/script>"); - - hDoc.write("</head><body bgcolor=white>"); - + hDoc.write('$start_page_highlight_central'); hDoc.write("<form action=\\"inactive\\" name=\\"hlCenter\\">"); - hDoc.write("<font color=\\"green\\" size=+1> Keyword Highlight Options</font><br><br>"); + hDoc.write("<font color=\\"green\\" size=+1> Keyword Highlight Options</font><br /><br />"); hDoc.write("<table border=0 width=100%><tr><td bgcolor=\\"#777777\\">"); hDoc.write("<table border=0 width=100%><tr bgcolor=\\"#ddffff\\">"); @@ -1392,9 +1448,9 @@ sub sub_page_kw_js { hDoc.write("</table>"); hDoc.write("</td></tr></table> "); hDoc.write("<input type=\\"button\\" value=\\"Save\\" onClick=\\"javascript:updateChoice(1)\\"> "); - hDoc.write("<input type=\\"button\\" value=\\"Cancel\\" onClick=\\"self.close()\\"><br><br>"); + hDoc.write("<input type=\\"button\\" value=\\"Cancel\\" onClick=\\"self.close()\\"><br /><br />"); hDoc.write("</form>"); - hDoc.write("</body></html>"); + hDoc.write('$end_page_highlight_central'); hDoc.close(); } @@ -1402,6 +1458,15 @@ sub sub_page_kw_js { SUBJAVASCRIPT } +sub get_increment { + my $increment = $env{'form.increment'}; + if ($increment != 1 && $increment != .5 && $increment != .25 && + $increment != .1) { + $increment = 1; + } + return $increment; +} + #--- displays the grading box, used in essay type problem and grading by page/sequence sub gradeBox { my ($request,$symb,$uname,$udom,$counter,$partid,$record) = @_; @@ -1424,13 +1489,16 @@ sub gradeBox { $result.='<table border="0"><tr><td>'. '<b>Part: </b>'.$display_part.' <b>Points: </b></td><td>'."\n"; my $ctr = 0; + my $thisweight = 0; + my $increment = &get_increment(); $result.='<table border="0"><tr>'."\n"; # display radio buttons in a nice table 10 across - while ($ctr<=$wgt) { + while ($thisweight<=$wgt) { $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."</label></nobr></td>\n"; + $thisweight.')" value="'.$thisweight.'" '. + ($score eq $thisweight ? 'checked':'').' /> '.$thisweight."</label></nobr></td>\n"; $result.=(($ctr+1)%10 == 0 ? '</tr><tr>' : ''); + $thisweight += $increment; $ctr++; } $result.='</tr></table>'; @@ -1483,7 +1551,10 @@ sub handback_box { next if (!@$files); my $file_counter = 1; foreach my $file (@$files) { - my ($file_disp) = ($file =~ m|.+/(.+)$|); + my ($file_path, $file_disp) = ($file =~ m|(.+/)(.+)$|); + my ($name,$version,$ext) = &file_name_version_ext($file_disp); + $file_disp = "$name.$ext"; + $file = $file_path.$file_disp; $result.=&mt('Return commented version of [_1] to student.', '<span class="filename">'.$file_disp.'</span>'); $result.='<input type="file" name="'.$prefix.'returndoc'.$file_counter.'" />'."\n"; @@ -1497,6 +1568,7 @@ sub handback_box { sub show_problem { my ($request,$symb,$uname,$udom,$removeform,$viewon,$mode) = @_; my $rendered; + &Apache::lonxml::remember_problem_counter(); if ($mode eq 'both' or $mode eq 'text') { $rendered=&Apache::loncommon::get_student_view($symb,$uname,$udom, $env{'request.course.id'}); @@ -1508,6 +1580,7 @@ sub show_problem { } my $companswer; if ($mode eq 'both' or $mode eq 'answer') { + &Apache::lonxml::restore_problem_counter(); $companswer=&Apache::loncommon::get_student_answers($symb,$uname,$udom, $env{'request.course.id'}); } @@ -1594,6 +1667,7 @@ sub submission { } elsif ($env{'form.vAns'} eq 'yes') { $mode='answer'; } + &Apache::lonxml::clear_problem_counter(); $request->print(&show_problem($request,$symb,$uname,$udom,0,1,$mode)); } @@ -1630,9 +1704,9 @@ sub submission { '<input type="hidden" name="vProb" value="'.$env{'form.vProb'}.'" />'."\n". '<input type="hidden" name="vAns" value="'.$env{'form.vAns'}.'" />'."\n". '<input type="hidden" name="lastSub" value="'.$env{'form.lastSub'}.'" />'."\n". - '<input type="hidden" name="section" value="'.$env{'form.section'}.'">'."\n". - '<input type="hidden" name="submitonly" value="'.$env{'form.submitonly'}.'">'."\n". - '<input type="hidden" name="handgrade" value="'.$env{'form.handgrade'}.'">'."\n". + '<input type="hidden" name="section" value="'.$env{'form.section'}.'" />'."\n". + '<input type="hidden" name="submitonly" value="'.$env{'form.submitonly'}.'" />'."\n". + '<input type="hidden" name="handgrade" value="'.$env{'form.handgrade'}.'" />'."\n". '<input type="hidden" name="NCT"'. ' value="'.($env{'form.NTSTU'} ne '' ? $env{'form.NTSTU'} : $total+1).'" />'."\n"); if ($env{'form.handgrade'} eq 'yes') { @@ -1676,7 +1750,7 @@ KEYWORDS # my (undef,undef,$essayurl) = &Apache::lonnet::decode_symb($symb); my ($adom,$aname,$apath)=($essayurl=~/^(\w+)\/(\w+)\/(.*)$/); - $apath=&Apache::lonnet::escape($apath); + $apath=&escape($apath); $apath=~s/\W/\_/gs; %oldessays=&Apache::lonnet::dump('nohist_essay_'.$apath,$adom,$aname); } @@ -1692,6 +1766,7 @@ KEYWORDS } elsif ($env{'form.vAns'} eq 'all') { $mode='answer'; } + &Apache::lonxml::clear_problem_counter(); $request->print(&show_problem($request,$symb,$uname,$udom,1,1,$mode)); } @@ -1700,8 +1775,8 @@ KEYWORDS # Display student info $request->print(($counter == 0 ? '' : '<br />')); - my $result='<table border="0" width=100%><tr><td bgcolor="#777777">'."\n". - '<table border="0" width=100%><tr bgcolor="#edffff"><td>'."\n"; + my $result='<table border="0" width="100%"><tr><td bgcolor="#777777">'."\n". + '<table border="0" width="100%"><tr bgcolor="#edffff"><td>'."\n"; $result.='<b>Fullname: </b>'.&nameUserString(undef,$env{'form.fullname'},$uname,$udom).'<br />'."\n"; $result.='<input type="hidden" name="name'.$counter. @@ -1837,7 +1912,7 @@ KEYWORDS foreach my $file (@$files) { $file_counter ++; &Apache::lonnet::allowuploaded('/adm/grades',$file); - $lastsubonly.='<br /><a href="'.$file.'" target="lonGRDs"><img src="'.&Apache::loncommon::icon($file).'" border="0"> '.$file.'</a>'; + $lastsubonly.='<br /><a href="'.$file.'?rawmode=1" target="lonGRDs"><img src="'.&Apache::loncommon::icon($file).'" border=0"> '.$file.'</a>'; } $lastsubonly.='<br />'; } @@ -1893,8 +1968,8 @@ KEYWORDS '<input type="hidden" name="newmsg'.$counter.'" value="" />'."\n"; $result.=' <a href="javascript:msgCenter(document.SCORE,'.$counter. ',\''.$msgfor.'\')"; TARGET=_self>'. - &mt('Compose message to student').(scalar(@col_fullnames) >= 1 ? 's' : '').'</a> ('. - &mt('incl. grades').' <input type="checkbox" name="withgrades'.$counter.'" />)'. + &mt('Compose message to student').(scalar(@col_fullnames) >= 1 ? 's' : '').'</a><label> ('. + &mt('incl. grades').' <input type="checkbox" name="withgrades'.$counter.'" /></label>)'. '<img src="'.$request->dir_config('lonIconsURL'). '/mailbkgrd.gif" width="14" height="10" name="mailicon'.$counter.'" />'."\n". '<br /> ('. @@ -1954,6 +2029,8 @@ KEYWORDS '<input type="button" value="Next" '. 'onClick="javascript:checksubmit(this.form,\'Next\');" TARGET=_self> '; $endform.='(Next and Previous (student) do not save the scores.)'."\n" ; + $endform.="<input type='hidden' value='".&get_increment(). + "' name='increment' />"; $endform.='</td><tr></table></form>'; $endform.=&show_grading_menu_form($symb); $request->print($endform); @@ -2231,20 +2308,19 @@ sub processHandGrade { #---- Save the score and award for each student, if changed sub saveHandGrade { my ($request,$symb,$stuname,$domain,$newflg,$submitter,$part) = @_; - my @v_flag; + my @version_parts; my $usec = &Apache::lonnet::getsection($domain,$stuname, $env{'request.course.id'}); if (!&canmodify($usec)) { return('not_allowed'); } - my %record = &Apache::lonnet::restore($symb,$env{'request.course.id'},$domain,$stuname); + my %record = &Apache::lonnet::restore($symb,$env{'request.course.id'},$domain,$stuname); my @parts_graded; my %newrecord = (); my ($pts,$wgt) = ('',''); my %aggregate = (); my $aggregateflag = 0; - my @parts = split(/:/,$env{'form.partlist'.$newflg}); foreach my $new_part (@parts) { - #collaborator may vary for different parts + #collaborator ($submi may vary for different parts if ($submitter && $new_part ne $part) { next; } my $dropMenu = $env{'form.GD_SEL'.$newflg.'_'.$new_part}; if ($dropMenu eq 'excused') { @@ -2274,7 +2350,7 @@ sub saveHandGrade { my $solvedstatus = $record{'resource.'.$new_part.'.solved'}; if ($aggtries > 0) { - &decrement($symb,$new_part,\%aggregate,$aggtries,$totaltries,$solvedstatus); + &decrement_aggs($symb,$new_part,\%aggregate,$aggtries,$totaltries,$solvedstatus); $aggregateflag = 1; } } elsif ($dropMenu eq '') { @@ -2289,6 +2365,7 @@ sub saveHandGrade { my $partial= $pts/$wgt; if ($partial eq $record{'resource.'.$new_part.'.awarded'}) { #do not update score for part if not changed. + &handback_files($request,$symb,$stuname,$domain,$newflg,$new_part,\%newrecord); next; } else { push @parts_graded, $new_part; @@ -2312,43 +2389,26 @@ sub saveHandGrade { } $newrecord{'resource.'.$new_part.'.regrader'}= "$env{'user.name'}:$env{'user.domain'}"; + &handback_files($request,$symb,$stuname,$domain,$newflg,$new_part,\%newrecord); } - my ($partlist,$handgrade,$responseType) = &response_type($symb); - foreach my $part_resp (sort(keys(%$handgrade))) { - my ($part_id, $resp_id) = split(/_/,$part_resp); - &Apache::lonnet::logthis('form.'.$newflg.'_'.$part_resp.'_returndoc1'); - &Apache::lonnet::logthis("new part is $new_part and partid is $part_id"); - if (($env{'form.'.$newflg.'_'.$part_resp.'_returndoc1'}) && ($new_part == $part_id)) { - # if multiple files are uploaded names will be 'returndoc2','returndoc3' - my $file_counter = 1; - while ($env{'form.'.$newflg.'_'.$part_resp.'_returndoc'.$file_counter}) { - my $fname=$env{'form.'.$newflg.'_'.$part_resp.'_returndoc'.$file_counter.'.filename'}; - $newrecord{"resource.$new_part.$resp_id.handback"} = $env{'form.returndocorig'.$file_counter}; - $request->print("<br />".$fname." will be the uploaded file name"); - $request->print("<font color=\"red\">Will upload document</font>".$env{'form.'.$newflg.'_'.$part_resp.'_origdoc'.$file_counter}); - $file_counter++; - } - } - } - # unless problem has been graded, set flag to version the submitted files unless ($record{'resource.'.$new_part.'.solved'} =~ /^correct_/ || $record{'resource.'.$new_part.'.solved'} eq 'incorrect_by_override' || $dropMenu eq 'reset status') { - push (@v_flag,$new_part); + push (@version_parts,$new_part); } } my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; - if (scalar(keys(%newrecord)) > 0) { - if (scalar(@v_flag)) { - &version_portfiles(\%record, \@parts_graded, $env{'request.course.id'}, $symb, $domain, $stuname, \@v_flag); + if (%newrecord) { + if (@version_parts) { + my @changed_keys = &version_portfiles(\%record, \@parts_graded, $env{'request.course.id'}, $symb, $domain, $stuname, \@version_parts); + @newrecord{@changed_keys} = @record{@changed_keys}; } &Apache::lonnet::cstore(\%newrecord,$symb, $env{'request.course.id'},$domain,$stuname); - my @ungraded_parts; foreach my $part (@parts) { if ( !defined($record{'resource.'.$part.'.awarded'}) @@ -2368,6 +2428,54 @@ sub saveHandGrade { return ('',$pts,$wgt); } +sub handback_files { + my ($request,$symb,$stuname,$domain,$newflg,$new_part,$newrecord) = @_; + my $portfolio_root = &propath($domain,$stuname).'/userfiles/portfolio'; + my ($partlist,$handgrade,$responseType) = &response_type($symb); + foreach my $part_resp (sort(keys(%$handgrade))) { + my ($part_id, $resp_id) = split(/_/,$part_resp); + if (($env{'form.'.$newflg.'_'.$part_resp.'_returndoc1'}) && ($new_part == $part_id)) { + # if multiple files are uploaded names will be 'returndoc2','returndoc3' + my $file_counter = 1; + while ($env{'form.'.$newflg.'_'.$part_resp.'_returndoc'.$file_counter}) { + my $fname=$env{'form.'.$newflg.'_'.$part_resp.'_returndoc'.$file_counter.'.filename'}; + my ($directory,$answer_file) = + ($env{'form.'.$newflg.'_'.$part_resp.'_origdoc'.$file_counter} =~ /^(.*?)([^\/]*)$/); + my ($answer_name,$answer_ver,$answer_ext) = + &file_name_version_ext($answer_file); + my ($portfolio_path) = ($directory =~ /^.+$stuname\/portfolio(.*)/); + my @dir_list = &Apache::lonnet::dirlist($portfolio_path,$domain,$stuname,$portfolio_root); + my $version = &get_next_version($answer_name, $answer_ext, \@dir_list); + my $new_answer = &version_selected_portfile($domain, $stuname, $portfolio_path, $answer_file, $version); + $$newrecord{"resource.$new_part.$resp_id.handback"} = $new_answer; + $version++; + # fix file name + my ($save_file_name) = (($directory.$answer_name.".$version.".$answer_ext) =~ /^.+\/${stuname}\/(.*)/); + my $result=&Apache::lonnet::finishuserfileupload($stuname,$domain, + $newflg.'_'.$part_resp.'_returndoc'.$file_counter, + $save_file_name); + if ($result !~ m|^/uploaded/|) { + $request->print('<font color="red"> An errror occured ('.$result. + ') while trying to upload '.$newflg.'_'.$part_resp.'_returndoc'.$file_counter.'</font><br />'); + } else { + my $subject = "File Handed Back by Instructor "; + my $message = "A file has been returned that was originally submitted in reponse to: <br />"; + $message .= "<strong>".&Apache::lonnet::gettitle($symb)."</strong><br />"; + $message .= " The returned file is named: <br /><strong>".$save_file_name."</strong><br />"; + $message .= " and can be found in your portfolio space."; + &Apache::lonnet::logthis($message); + my $msgstatus = &Apache::lonmsg::user_normal_msg($stuname,$domain, + $subject.' [File Returned]',$message); + } + $request->print("<br />".$fname." will be the uploaded file name"); + $request->print(" ".$env{'form.'.$newflg.'_'.$part_resp.'_origdoc'.$file_counter}); + $file_counter++; + } + } + } + return; +} + sub get_submitted_files { my ($udom,$uname,$partid,$respid,$record) = @_; my @files; @@ -2446,40 +2554,39 @@ sub get_last_resets { sub version_portfiles { my ($record, $parts_graded, $courseid, $symb, $domain, $stu_name, $v_flag) = @_; my $version_parts = join('|',@$v_flag); + my @returned_keys; my $parts = join('|', @$parts_graded); - my $portfolio_root = &Apache::loncommon::propath($domain, - $stu_name). - '/userfiles/portfolio'; + my $portfolio_root = &propath($domain,$stu_name). + '/userfiles/portfolio'; foreach my $key (keys(%$record)) { my $new_portfiles; if ($key =~ /^resource\.($version_parts)\./ && $key =~ /\.portfiles$/ ) { - my @v_portfiles; + my @versioned_portfiles; my @portfiles = split(/,/,$$record{$key}); foreach my $file (@portfiles) { &Apache::lonnet::unmark_as_readonly($domain,$stu_name,[$symb,$env{'request.course.id'}],$file); my ($directory,$answer_file) =($file =~ /^(.*?)([^\/]*)$/); - my $version = 0; my ($answer_name,$answer_ver,$answer_ext) = &file_name_version_ext($answer_file); my @dir_list = &Apache::lonnet::dirlist($directory,$domain,$stu_name,$portfolio_root); - $version = &get_next_version($answer_name, $answer_ext, \@dir_list); + my $version = &get_next_version($answer_name, $answer_ext, \@dir_list); my $new_answer = &version_selected_portfile($domain, $stu_name, $directory, $answer_file, $version); if ($new_answer ne 'problem getting file') { - push(@v_portfiles, $directory.$new_answer); + push(@versioned_portfiles, $directory.$new_answer); &Apache::lonnet::mark_as_readonly($domain,$stu_name, ['/portfolio'.$directory.$new_answer], [$symb,$env{'request.course.id'},'graded']); } - } - $$record{$key} = join(',',@v_portfiles); + $$record{$key} = join(',',@versioned_portfiles); + push(@returned_keys,$key); } } - return 'ok'; + return (@returned_keys); } sub get_next_version { - my ($answer_name, $answer_ext, $dir_list); + my ($answer_name, $answer_ext, $dir_list) = @_; my $version; foreach my $row (@$dir_list) { my ($file) = split(/\&/,$row,2); @@ -3233,7 +3340,7 @@ sub csvuploadmap_header { <form method="post" enctype="multipart/form-data" action="/adm/grades" name="gradesupload"> <h3><font color="#339933">Uploading Class Grades</font></h3> $result -<hr> +<hr /> <h3>Identify fields</h3> Total number of records found in file: $distotal <hr /> Enter as many fields as you can. The system will inform you and bring you back @@ -3315,8 +3422,8 @@ sub upcsvScores_form { $env{'form.probTitle'} = &Apache::lonnet::gettitle($symb); my ($table) = &showResourceInfo($symb,$env{'form.probTitle'}); $result.=$table; - $result.='<br /><table width=100% border=0><tr><td bgcolor="#777777">'."\n"; - $result.='<table width=100% border=0><tr bgcolor="#e6ffff"><td>'."\n"; + $result.='<br /><table width="100%" border="0"><tr><td bgcolor="#777777">'."\n"; + $result.='<table width="100%" border="0"><tr bgcolor="#e6ffff"><td>'."\n"; $result.=' <b>Specify a file containing the class scores for current resource'. '.</b></td></tr>'."\n"; $result.='<tr bgcolor=#ffffe6><td>'."\n"; @@ -3449,6 +3556,7 @@ sub csvuploadassign { my ($request)= @_; my ($symb)=&get_symb($request); if (!$symb) {return '';} + my $error_msg = ''; &Apache::loncommon::load_tmp_file($request); my @gradedata = &Apache::loncommon::upfile_record_sep(); if ($env{'form.noFirstLine'}) { shift(@gradedata); } @@ -3501,12 +3609,20 @@ sub csvuploadassign { my $part=$1; my $wgt =&Apache::lonnet::EXT('resource.'.$part.'.weight', $symb,$domain,$username); - $entries{$fields{$dest}}=~s/\s//g; - my $pcr=$entries{$fields{$dest}} / $wgt; - my $award='correct_by_override'; - $grades{"resource.$part.awarded"}=$pcr; - $grades{"resource.$part.solved"}=$award; - $points{$part}=1; + if ($wgt) { + $entries{$fields{$dest}}=~s/\s//g; + my $pcr=$entries{$fields{$dest}} / $wgt; + my $award='correct_by_override'; + $grades{"resource.$part.awarded"}=$pcr; + $grades{"resource.$part.solved"}=$award; + $points{$part}=1; + } else { + $error_msg = "<br />" . + &mt("Some point values were assigned" + ." for problems with a weight " + ."of zero. These values were " + ."ignored."); + } } else { if ($dest=~/stores_(.*)_awarded/) { if ($points{$1}) {next;} } if ($dest=~/stores_(.*)_solved/) { if ($points{$1}) {next;} } @@ -3546,7 +3662,7 @@ sub csvuploadassign { } $request->print("<br />\n"); $request->print(&show_grading_menu_form($symb)); - return ''; + return $error_msg; } #------------- end of section for handling csv file upload --------- # @@ -3597,7 +3713,7 @@ LISTJAVASCRIPT '>'.$showtitle.'</option>'."\n"; $ctr++; } - $result.= '</select>'."<br>\n"; + $result.= '</select>'."<br />\n"; $ctr=0; foreach (@$titles) { my ($minder,$showtitle) = ($_ =~ /(\d+)\.(.*)/); @@ -3627,7 +3743,7 @@ LISTJAVASCRIPT $request->print($result); - my $studentTable.=' <b>Select a student you wish to grade and then click on the Next button.</b><br>'. + my $studentTable.=' <b>Select a student you wish to grade and then click on the Next button.</b><br />'. '<table border="0"><tr><td bgcolor="#777777">'. '<table border="0"><tr bgcolor="#e6ffff">'. '<td align="right"> <b>No.</b></td>'. @@ -3748,6 +3864,7 @@ sub displayPage { '<td align="center"><b> Prob. </b></td>'. '<td><b> '.($env{'form.vProb'} eq 'no' ? 'Title' : 'Problem Text').'/Grade</b></td></tr>'; + &Apache::lonxml::clear_problem_counter(); my ($depth,$question,$prob) = (1,1,1); $iterator->next(); # skip the first BEGIN_MAP my $curRes = $iterator->next(); # for "current resource" @@ -3760,7 +3877,7 @@ sub displayPage { my $title = $curRes->compTitle(); my $symbx = $curRes->symb(); $studentTable.='<tr bgcolor="#ffffe6"><td align="center" valign="top" >'.$prob. - (scalar(@{$parts}) == 1 ? '' : '<br>('.scalar(@{$parts}).' parts)').'</td>'; + (scalar(@{$parts}) == 1 ? '' : '<br />('.scalar(@{$parts}).' parts)').'</td>'; $studentTable.='<td valign="top">'; if ($env{'form.vProb'} eq 'yes' ) { $studentTable.=&show_problem($request,$symbx,$uname,$udom,1, @@ -3771,10 +3888,10 @@ sub displayPage { $companswer =~ s|</form>||g; # while ($companswer =~ /(<a href\=\"javascript:newWindow.*?Script Vars<\/a>)/s) { #<a href="javascript:newWindow</a> # $companswer =~ s/$1/ /ms; -# $request->print('match='.$1."<br>\n"); +# $request->print('match='.$1."<br />\n"); # } # $companswer =~ s|<table border=\"1\">|<table border=\"0\">|g; - $studentTable.=' <b>'.$title.'</b> <br> <b>Correct answer:</b><br>'.$companswer; + $studentTable.=' <b>'.$title.'</b> <br /> <b>Correct answer:</b><br />'.$companswer; } my %record = &Apache::lonnet::restore($symbx,$env{'request.course.id'},$udom,$uname); @@ -3830,6 +3947,7 @@ sub displayPage { sub displaySubByDates { my ($symb,$record,$parts,$responseType,$checkIcon,$uname,$udom) = @_; my $isCODE=0; + my $isTask = ($symb =~/\.task$/); if (exists($record->{'resource.CODE'})) { $isCODE=1; } my $studentTable='<table border="0" width="100%"><tr><td bgcolor="#777777">'. '<table border="0" width="100%"><tr bgcolor="#e6ffff">'. @@ -3844,8 +3962,17 @@ sub displaySubByDates { if (!exists($$record{'1:timestamp'})) { return '<br /> <font color="red">Nothing submitted - no attempts</font><br />'; } + + my $interaction; for ($version=1;$version<=$$record{'version'};$version++) { my $timestamp = scalar(localtime($$record{$version.':timestamp'})); + if (exists($$record{$version.':resource.0.version'})) { + $interaction = $$record{$version.':resource.0.version'}; + } + + my $where = ($isTask ? "$version:resource.$interaction" + : "$version:resource"); + #&Apache::lonnet::logthis(" got $where"); $studentTable.='<tr bgcolor="#ffffff" valign="top"><td>'.$timestamp.'</td>'; if ($isCODE) { $studentTable.='<td>'.$record->{$version.':resource.CODE'}.'</td>'; @@ -3853,40 +3980,57 @@ sub displaySubByDates { my @versionKeys = split(/\:/,$$record{$version.':keys'}); my @displaySub = (); foreach my $partid (@{$parts}) { - my @matchKey = sort(grep /^resource\.\Q$partid\E\..*?\.submission$/,@versionKeys); + my @matchKey = ($isTask ? sort(grep /^resource\.\d+\.\Q$partid\E\.award$/,@versionKeys) + : sort(grep /^resource\.\Q$partid\E\..*?\.submission$/,@versionKeys)); + + # next if ($$record{"$version:resource.$partid.solved"} eq ''); my $display_part=&get_display_part($partid,$symb); foreach my $matchKey (@matchKey) { if (exists($$record{$version.':'.$matchKey}) && $$record{$version.':'.$matchKey} ne '') { - my ($responseId)=($matchKey=~ /^resource\.\Q$partid\E\.(.*?)\.submission$/); + + my ($responseId)= ($isTask ? ($matchKey=~ /^resource\.(.*?)\.\Q$partid\E\.award$/) + : ($matchKey=~ /^resource\.\Q$partid\E\.(.*?)\.submission$/)); + #&Apache::lonnet::logthis("match $matchKey $responseId (".$$record{$version.':'.$matchKey}); $displaySub[0].='<b>Part:</b> '.$display_part.' '; $displaySub[0].='<font color="#999999">(ID '. $responseId.')</font> <b>'; - if ($$record{"$version:resource.$partid.tries"} eq '') { + if ($$record{"$where.$partid.tries"} eq '') { $displaySub[0].='Trial not counted'; } else { $displaySub[0].='Trial '. - $$record{"$version:resource.$partid.tries"}; + $$record{"$where.$partid.tries"}; } - my $responseType=$responseType->{$partid}->{$responseId}; + my $responseType=($isTask ? 'Task' + : $responseType->{$partid}->{$responseId}); if (!exists($orders{$partid})) { $orders{$partid}={}; } if (!exists($orders{$partid}->{$responseId})) { $orders{$partid}->{$responseId}= &get_order($partid,$responseId,$symb,$uname,$udom); } $displaySub[0].='</b> '. - &cleanRecord($$record{$version.':'.$matchKey},$responseType,$symb,$partid,$responseId,$record,$orders{$partid}->{$responseId},"$version:").'<br />'; + &cleanRecord($$record{$version.':'.$matchKey},$responseType,$symb,$partid,$responseId,$record,$orders{$partid}->{$responseId},"$version:",$uname,$udom).'<br />'; } } - if (exists $$record{"$version:resource.$partid.award"}) { + if (exists($$record{"$where.$partid.checkedin"})) { + $displaySub[1].='Checked in by '. + $$record{"$where.$partid.checkedin"}.' into slot '. + $$record{"$where.$partid.checkedin.slot"}. + '<br />'; + } + if (exists $$record{"$where.$partid.award"}) { $displaySub[1].='<b>Part:</b> '.$display_part.' '. - lc($$record{"$version:resource.$partid.award"}).' '. - $mark{$$record{"$version:resource.$partid.solved"}}. + lc($$record{"$where.$partid.award"}).' '. + $mark{$$record{"$where.$partid.solved"}}. '<br />'; } - if (exists $$record{"$version:resource.$partid.regrader"}) { - $displaySub[2].=$$record{"$version:resource.$partid.regrader"}. + if (exists $$record{"$where.$partid.regrader"}) { + $displaySub[2].=$$record{"$where.$partid.regrader"}. + ' (<b>'.&mt('Part').':</b> '.$display_part.')'; + } elsif ($$record{"$version:resource.$partid.regrader"} =~ /\S/) { + $displaySub[2].= + $$record{"$version:resource.$partid.regrader"}. ' (<b>'.&mt('Part').':</b> '.$display_part.')'; } } @@ -3957,7 +4101,7 @@ sub updateGradeByPage { my $title = $curRes->compTitle(); my $symbx = $curRes->symb(); $studentTable.='<tr bgcolor="#ffffe6"><td align="center" valign="top" >'.$prob. - (scalar(@{$parts}) == 1 ? '' : '<br>('.scalar(@{$parts}).' parts)').'</td>'; + (scalar(@{$parts}) == 1 ? '' : '<br />('.scalar(@{$parts}).' parts)').'</td>'; $studentTable.='<td valign="top"> <b>'.$title.'</b> </td>'; my %newrecord=(); @@ -4003,10 +4147,10 @@ sub updateGradeByPage { my $oldstatus = $env{'form.solved'.$question.'_'.$partid}; $displayPts[0].=' <b>Part:</b> '.$display_part.' = '. (($oldstatus eq 'excused') ? 'excused' : $oldpts). - ' <br>'; + ' <br />'; $displayPts[1].=' <b>Part:</b> '.$display_part.' = '. (($score eq 'excused') ? 'excused' : $newpts). - ' <br>'; + ' <br />'; $question++; next if ($dropMenu eq 'reset status' || ($newpts == $oldpts && $score ne 'excused')); @@ -4084,7 +4228,7 @@ sub scantron_filenames { my $cdom=$env{'course.'.$env{'request.course.id'}.'.domain'}; my $cname=$env{'course.'.$env{'request.course.id'}.'.num'}; my @files=&Apache::lonnet::dirlist('userfiles',$cdom,$cname, - &Apache::loncommon::propath($cdom,$cname)); + &propath($cdom,$cname)); my @possiblenames; foreach my $filename (sort(@files)) { ($filename)=split(/&/,$filename); @@ -4192,7 +4336,8 @@ sub scantron_selectphase { <td> Options: </td> <td> <label><input type="checkbox" name="scantron_options_redo" value="redo_skipped"/> Do only previously skipped records</label> <br /> - <label><input type="checkbox" name="scantron_options_ignore" value="ignore_corrections"/> Remove all exisiting corrections</label> + <label><input type="checkbox" name="scantron_options_ignore" value="ignore_corrections"/> Remove all exisiting corrections</label> <br /> + <label><input type="checkbox" name="scantron_options_hidden" value="ignore_hidden"/> Skip hidden resources when grading</label> </td> </tr> <tr bgcolor="#ffffe6"> @@ -4521,8 +4666,15 @@ sub scantron_find_student { sub scantron_filter { my ($curres)=@_; - # randomout is dysfunctional at best for this purpose - if (ref($curres) && $curres->is_problem()) { #&& !$curres->randomout) { + + if (ref($curres) && $curres->is_problem()) { + # if the user has asked to not have either hidden + # or 'randomout' controlled resources to be graded + # don't include them + if ($env{'form.scantron_options_hidden'} eq 'ignore_hidden' + && $curres->randomout) { + return 0; + } return 1; } return 0; @@ -4617,7 +4769,6 @@ sub remember_current_skipped { $to_remember{$i}=1; } } - &Apache::lonnet::logthis('remembering '.join(':',%to_remember)); &scan_data($scan_data,'remember_skipping',join(':',%to_remember)); &scantron_putfile(undef,$scan_data); } @@ -4689,7 +4840,7 @@ $warning <input type="hidden" name="command" value="scantron_validate" /> STUFF } - $r->print("</form><br />".&show_grading_menu_form($symb)."</body></html>"); + $r->print("</form><br />".&show_grading_menu_form($symb)); return ''; } @@ -4705,6 +4856,7 @@ sub scantron_form_start { <input type="hidden" name="scantron_CODEunique" value="$env{'form.scantron_CODEunique'}" /> <input type="hidden" name="scantron_options_redo" value="$env{'form.scantron_options_redo'}" /> <input type="hidden" name="scantron_options_ignore" value="$env{'form.scantron_options_ignore'}" /> + <input type="hidden" name="scantron_options_hidden" value="$env{'form.scantron_options_hidden'}" /> SCANTRONFORM return $result; } @@ -4739,11 +4891,12 @@ sub scantron_validate_file { $r->print("<p>Gathering neccessary info.</p>");$r->rflush(); #get the student pick code ready $r->print(&Apache::loncommon::studentbrowser_javascript()); - my $max_bubble=&scantron_get_maxbubble($r); + my $max_bubble=&scantron_get_maxbubble(); my $result=&scantron_form_start($max_bubble).$default_form_data; $r->print($result); - my @validate_phases=( 'ID', + my @validate_phases=( 'sequence', + 'ID', 'CODE', 'doublebubble', 'missingbubbles'); @@ -4776,13 +4929,19 @@ STUFF $r->print("<input type='hidden' name='validatepass' value='".$currentphase."' />"); } if ($stop) { - $r->print('<input type="submit" name="submit" value="Continue ->" />'); - $r->print(' using corrected info <br />'); - $r->print("<input type='submit' value='Skip' name='scantron_skip_record' />"); - $r->print(" this scanline saving it for later."); + if ($validate_phases[$currentphase] eq 'sequence') { + $r->print('<input type="submit" name="submit" value="Ignore -> " />'); + $r->print(' this error <br />'); + + $r->print(" <p>Or click the 'Grading Menu' button to start over.</p>"); + } else { + $r->print('<input type="submit" name="submit" value="Continue ->" />'); + $r->print(' using corrected info <br />'); + $r->print("<input type='submit' value='Skip' name='scantron_skip_record' />"); + $r->print(" this scanline saving it for later."); + } } - $r->print(" </form><br />".&show_grading_menu_form($symb). - "</body></html>"); + $r->print(" </form><br />".&show_grading_menu_form($symb)); return ''; } @@ -4912,6 +5071,45 @@ sub scantron_put_line { $scanlines->{'corrected'}[$i]=$newline; } +sub scantron_filter_not_exam { + my ($curres)=@_; + + if (ref($curres) && $curres->is_problem() && !$curres->is_exam()) { + # if the user has asked to not have either hidden + # or 'randomout' controlled resources to be graded + # don't include them + if ($env{'form.scantron_options_hidden'} eq 'ignore_hidden' + && $curres->randomout) { + return 0; + } + return 1; + } + return 0; +} + +sub scantron_validate_sequence { + my ($r,$currentphase) = @_; + + my $navmap=Apache::lonnavmaps::navmap->new(); + my (undef,undef,$sequence)= + &Apache::lonnet::decode_symb($env{'form.selectpage'}); + + my $map=$navmap->getResourceByUrl($sequence); + + $r->print('<input type="hidden" name="validate_sequence_exam" + value="ignore" />'); + if ($env{'form.validate_sequence_exam'} ne 'ignore') { + my @resources= + $navmap->retrieveResources($map,\&scantron_filter_not_exam,1,0); + if (@resources) { + $r->print("<p>".&mt('Some resources in the sequence currently are not set to exam mode. Grading these resources currently may not work correctly.')."</p>"); + return (1,$currentphase); + } + } + + return (0,$currentphase+1); +} + sub scantron_validate_ID { my ($r,$currentphase) = @_; @@ -4982,7 +5180,7 @@ sub scantron_get_correction { #the previous one or the current one $r->print("<p><b>An error was detected ($error)</b>"); - if ( defined($$scan_record{'scantron.PaperID'}) ) { + if ( $$scan_record{'scantron.PaperID'} =~ /\S/) { $r->print(" for PaperID <tt>". $$scan_record{'scantron.PaperID'}."</tt> \n"); } else { @@ -5058,13 +5256,15 @@ function change_radio(field) { </script> ENDSCRIPT my $href="/adm/pickcode?". - "form=".&Apache::lonnet::escape("scantronupload"). - "&scantron_format=".&Apache::lonnet::escape($env{'form.scantron_format'}). - "&scantron_CODElist=".&Apache::lonnet::escape($env{'form.scantron_CODElist'}). - "&curCODE=".&Apache::lonnet::escape($$scan_record{'scantron.CODE'}). - "&scantron_selectfile=".&Apache::lonnet::escape($env{'form.scantron_selectfile'}); - $r->print("<label><input type='radio' name='scantron_CODE_resolution' value='use_found' /> <a target='_blank' href='$href'>Select</a> a CODE from the list of all CODEs and use it.</label> Selected CODE is <input readonly='true' type='text' size='8' name='scantron_CODE_selectedvalue' onfocus=\"javascript:change_radio('use_found')\" onchange=\"javascript:change_radio('use_found')\" />"); - $r->print("\n<br />"); + "form=".&escape("scantronupload"). + "&scantron_format=".&escape($env{'form.scantron_format'}). + "&scantron_CODElist=".&escape($env{'form.scantron_CODElist'}). + "&curCODE=".&escape($$scan_record{'scantron.CODE'}). + "&scantron_selectfile=".&escape($env{'form.scantron_selectfile'}); + if ($env{'form.scantron_CODElist'} =~ /\S/) { + $r->print("<label><input type='radio' name='scantron_CODE_resolution' value='use_found' /> <a target='_blank' href='$href'>Select</a> a CODE from the list of all CODEs and use it.</label> Selected CODE is <input readonly='true' type='text' size='8' name='scantron_CODE_selectedvalue' onfocus=\"javascript:change_radio('use_found')\" onchange=\"javascript:change_radio('use_found')\" />"); + $r->print("\n<br />"); + } $r->print("<label><input type='radio' name='scantron_CODE_resolution' value='use_typed' /> Use </label><input type='text' size='8' name='scantron_CODE_newvalue' onfocus=\"javascript:change_radio('use_typed')\" onkeypress=\"javascript:change_radio('use_typed')\" /> as the CODE."); $r->print("\n<br /><br />"); } elsif ($error eq 'doublebubble') { @@ -5238,28 +5438,29 @@ sub scantron_validate_doublebubble { return (0,$currentphase+1); } -sub scantron_get_maxbubble { - my ($r)=@_; +sub scantron_get_maxbubble { if (defined($env{'form.scantron_maxbubble'}) && $env{'form.scantron_maxbubble'}) { return $env{'form.scantron_maxbubble'}; } + my $navmap=Apache::lonnavmaps::navmap->new(); my (undef,undef,$sequence)= &Apache::lonnet::decode_symb($env{'form.selectpage'}); + my $map=$navmap->getResourceByUrl($sequence); my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0); - &Apache::lonnet::delenv('form.counter'); + + &Apache::lonxml::clear_problem_counter(); + foreach my $resource (@resources) { - my $result=&Apache::lonnet::ssi($resource->src().'?symb='.&Apache::lonnet::escape($resource->symb())); + my $result=&Apache::lonnet::ssi($resource->src(), + ('symb' => $resource->symb())); } &Apache::lonnet::delenv('scantron\.'); - my $envfile=$env{'user.environment'}; - $envfile=~/\/([^\/]+)\.id$/; - $envfile=$1; - &Apache::lonnet::transfer_profile_to_env($r->dir_config('lonIDsDir'), - $envfile); - $env{'form.scantron_maxbubble'}=$env{'form.counter'}-1; + $env{'form.scantron_maxbubble'} = + &Apache::lonxml::get_problem_counter()-1; + return $env{'form.scantron_maxbubble'}; } @@ -5353,7 +5554,8 @@ SCANTRONFORM next; } ($uname,$udom)=split(/:/,$uname); - &Apache::lonnet::delenv('form.counter'); + + &Apache::lonxml::clear_problem_counter(); &Apache::lonnet::appenv(%$scan_record); my $i=0; @@ -5381,7 +5583,7 @@ SCANTRONFORM $completedstudents{$uname}={'line'=>$line}; if (&Apache::loncommon::connection_aborted($r)) { last; } } continue { - &Apache::lonnet::delenv('form.counter'); + &Apache::lonxml::clear_problem_counter(); &Apache::lonnet::delenv('scantron\.'); } &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state); @@ -5487,7 +5689,6 @@ sub scantron_upload_scantron_data_save { sub valid_file { my ($requested_file)=@_; foreach my $filename (sort(&scantron_filenames())) { - &Apache::lonnet::logthis("$requested_file $filename"); if ($requested_file eq $filename) { return 1; } } return 0; @@ -5622,12 +5823,12 @@ GRADINGMENUJS '<input type="hidden" name="gradingMenu" value="1" />'."\n". '<input type="hidden" name="showgrading" value="yes" />'."\n"; - $result.='<table width="100%" border=0><tr><td bgcolor=#777777>'."\n". - '<table width=100% border=0><tr bgcolor="#e6ffff"><td colspan="2">'."\n". + $result.='<table width="100%" border="0"><tr><td bgcolor=#777777>'."\n". + '<table width="100%" border="0"><tr bgcolor="#e6ffff"><td colspan="2">'."\n". ' <b>Select a Grading/Viewing Option</b></td></tr>'."\n". '<tr bgcolor="#ffffe6" valign="top"><td>'."\n"; - $result.='<table width="100%" border=0>'; + $result.='<table width="100%" border="0">'; $result.='<tr bgcolor="#ffffe6" valign="top"><td>'."\n". ' '.&mt('Select Section').': <select name="section">'."\n"; if (ref($sections)) { @@ -5644,27 +5845,27 @@ GRADINGMENUJS $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'). + ($saveCmd eq 'submission' ? 'checked' : '').' /> '.'<b>'.&mt('Current Resource').':</b> '.&mt('For one or more students'). '</label> <select name="submitonly">'. '<option value="yes" '. - ($saveSub eq 'yes' ? 'selected="on"' : '').'>'.&mt('with submissions').'</option>'. + ($saveSub eq 'yes' ? 'selected="on"' : '').' />'.&mt('with submissions').'</option>'. '<option value="queued" '. - ($saveSub eq 'queued' ? 'selected="on"' : '').'>'.&mt('in grading queue').'</option>'. + ($saveSub eq 'queued' ? 'selected="on"' : '').' />'.&mt('in grading queue').'</option>'. '<option value="graded" '. - ($saveSub eq 'graded' ? 'selected="on"' : '').'>'.&mt('with ungraded submissions').'</option>'. + ($saveSub eq 'graded' ? 'selected="on"' : '').' />'.&mt('with ungraded submissions').'</option>'. '<option value="incorrect" '. - ($saveSub eq 'incorrect' ? 'selected="on"' : '').'>'.&mt('with incorrect submissions').'</option>'. + ($saveSub eq 'incorrect' ? 'selected="on"' : '').' />'.&mt('with incorrect submissions').'</option>'. '<option value="all" '. - ($saveSub eq 'all' ? 'selected="on"' : '').'>'.&mt('with any status').'</option></select></td></tr>'."\n"; + ($saveSub eq 'all' ? 'selected="on"' : '').' />'.&mt('with any status').'</option></select></td></tr>'."\n"; $result.='<tr bgcolor="#ffffe6"valign="top"><td>'. '<label><input type="radio" name="radioChoice" value="viewgrades" '. - ($saveCmd eq 'viewgrades' ? 'checked' : '').'> '. + ($saveCmd eq 'viewgrades' ? 'checked' : '').' /> '. '<b>Current Resource:</b> For all students in selected section or course</label></td></tr>'."\n"; $result.='<tr bgcolor="#ffffe6" valign="top"><td>'. '<label><input type="radio" name="radioChoice" value="pickStudentPage" '. - ($saveCmd eq 'pickStudentPage' ? 'checked' : '').'> '. + ($saveCmd eq 'pickStudentPage' ? 'checked' : '').' /> '. 'The <b>complete</b> set/page/sequence: For one student</label></td></tr>'."\n"; $result.='<tr bgcolor="#ffffe6"><td><br />'. @@ -5673,7 +5874,7 @@ GRADINGMENUJS $result.='</td><td valign="top">'; - $result.='<table width="100%" border=0>'; + $result.='<table width="100%" border="0">'; $result.='<tr bgcolor="#ffffe6"><td>'. '<input type="button" onClick="javascript:checkChoice(this.form,\'3\',\'csvform\');" value="'.&mt('Upload').'" />'. ' '.&mt('scores from file').' </td></tr>'."\n"; @@ -5687,7 +5888,7 @@ GRADINGMENUJS '<input type="button" onClick="javascript:checkChoice(this.form,\'5\',\'verify\');" value="'.&mt('Verify').'" />'. ' '.&mt('receipt').': '. &Apache::lonnet::recprefix($env{'request.course.id'}). - '-<input type="text" name="receipt" size="4" onChange="javascript:checkReceiptNo(this.form,\'OK\')">'. + '-<input type="text" name="receipt" size="4" onChange="javascript:checkReceiptNo(this.form,\'OK\')" />'. '</td></tr>'."\n"; } $result.='<tr bgcolor="#ffffe6"valign="top"><td colspan="2">'. @@ -5743,7 +5944,7 @@ sub handler { if ($#commands > 0) { &Apache::lonnet::logthis("grades got multiple commands ".join(':',@commands)); } - &send_header($request); + $request->print(&Apache::loncommon::start_page('Grading')); if ($symb eq '' && $command eq '') { if ($env{'user.adv'}) { if (($env{'form.codeone'}) && ($env{'form.codetwo'}) && @@ -5834,27 +6035,10 @@ sub handler { $request->print("Access Denied ($command)"); } } - &send_footer($request); + $request->print(&Apache::loncommon::end_page()); return ''; } -sub send_header { - my ($request)= @_; - $request->print(&Apache::lontexconvert::header()); -# $request->print(" -#<script> -#remotewindow=open('','homeworkremote'); -#remotewindow.close(); -#</script>"); - $request->print(&Apache::loncommon::bodytag('Grading')); - $request->rflush(); -} - -sub send_footer { - my ($request)= @_; - $request->print('</body></html>'); -} - 1; __END__;