Diff for /loncom/homework/grades.pm between versions 1.360 and 1.410

version 1.360, 2006/06/12 00:34:45 version 1.410, 2007/06/16 01:37:44
Line 36  use Apache::lonhtmlcommon; Line 36  use Apache::lonhtmlcommon;
 use Apache::lonnavmaps;  use Apache::lonnavmaps;
 use Apache::lonhomework;  use Apache::lonhomework;
 use Apache::loncoursedata;  use Apache::loncoursedata;
 use Apache::lonmsg qw(:user_normal_msg);  use Apache::lonmsg();
 use Apache::Constants qw(:common);  use Apache::Constants qw(:common);
 use Apache::lonlocal;  use Apache::lonlocal;
   use Apache::lonenc;
 use String::Similarity;  use String::Similarity;
 use lib '/home/httpd/lib/perl';  
 use LONCAPA;  use LONCAPA;
   
 use POSIX qw(floor);  use POSIX qw(floor);
Line 101  sub get_symb { Line 101  sub get_symb {
 sub nameUserString {  sub nameUserString {
     my ($type,$fullname,$uname,$udom) = @_;      my ($type,$fullname,$uname,$udom) = @_;
     if ($type eq 'header') {      if ($type eq 'header') {
  return '<b>&nbsp;Fullname&nbsp;</b><font color="#999999">(Username)</font>';   return '<b>&nbsp;Fullname&nbsp;</b><span class="LC_internal_info">(Username)</span>';
     } else {      } else {
  return '&nbsp;'.$fullname.'<font color="#999999">&nbsp;('.$uname.   return '&nbsp;'.$fullname.'<span class="LC_internal_info">&nbsp;('.$uname.
     ($env{'user.domain'} eq $udom ? '' : ' ('.$udom.')').')</font>';      ($env{'user.domain'} eq $udom ? '' : ' ('.$udom.')').')</span>';
     }      }
 }  }
   
Line 112  sub nameUserString { Line 112  sub nameUserString {
 #--- Indicate if a response type is coded handgraded or not. ---  #--- Indicate if a response type is coded handgraded or not. ---
 sub response_type {  sub response_type {
     my ($symb) = shift;      my ($symb) = shift;
     my (undef,undef,$url) = &Apache::lonnet::decode_symb($symb);  
     my $allkeys = &Apache::lonnet::metadata($url,'keys');      my $navmap = Apache::lonnavmaps::navmap->new();
     my %vPart;      my $res = $navmap->getBySymb($symb);
     foreach my $partid (&Apache::loncommon::get_env_multiple('form.vPart')) {      my $partlist = $res->parts();
  $vPart{$partid}=1;      my %vPart = 
     }   map { $_ => 1 } (&Apache::loncommon::get_env_multiple('form.vPart'));
     my %seen = ();      my (%response_types,%handgrade);
     my (@partlist,%handgrade,%responseType);      foreach my $part (@{ $partlist }) {
     foreach (split(/,/,&Apache::lonnet::metadata($url,'packages'))) {   next if (%vPart && !exists($vPart{$part}));
  if (/^\w+response_.*/ || /^Task_/) {  
     my ($responsetype,$part) = split(/_/,$_,2);   my @types = $res->responseType($part);
     my ($partid,$respid) = split(/_/,$part);   my @ids = $res->responseIds($part);
     if ($responsetype eq 'Task') { $respid='0'; }   for (my $i=0; $i < scalar(@ids); $i++) {
     if (&Apache::loncommon::check_if_partid_hidden($partid,$symb)) {      $response_types{$part}{$ids[$i]} = $types[$i];
  next;      $handgrade{$part.'_'.$ids[$i]} = 
     }   &Apache::lonnet::EXT('resource.'.$part.'_'.$ids[$i].
     if (%vPart && !exists($vPart{$partid})) {       '.handgrade',$symb);
  next;   }
     }      }
     $responsetype =~ s/response$//; # make it compatible w/ navmaps - should move to that!!      return ($partlist,\%handgrade,\%response_types);
     my ($value) = &Apache::lonnet::EXT('resource.'.$part.'.handgrade',$symb);  }
     $handgrade{$part} = ($value eq 'yes' ? 'yes' : 'no');   
     if (!exists($responseType{$partid})) { $responseType{$partid}={}; }  sub flatten_responseType {
     $responseType{$partid}->{$respid}=$responsetype;      my ($responseType) = @_;
     next if ($seen{$partid} > 0);      my @part_response_id =
     $seen{$partid}++;   map { 
     push @partlist,$partid;      my $part = $_;
  }      map {
     }   [$part,$_]
     return (\@partlist,\%handgrade,\%responseType);   } sort(keys(%{ $responseType->{$part} }));
    } sort(keys(%$responseType));
       return @part_response_id;
 }  }
   
 sub get_display_part {  sub get_display_part {
     my ($partID,$symb)=@_;      my ($partID,$symb)=@_;
     my $display=&Apache::lonnet::EXT('resource.'.$partID.'.display',$symb);      my $display=&Apache::lonnet::EXT('resource.'.$partID.'.display',$symb);
     if (defined($display) and $display ne '') {      if (defined($display) and $display ne '') {
  $display.= " (<font color=\"#999900\">id $partID</font>)";   $display.= " (<span class=\"LC_internal_info\">id $partID</span>)";
     } else {      } else {
  $display=$partID;   $display=$partID;
     }      }
Line 161  sub showResourceInfo { Line 163  sub showResourceInfo {
     my ($symb,$probTitle,$checkboxes) = @_;      my ($symb,$probTitle,$checkboxes) = @_;
     my $col=3;      my $col=3;
     if ($checkboxes) { $col=4; }      if ($checkboxes) { $col=4; }
     my $result ='<table border="0">'.      my $result = '<h3>'.&mt('Current Resource').': '.$probTitle.'</h3>'."\n";
  '<tr><td colspan="'.$col.'"><font size="+1"><b>'.&mt('Current Resource').': </b>'.      $result .='<table border="0">';
  $probTitle.'</font></td></tr>'."\n";  
     my ($partlist,$handgrade,$responseType) = &response_type($symb);      my ($partlist,$handgrade,$responseType) = &response_type($symb);
     my %resptype = ();      my %resptype = ();
     my $hdgrade='no';      my $hdgrade='no';
     my %partsseen;      my %partsseen;
     for my $part_resID (sort keys(%$handgrade)) {      foreach my $partID (sort keys(%$responseType)) {
  my $handgrade=$$handgrade{$part_resID};   foreach my $resID (sort keys(%{ $responseType->{$partID} })) {
  my ($partID,$resID) = split(/_/,$part_resID);      my $handgrade=$$handgrade{$partID.'_'.$resID};
  my $responsetype = $responseType->{$partID}->{$resID};      my $responsetype = $responseType->{$partID}->{$resID};
  $hdgrade = $handgrade if ($handgrade eq 'yes');      $hdgrade = $handgrade if ($handgrade eq 'yes');
  $result.='<tr>';      $result.='<tr>';
  if ($checkboxes) {      if ($checkboxes) {
     if (exists($partsseen{$partID})) {   if (exists($partsseen{$partID})) {
  $result.="<td>&nbsp;</td>";      $result.="<td>&nbsp;</td>";
     } else {   } else {
  $result.="<td><input type='checkbox' name='vPart' value='$partID' checked='on' /></td>";      $result.="<td><input type='checkbox' name='vPart' value='$partID' checked='checked' /></td>";
    }
    $partsseen{$partID}=1;
     }      }
     $partsseen{$partID}=1;      my $display_part=&get_display_part($partID,$symb);
  }      $result.='<td><b>Part: </b>'.$display_part.' <span class="LC_internal_info">'.
  my $display_part=&get_display_part($partID,$symb);   $resID.'</span></td>'.
  $result.='<td><b>Part: </b>'.$display_part.' <font color="#999999">'.   '<td><b>Type: </b>'.$responsetype.'</td></tr>';
     $resID.'</font></td>'.  
     '<td><b>Type: </b>'.$responsetype.'</td></tr>';  
 #    '<td><b>Handgrade: </b>'.$handgrade.'</td></tr>';  #    '<td><b>Handgrade: </b>'.$handgrade.'</td></tr>';
    }
     }      }
     $result.='</table>'."\n";      $result.='</table>'."\n";
     return $result,$responseType,$hdgrade,$partlist,$handgrade;      return $result,$responseType,$hdgrade,$partlist,$handgrade;
Line 214  sub get_order { Line 216  sub get_order {
 sub cleanRecord {  sub cleanRecord {
     my ($answer,$response,$symb,$partid,$respid,$record,$order,$version,      my ($answer,$response,$symb,$partid,$respid,$record,$order,$version,
  $uname,$udom) = @_;   $uname,$udom) = @_;
     my $grayFont = '<font color="#999999">';      my $grayFont = '<span class="LC_internal_info">';
     if ($response =~ /^(option|rank)$/) {      if ($response =~ /^(option|rank)$/) {
  my %answer=&Apache::lonnet::str2hash($answer);   my %answer=&Apache::lonnet::str2hash($answer);
  my %grading=&Apache::lonnet::str2hash($record->{$version."resource.$partid.$respid.submissiongrading"});   my %grading=&Apache::lonnet::str2hash($record->{$version."resource.$partid.$respid.submissiongrading"});
Line 225  sub cleanRecord { Line 227  sub cleanRecord {
     } else {      } else {
  $toprow.='<td><i>'.$answer{$foil}.'&nbsp;</i></td>';   $toprow.='<td><i>'.$answer{$foil}.'&nbsp;</i></td>';
     }      }
     $bottomrow.='<td>'.$grayFont.$foil.'</font>&nbsp;</td>';      $bottomrow.='<td>'.$grayFont.$foil.'</span>&nbsp;</td>';
  }   }
  return '<blockquote><table border="1">'.   return '<blockquote><table border="1">'.
     '<tr valign="top"><td>Answer</td>'.$toprow.'</tr>'.      '<tr valign="top"><td>Answer</td>'.$toprow.'</tr>'.
     '<tr valign="top"><td>'.$grayFont.'Option ID</font></td>'.      '<tr valign="top"><td>'.$grayFont.'Option ID</span></td>'.
     $grayFont.$bottomrow.'</tr>'.'</table></blockquote>';      $grayFont.$bottomrow.'</tr>'.'</table></blockquote>';
     } elsif ($response eq 'match') {      } elsif ($response eq 'match') {
  my %answer=&Apache::lonnet::str2hash($answer);   my %answer=&Apache::lonnet::str2hash($answer);
Line 240  sub cleanRecord { Line 242  sub cleanRecord {
     my $item=shift(@items);      my $item=shift(@items);
     if ($grading{$foil} == 1) {      if ($grading{$foil} == 1) {
  $toprow.='<td><b>'.$item.'&nbsp;</b></td>';   $toprow.='<td><b>'.$item.'&nbsp;</b></td>';
  $middlerow.='<td><b>'.$grayFont.$answer{$foil}.'&nbsp;</font></b></td>';   $middlerow.='<td><b>'.$grayFont.$answer{$foil}.'&nbsp;</span></b></td>';
     } else {      } else {
  $toprow.='<td><i>'.$item.'&nbsp;</i></td>';   $toprow.='<td><i>'.$item.'&nbsp;</i></td>';
  $middlerow.='<td><i>'.$grayFont.$answer{$foil}.'&nbsp;</font></i></td>';   $middlerow.='<td><i>'.$grayFont.$answer{$foil}.'&nbsp;</span></i></td>';
     }      }
     $bottomrow.='<td>'.$grayFont.$foil.'</font>&nbsp;</td>';      $bottomrow.='<td>'.$grayFont.$foil.'</span>&nbsp;</td>';
  }   }
  return '<blockquote><table border="1">'.   return '<blockquote><table border="1">'.
     '<tr valign="top"><td>Answer</td>'.$toprow.'</tr>'.      '<tr valign="top"><td>Answer</td>'.$toprow.'</tr>'.
     '<tr valign="top"><td>'.$grayFont.'Item ID</font></td>'.      '<tr valign="top"><td>'.$grayFont.'Item ID</span></td>'.
     $middlerow.'</tr>'.      $middlerow.'</tr>'.
     '<tr valign="top"><td>'.$grayFont.'Option ID</font></td>'.      '<tr valign="top"><td>'.$grayFont.'Option ID</span></td>'.
     $bottomrow.'</tr>'.'</table></blockquote>';      $bottomrow.'</tr>'.'</table></blockquote>';
     } elsif ($response eq 'radiobutton') {      } elsif ($response eq 'radiobutton') {
  my %answer=&Apache::lonnet::str2hash($answer);   my %answer=&Apache::lonnet::str2hash($answer);
Line 268  sub cleanRecord { Line 270  sub cleanRecord {
     } else {      } else {
  $toprow.='<td>false</td>';   $toprow.='<td>false</td>';
     }      }
     $bottomrow.='<td>'.$grayFont.$foil.'</font>&nbsp;</td>';      $bottomrow.='<td>'.$grayFont.$foil.'</span>&nbsp;</td>';
  }   }
  return '<blockquote><table border="1">'.   return '<blockquote><table border="1">'.
     '<tr valign="top"><td>Answer</td>'.$toprow.'</tr>'.      '<tr valign="top"><td>Answer</td>'.$toprow.'</tr>'.
     '<tr valign="top"><td>'.$grayFont.'Option ID</font></td>'.      '<tr valign="top"><td>'.$grayFont.'Option ID</span></td>'.
     $grayFont.$bottomrow.'</tr>'.'</table></blockquote>';      $grayFont.$bottomrow.'</tr>'.'</table></blockquote>';
     } elsif ($response eq 'essay') {      } elsif ($response eq 'essay') {
  if (! exists ($env{'form.'.$symb})) {   if (! exists ($env{'form.'.$symb})) {
Line 589  sub verifyreceipt { Line 591  sub verifyreceipt {
     my $receipt  = &Apache::lonnet::recprefix($courseid).'-'.      my $receipt  = &Apache::lonnet::recprefix($courseid).'-'.
  $env{'form.receipt'};   $env{'form.receipt'};
     $receipt     =~ s/[^\-\d]//g;      $receipt     =~ s/[^\-\d]//g;
     my $symb     = &Apache::lonnet::symbread();      my ($symb)   = &get_symb($request);
   
     my $title.='<h3><font color="#339933">Verifying Submission Receipt '.      my $title.='<h3><span class="LC_info">Verifying Submission Receipt '.
  $receipt.'</h3></font>'."\n".   $receipt.'</h3></span>'."\n".
  '<font size=+1><b>Resource: </b>'.$env{'form.probTitle'}.'</font><br /><br />'."\n";   '<h4><b>Resource: </b>'.$env{'form.probTitle'}.'</h4><br /><br />'."\n";
   
     my ($string,$contents,$matches) = ('','',0);      my ($string,$contents,$matches) = ('','',0);
     my (undef,undef,$fullname) = &getclasslist('all','0');      my (undef,undef,$fullname) = &getclasslist('all','0');
           
     my $receiptparts=0;      my $receiptparts=0;
     if ($env{"course.$courseid.receiptalg"} eq 'receipt2') { $receiptparts=1; }      if ($env{"course.$courseid.receiptalg"} eq 'receipt2' ||
    $env{"course.$courseid.receiptalg"} eq 'receipt3') { $receiptparts=1; }
     my $parts=['0'];      my $parts=['0'];
     if ($receiptparts) { ($parts)=&response_type($symb); }      if ($receiptparts) { ($parts)=&response_type($symb); }
     foreach (sort       foreach (sort 
Line 663  sub listStudents { Line 666  sub listStudents {
     $env{'form.probTitle'} = $env{'form.probTitle'} eq '' ?       $env{'form.probTitle'} = $env{'form.probTitle'} eq '' ? 
  &Apache::lonnet::gettitle($symb) : $env{'form.probTitle'};   &Apache::lonnet::gettitle($symb) : $env{'form.probTitle'};
   
     my $result='<h3><font color="#339933">&nbsp;'.$viewgrade.      my $result='<h3><span class="LC_info">&nbsp;'.$viewgrade.
  ' Submissions for a Student or a Group of Students</font></h3>';   ' Submissions for a Student or a Group of Students</span></h3>';
   
     my ($table,undef,$hdgrade,$partlist,$handgrade) = &showResourceInfo($symb,$env{'form.probTitle'},($env{'form.showgrading'} eq 'yes'));      my ($table,undef,$hdgrade,$partlist,$handgrade) = &showResourceInfo($symb,$env{'form.probTitle'},($env{'form.showgrading'} eq 'yes'));
   
Line 704  LISTJAVASCRIPT Line 707  LISTJAVASCRIPT
     &commonJSfunctions($request);      &commonJSfunctions($request);
     $request->print($result);      $request->print($result);
   
     my $checkhdgrade = ($env{'form.handgrade'} eq 'yes' && scalar(@$partlist) > 1 ) ? 'checked' : '';      my $checkhdgrade = ($env{'form.handgrade'} eq 'yes' && scalar(@$partlist) > 1 ) ? 'checked="checked"' : '';
     my $checklastsub = $checkhdgrade eq '' ? 'checked' : '';      my $checklastsub = $checkhdgrade eq '' ? 'checked="checked"' : '';
     my $gradeTable='<form action="/adm/grades" method="post" name="gradesub">'.      my $gradeTable='<form action="/adm/grades" method="post" name="gradesub">'.
  "\n".$table.   "\n".$table.
  '&nbsp;<b>View Problem Text: </b><label><input type="radio" name="vProb" value="no" checked="on" /> no </label>'."\n".   '&nbsp;<b>View Problem Text: </b><label><input type="radio" name="vProb" value="no" checked="checked" /> no </label>'."\n".
  '<label><input type="radio" name="vProb" value="yes" /> one student </label>'."\n".   '<label><input type="radio" name="vProb" value="yes" /> one student </label>'."\n".
  '<label><input type="radio" name="vProb" value="all" /> all students </label><br />'."\n".   '<label><input type="radio" name="vProb" value="all" /> all students </label><br />'."\n".
  '&nbsp;<b>View Answer: </b><label><input type="radio" name="vAns" value="no"  /> no </label>'."\n".   '&nbsp;<b>View Answer: </b><label><input type="radio" name="vAns" value="no"  /> no </label>'."\n".
  '<label><input type="radio" name="vAns" value="yes" /> one student </label>'."\n".   '<label><input type="radio" name="vAns" value="yes" /> one student </label>'."\n".
  '<label><input type="radio" name="vAns" value="all" checked="on" /> all students </label><br />'."\n".   '<label><input type="radio" name="vAns" value="all" checked="checked" /> all students </label><br />'."\n".
  '&nbsp;<b>Submissions: </b>'."\n";   '&nbsp;<b>Submissions: </b>'."\n";
     if ($env{'form.handgrade'} eq 'yes' && scalar(@$partlist) > 1) {      if ($env{'form.handgrade'} eq 'yes' && scalar(@$partlist) > 1) {
  $gradeTable.='<label><input type="radio" name="lastSub" value="hdgrade" '.$checkhdgrade.' /> essay part only </label>'."\n";   $gradeTable.='<label><input type="radio" name="lastSub" value="hdgrade" '.$checkhdgrade.' /> essay part only </label>'."\n";
Line 759  LISTJAVASCRIPT Line 762  LISTJAVASCRIPT
  'onClick="javascript:checkSelect(this.form.stuinfo);" '."\n".   'onClick="javascript:checkSelect(this.form.stuinfo);" '."\n".
  'value="Next->" /> <br />'."\n";   'value="Next->" /> <br />'."\n";
     $gradeTable.=&check_buttons();      $gradeTable.=&check_buttons();
     $gradeTable.='<label><input type="checkbox" name="checkPlag" checked="on" />Check For Plagiarism</label>';      $gradeTable.='<label><input type="checkbox" name="checkPlag" checked="checked" />Check For Plagiarism</label>';
     my ($classlist, undef, $fullname) = &getclasslist($getsec,'1');      my ($classlist, undef, $fullname) = &getclasslist($getsec,'1');
     $gradeTable.='<table border="0"><tr><td bgcolor="#777777">'.      $gradeTable.='<table border="0"><tr><td bgcolor="#777777">'.
  '<table border="0"><tr bgcolor="#e6ffff">';   '<table border="0"><tr bgcolor="#e6ffff">';
Line 876  LISTJAVASCRIPT Line 879  LISTJAVASCRIPT
     if ($ctr == 0) {      if ($ctr == 0) {
  my $num_students=(scalar(keys(%$fullname)));   my $num_students=(scalar(keys(%$fullname)));
  if ($num_students eq 0) {   if ($num_students eq 0) {
     $gradeTable='<br />&nbsp;<font color="red">There are no students currently enrolled.</font>';      $gradeTable='<br />&nbsp;<span class="LC_warning">There are no students currently enrolled.</span>';
  } else {   } else {
     my $submissions='submissions';      my $submissions='submissions';
     if ($submitonly eq 'incorrect') { $submissions = 'incorrect submissions'; }      if ($submitonly eq 'incorrect') { $submissions = 'incorrect submissions'; }
     if ($submitonly eq 'graded'   ) { $submissions = 'ungraded submissions'; }      if ($submitonly eq 'graded'   ) { $submissions = 'ungraded submissions'; }
     if ($submitonly eq 'queued'   ) { $submissions = 'queued submissions'; }      if ($submitonly eq 'queued'   ) { $submissions = 'queued submissions'; }
     $gradeTable='<br />&nbsp;<font color="red">'.      $gradeTable='<br />&nbsp;<span class="LC_warning">'.
  'No '.$submissions.' found for this resource for any students. ('.$num_students.   'No '.$submissions.' found for this resource for any students. ('.$num_students.
  ' students checked for '.$submissions.')</font><br />';   ' students checked for '.$submissions.')</span><br />';
  }   }
     } elsif ($ctr == 1) {      } elsif ($ctr == 1) {
  $gradeTable =~ s/type=checkbox/type=checkbox checked/;   $gradeTable =~ s/type=checkbox/type=checkbox checked/;
Line 948  sub processGroup { Line 951  sub processGroup {
     my @stuchecked = &Apache::loncommon::get_env_multiple('form.stuinfo');      my @stuchecked = &Apache::loncommon::get_env_multiple('form.stuinfo');
     my $total      = scalar(@stuchecked)-1;      my $total      = scalar(@stuchecked)-1;
   
     foreach (@stuchecked) {      foreach my $student (@stuchecked) {
  my ($uname,$udom,$fullname) = split(/:/);   my ($uname,$udom,$fullname) = split(/:/,$student);
  $env{'form.student'}        = $uname;   $env{'form.student'}        = $uname;
  $env{'form.userdom'}        = $udom;   $env{'form.userdom'}        = $udom;
  $env{'form.fullname'}       = $fullname;   $env{'form.fullname'}       = $fullname;
Line 1339  INNERJS Line 1342  INNERJS
   
     pDoc.write("<form action=\\"inactive\\" name=\\"msgcenter\\">");      pDoc.write("<form action=\\"inactive\\" name=\\"msgcenter\\">");
     pDoc.write("<input value=\\""+usrctr+"\\" name=\\"usrctr\\" type=\\"hidden\\">");      pDoc.write("<input value=\\""+usrctr+"\\" name=\\"usrctr\\" type=\\"hidden\\">");
     pDoc.write("<font color=\\"green\\" size=+1>&nbsp;Compose Message for \"+fullname+\"</font><br /><br />");      pDoc.write("<h3><span class=\\"LC_info\\">&nbsp;Compose Message for \"+fullname+\"</span></h3><br /><br />");
   
     pDoc.write("<table border=0 width=100%><tr><td bgcolor=\\"#777777\\">");      pDoc.write("<table border=0 width=100%><tr><td bgcolor=\\"#777777\\">");
     pDoc.write("<table border=0 width=100%><tr bgcolor=\\"#ddffff\\">");      pDoc.write("<table border=0 width=100%><tr bgcolor=\\"#ddffff\\">");
Line 1424  INNERJS Line 1427  INNERJS
     hDoc.$docopen;      hDoc.$docopen;
     hDoc.write('$start_page_highlight_central');      hDoc.write('$start_page_highlight_central');
     hDoc.write("<form action=\\"inactive\\" name=\\"hlCenter\\">");      hDoc.write("<form action=\\"inactive\\" name=\\"hlCenter\\">");
     hDoc.write("<font color=\\"green\\" size=+1>&nbsp;Keyword Highlight Options</font><br /><br />");      hDoc.write("<h3><span class=\\"LC_info\\">&nbsp;Keyword Highlight Options</span></h3><br /><br />");
   
     hDoc.write("<table border=0 width=100%><tr><td bgcolor=\\"#777777\\">");      hDoc.write("<table border=0 width=100%><tr><td bgcolor=\\"#777777\\">");
     hDoc.write("<table border=0 width=100%><tr bgcolor=\\"#ddffff\\">");      hDoc.write("<table border=0 width=100%><tr bgcolor=\\"#ddffff\\">");
Line 1470  sub get_increment { Line 1473  sub get_increment {
 #--- displays the grading box, used in essay type problem and grading by page/sequence  #--- displays the grading box, used in essay type problem and grading by page/sequence
 sub gradeBox {  sub gradeBox {
     my ($request,$symb,$uname,$udom,$counter,$partid,$record) = @_;      my ($request,$symb,$uname,$udom,$counter,$partid,$record) = @_;
     my $checkIcon = '<img src="'.$request->dir_config('lonIconsURL').      my $checkIcon = '<img alt="'.&mt('Check Mark').
    '" src="'.$request->dir_config('lonIconsURL').
  '/check.gif" height="16" border="0" />';   '/check.gif" height="16" border="0" />';
     my $wgt    = &Apache::lonnet::EXT('resource.'.$partid.'.weight',$symb,$udom,$uname);      my $wgt    = &Apache::lonnet::EXT('resource.'.$partid.'.weight',$symb,$udom,$uname);
     my $wgtmsg = ($wgt > 0 ? '(problem weight)' :       my $wgtmsg = ($wgt > 0 ? '(problem weight)' : 
   '<font color="red">problem weight assigned by computer</font>');    '<span class="LC_info">problem weight assigned by computer</span>');
     $wgt       = ($wgt > 0 ? $wgt : '1');      $wgt       = ($wgt > 0 ? $wgt : '1');
     my $score  = ($$record{'resource.'.$partid.'.awarded'} eq '' ?      my $score  = ($$record{'resource.'.$partid.'.awarded'} eq '' ?
   '' : &compute_points($$record{'resource.'.$partid.'.awarded'},$wgt));    '' : &compute_points($$record{'resource.'.$partid.'.awarded'},$wgt));
Line 1493  sub gradeBox { Line 1497  sub gradeBox {
     my $increment = &get_increment();      my $increment = &get_increment();
     $result.='<table border="0"><tr>'."\n";  # display radio buttons in a nice table 10 across      $result.='<table border="0"><tr>'."\n";  # display radio buttons in a nice table 10 across
     while ($thisweight<=$wgt) {      while ($thisweight<=$wgt) {
  $result.= '<td><nobr><label><input type="radio" name="RADVAL'.$counter.'_'.$partid.'" '.   $result.= '<td><span style="white-space: nowrap;"><label><input type="radio" name="RADVAL'.$counter.'_'.$partid.'" '.
     'onclick="javascript:writeBox(this.form,\''.$counter.'_'.$partid.'\','.      'onclick="javascript:writeBox(this.form,\''.$counter.'_'.$partid.'\','.
     $thisweight.')" value="'.$thisweight.'" '.      $thisweight.')" value="'.$thisweight.'" '.
     ($score eq $thisweight ? 'checked':'').' /> '.$thisweight."</label></nobr></td>\n";      ($score eq $thisweight ? 'checked="checked"':'').' /> '.$thisweight."</label></span></td>\n";
  $result.=(($ctr+1)%10 == 0 ? '</tr><tr>' : '');   $result.=(($ctr+1)%10 == 0 ? '</tr><tr>' : '');
         $thisweight += $increment;          $thisweight += $increment;
  $ctr++;   $ctr++;
Line 1513  sub gradeBox { Line 1517  sub gradeBox {
     $result.='<select name="GD_SEL'.$counter.'_'.$partid.'" '.      $result.='<select name="GD_SEL'.$counter.'_'.$partid.'" '.
  'onChange="javascript:clearRadBox(this.form,\''.$counter.'_'.$partid.'\')" >'."\n";   'onChange="javascript:clearRadBox(this.form,\''.$counter.'_'.$partid.'\')" >'."\n";
     if ($$record{'resource.'.$partid.'.solved'} eq 'excused') {      if ($$record{'resource.'.$partid.'.solved'} eq 'excused') {
  $result.='<option> </option>'.   $result.='<option></option>'.
     '<option selected="on">excused</option>';      '<option selected="selected">excused</option>';
     } else {      } else {
  $result.='<option selected="on"> </option>'.   $result.='<option selected="selected"></option>'.
     '<option>excused</option>';      '<option>excused</option>';
     }      }
     $result.='<option>reset status</option></select>'."\n";      $result.='<option>reset status</option></select>'."\n";
     $result.="&nbsp&nbsp\n";      $result.="&nbsp;&nbsp;\n";
     $result.='<input type="hidden" name="stores'.$counter.'_'.$partid.'" value="" />'."\n".      $result.='<input type="hidden" name="stores'.$counter.'_'.$partid.'" value="" />'."\n".
  '<input type="hidden" name="oldpts'.$counter.'_'.$partid.'" value="'.$score.'" />'."\n".   '<input type="hidden" name="oldpts'.$counter.'_'.$partid.'" value="'.$score.'" />'."\n".
  '<input type="hidden" name="solved'.$counter.'_'.$partid.'" value="'.   '<input type="hidden" name="solved'.$counter.'_'.$partid.'" value="'.
Line 1538  sub handback_box { Line 1542  sub handback_box {
     my ($symb,$uname,$udom,$counter,$partid,$record) = @_;      my ($symb,$uname,$udom,$counter,$partid,$record) = @_;
     my ($partlist,$handgrade,$responseType) = &response_type($symb);      my ($partlist,$handgrade,$responseType) = &response_type($symb);
     my (@respids);      my (@respids);
     foreach my $part_resp (sort(keys(%$handgrade))) {       my @part_response_id = &flatten_responseType($responseType);
         my ($part,$resp) = split(/_/,$part_resp);      foreach my $part_response_id (@part_response_id) {
       my ($part,$resp) = @{ $part_response_id };
         if ($part eq $partid) {          if ($part eq $partid) {
             push @respids,$resp;              push(@respids,$resp);
         }          }
     }      }
     my $result;      my $result;
Line 1551  sub handback_box { Line 1556  sub handback_box {
  next if (!@$files);   next if (!@$files);
  my $file_counter = 1;   my $file_counter = 1;
  foreach my $file (@$files) {   foreach my $file (@$files) {
     my ($file_path, $file_disp) = ($file =~ m|(.+/)(.+)$|);      if ($file =~ /\/portfolio\//) {
     my ($name,$version,$ext) = &file_name_version_ext($file_disp);             my ($file_path, $file_disp) = ($file =~ m|(.+/)(.+)$|);
     $file_disp = "$name.$ext";             my ($name,$version,$ext) = &file_name_version_ext($file_disp);
     $file = $file_path.$file_disp;             $file_disp = "$name.$ext";
     $result.=&mt('Return commented version of [_1] to student.',             $file = $file_path.$file_disp;
  '<span class="filename">'.$file_disp.'</span>');             $result.=&mt('Return commented version of [_1] to student.',
     $result.='<input type="file"   name="'.$prefix.'returndoc'.$file_counter.'" />'."\n";      '<span class="LC_filename">'.$file_disp.'</span>');
     $result.='<input type="hidden" name="'.$prefix.'origdoc'.$file_counter.'" value="'.$file.'" /><br />';             $result.='<input type="file"   name="'.$prefix.'returndoc'.$file_counter.'" />'."\n";
     $file_counter++;             $result.='<input type="hidden" name="'.$prefix.'origdoc'.$file_counter.'" value="'.$file.'" /><br />';
              $result.='(File will be uploaded when you click on Save & Next below.)<br />';
              $file_counter++;
       }
  }   }
     }      }
     return $result;          return $result;    
 }  }
   
 sub show_problem {  sub show_problem {
     my ($request,$symb,$uname,$udom,$removeform,$viewon,$mode) = @_;      my ($request,$symb,$uname,$udom,$removeform,$viewon,$mode,$form) = @_;
     my $rendered;      my $rendered;
       my %form = ((ref($form) eq 'HASH')? %{$form} : ());
     &Apache::lonxml::remember_problem_counter();      &Apache::lonxml::remember_problem_counter();
     if ($mode eq 'both' or $mode eq 'text') {      if ($mode eq 'both' or $mode eq 'text') {
  $rendered=&Apache::loncommon::get_student_view($symb,$uname,$udom,   $rendered=&Apache::loncommon::get_student_view($symb,$uname,$udom,
      $env{'request.course.id'});         $env{'request.course.id'},
          undef,\%form);
     }      }
     if ($removeform) {      if ($removeform) {
  $rendered=~s|<form(.*?)>||g;   $rendered=~s|<form(.*?)>||g;
  $rendered=~s|</form>||g;   $rendered=~s|</form>||g;
  $rendered=~s|name="submit"|name="would_have_been_submit"|g;   $rendered=~s|(<input[^>]*name\s*=\s*"?)(\w+)("?)|$1would_have_been_$2$3|g;
     }      }
     my $companswer;      my $companswer;
     if ($mode eq 'both' or $mode eq 'answer') {      if ($mode eq 'both' or $mode eq 'answer') {
  &Apache::lonxml::restore_problem_counter();   &Apache::lonxml::restore_problem_counter();
  $companswer=&Apache::loncommon::get_student_answers($symb,$uname,$udom,   $companswer=
     $env{'request.course.id'});      &Apache::loncommon::get_student_answers($symb,$uname,$udom,
       $env{'request.course.id'},
       %form);
     }      }
     if ($removeform) {      if ($removeform) {
  $companswer=~s|<form(.*?)>||g;   $companswer=~s|<form(.*?)>||g;
Line 1613  sub show_problem { Line 1625  sub show_problem {
     return $result;      return $result;
 }  }
   
   sub files_exist {
       my ($r, $symb) = @_;
       my @students = &Apache::loncommon::get_env_multiple('form.stuinfo');
   
       foreach my $student (@students) {
           my ($uname,$udom,$fullname) = split(/:/,$student);
           my %record = &Apache::lonnet::restore($symb,$env{'request.course.id'},
         $udom,$uname);
           my ($string,$timestamp)= &get_last_submission(\%record);
           foreach my $submission (@$string) {
               my ($partid,$respid) =
    ($submission =~ /^resource\.([^\.]*)\.([^\.]*)\.submission/);
               my $files=&get_submitted_files($udom,$uname,$partid,$respid,
      \%record);
               return 1 if (@$files);
           }
       }
       return 0;
   }
   
   sub download_all_link {
       my ($r,$symb) = @_;
       my $all_students = 
    join("\n", &Apache::loncommon::get_env_multiple('form.stuinfo'));
   
       my $parts =
    join("\n",&Apache::loncommon::get_env_multiple('form.vPart'));
   
       my $identifier = &Apache::loncommon::get_cgi_id();
       &Apache::lonnet::appenv('cgi.'.$identifier.'.students' => $all_students,
                               'cgi.'.$identifier.'.symb' => $symb,
                               'cgi.'.$identifier.'.parts' => $parts,);
       $r->print('<a href="/cgi-bin/multidownload.pl?'.$identifier.'">'.
         &mt('Download All Submitted Documents').'</a>');
       return
   }
   
 # --------------------------- show submissions of a student, option to grade   # --------------------------- show submissions of a student, option to grade 
 sub submission {  sub submission {
     my ($request,$counter,$total) = @_;      my ($request,$counter,$total) = @_;
Line 1626  sub submission { Line 1675  sub submission {
     if ($symb eq '') { $request->print("Unable to handle ambiguous references:."); return ''; }      if ($symb eq '') { $request->print("Unable to handle ambiguous references:."); return ''; }
   
     if (!&canview($usec)) {      if (!&canview($usec)) {
  $request->print('<font color="red">Unable to view requested student.('.   $request->print('<span class="LC_warning">Unable to view requested student.('.
  $uname.'@'.$udom.' in section '.$usec.' in course id '.   $uname.':'.$udom.' in section '.$usec.' in course id '.
  $env{'request.course.id'}.')</font>');   $env{'request.course.id'}.')</span>');
  $request->print(&show_grading_menu_form($symb));   $request->print(&show_grading_menu_form($symb));
  return;   return;
     }      }
Line 1637  sub submission { Line 1686  sub submission {
     if (!$env{'form.vProb'}) { $env{'form.vProb'} = 'yes'; }      if (!$env{'form.vProb'}) { $env{'form.vProb'} = 'yes'; }
     if (!$env{'form.vAns'}) { $env{'form.vAns'} = 'yes'; }      if (!$env{'form.vAns'}) { $env{'form.vAns'} = 'yes'; }
     my $last = ($env{'form.lastSub'} eq 'last' ? 'last' : '');      my $last = ($env{'form.lastSub'} eq 'last' ? 'last' : '');
     my $checkIcon = '<img src="'.$request->dir_config('lonIconsURL').      my $checkIcon = '<img alt="'.&mt('Check Mark').
    '" src="'.$request->dir_config('lonIconsURL').
  '/check.gif" height="16" border="0" />';   '/check.gif" height="16" border="0" />';
   
     # header info      # header info
Line 1646  sub submission { Line 1696  sub submission {
  &sub_page_kw_js($request) if ($env{'form.handgrade'} eq 'yes');   &sub_page_kw_js($request) if ($env{'form.handgrade'} eq 'yes');
  $env{'form.probTitle'} = $env{'form.probTitle'} eq '' ?    $env{'form.probTitle'} = $env{'form.probTitle'} eq '' ? 
     &Apache::lonnet::gettitle($symb) : $env{'form.probTitle'};      &Apache::lonnet::gettitle($symb) : $env{'form.probTitle'};
    if ($env{'form.handgrade'} eq 'yes' && &files_exist($request, $symb)) {
  $request->print('<h3>&nbsp;<font color="#339933">Submission Record</font></h3>'."\n".      &download_all_link($request, $symb);
  '<font size=+1>&nbsp;<b>Resource: </b>'.$env{'form.probTitle'}.'</font>'."\n");   }
    $request->print('<h3>&nbsp;<span class="LC_info">Submission Record</span></h3>'."\n".
    '<h4>&nbsp;<b>Resource: </b>'.$env{'form.probTitle'}.'</h4>'."\n");
   
  if ($env{'form.handgrade'} eq 'no') {   if ($env{'form.handgrade'} eq 'no') {
     my $checkMark='<br /><br />&nbsp;<b>Note:</b> Part(s) graded correct by the computer is marked with a '.      my $checkMark='<br /><br />&nbsp;<b>Note:</b> Part(s) graded correct by the computer is marked with a '.
Line 1749  KEYWORDS Line 1801  KEYWORDS
 # Load the other essays for similarity check  # Load the other essays for similarity check
 #  #
             my (undef,undef,$essayurl) = &Apache::lonnet::decode_symb($symb);              my (undef,undef,$essayurl) = &Apache::lonnet::decode_symb($symb);
     my ($adom,$aname,$apath)=($essayurl=~/^(\w+)\/(\w+)\/(.*)$/);      my ($adom,$aname,$apath)=($essayurl=~/^($LONCAPA::domain_re)\/($LONCAPA::username_re)\/(.*)$/);
     $apath=&escape($apath);      $apath=&escape($apath);
     $apath=~s/\W/\_/gs;      $apath=~s/\W/\_/gs;
     %oldessays=&Apache::lonnet::dump('nohist_essay_'.$apath,$adom,$aname);      %oldessays=&Apache::lonnet::dump('nohist_essay_'.$apath,$adom,$aname);
Line 1855  KEYWORDS Line 1907  KEYWORDS
     $lastsubonly.='<tr><td bgcolor="#ffffe6">'.$$string[0];       $lastsubonly.='<tr><td bgcolor="#ffffe6">'.$$string[0]; 
  } else {   } else {
     my %seenparts;      my %seenparts;
     for my $part (sort keys(%$handgrade)) {      my @part_response_id = &flatten_responseType($responseType);
  my ($partid,$respid) = split(/_/,$part);      foreach my $part (@part_response_id) {
    next if ($env{'form.lastSub'} eq 'hdgrade' 
    && $$handgrade{$$part[0].'_'.$$part[1]} ne 'yes');
   
    my ($partid,$respid) = @{ $part };
  my $display_part=&get_display_part($partid,$symb);   my $display_part=&get_display_part($partid,$symb);
  if ($env{"form.$uname:$udom:$partid:submitted_by"}) {   if ($env{"form.$uname:$udom:$partid:submitted_by"}) {
     if (exists($seenparts{$partid})) { next; }      if (exists($seenparts{$partid})) { next; }
Line 1873  KEYWORDS Line 1929  KEYWORDS
  my $responsetype = $responseType->{$partid}->{$respid};   my $responsetype = $responseType->{$partid}->{$respid};
  if (!exists($record{"resource.$partid.$respid.submission"})) {   if (!exists($record{"resource.$partid.$respid.submission"})) {
     $lastsubonly.='<tr><td bgcolor="#ffffe6"><b>Part:</b> '.      $lastsubonly.='<tr><td bgcolor="#ffffe6"><b>Part:</b> '.
  $display_part.' <font color="#999999">( ID '.$respid.   $display_part.' <span class="LC_internal_info">( ID '.$respid.
  ' )</font>&nbsp; &nbsp;'.   ' )</span>&nbsp; &nbsp;'.
  '<font color="red">Nothing submitted - no attempts</font><br /><br />';   '<span class="LC_warning">Nothing submitted - no attempts</span><br /><br />';
     next;      next;
  }   }
  foreach (@$string) {   foreach (@$string) {
     my ($partid,$respid) = /^resource\.([^\.]*)\.([^\.]*)\.submission/;      my ($partid,$respid) = /^resource\.([^\.]*)\.([^\.]*)\.submission/;
     if ($part ne ($partid.'_'.$respid)) { next; }      if (join('_',@{$part}) ne ($partid.'_'.$respid)) { next; }
     my ($ressub,$subval) = split(/:/,$_,2);      my ($ressub,$subval) = split(/:/,$_,2);
     # Similarity check      # Similarity check
     my $similar='';      my $similar='';
Line 1889  KEYWORDS Line 1945  KEYWORDS
     &most_similar($uname,$udom,$subval);      &most_similar($uname,$udom,$subval);
  if ($osim) {   if ($osim) {
     $osim=int($osim*100.0);      $osim=int($osim*100.0);
     $similar="<hr /><h3><font color=\"#FF0000\">Essay".      $similar="<hr /><h3><span class=\"LC_warning\">Essay".
  " is $osim% similar to an essay by ".   " is $osim% similar to an essay by ".
  &Apache::loncommon::plainname($oname,$odom).   &Apache::loncommon::plainname($oname,$odom).
  '</font></h3><blockquote><i>'.   '</span></h3><blockquote><i>'.
  &keywords_highlight($oessay).   &keywords_highlight($oessay).
  '</i></blockquote><hr />';   '</i></blockquote><hr />';
  }   }
Line 1900  KEYWORDS Line 1956  KEYWORDS
     my $order=&get_order($partid,$respid,$symb,$uname,$udom);      my $order=&get_order($partid,$respid,$symb,$uname,$udom);
     if ($env{'form.lastSub'} eq 'lastonly' ||       if ($env{'form.lastSub'} eq 'lastonly' || 
  ($env{'form.lastSub'} eq 'hdgrade' &&    ($env{'form.lastSub'} eq 'hdgrade' && 
  $$handgrade{$part} eq 'yes')) {   $$handgrade{$$part[0].'_'.$$part[1]} eq 'yes')) {
  my $display_part=&get_display_part($partid,$symb);   my $display_part=&get_display_part($partid,$symb);
  $lastsubonly.='<tr><td bgcolor="#ffffe6"><b>Part:</b> '.   $lastsubonly.='<tr><td bgcolor="#ffffe6"><b>Part:</b> '.
     $display_part.' <font color="#999999">( ID '.$respid.      $display_part.' <span class="LC_internal_info">( ID '.$respid.
     ' )</font>&nbsp; &nbsp;';      ' )</span>&nbsp; &nbsp;';
  my $files=&get_submitted_files($udom,$uname,$partid,$respid,\%record);   my $files=&get_submitted_files($udom,$uname,$partid,$respid,\%record);
  if (@$files) {   if (@$files) {
     $lastsubonly.='<br /><font color="red" size="1">Like all files provided by users, this file may contain virusses</font><br />';      $lastsubonly.='<br /><span class="LC_warning">Like all files provided by users, this file may contain virusses</span><br />';
     my $file_counter = 0;      my $file_counter = 0;
     foreach my $file (@$files) {      foreach my $file (@$files) {
         $file_counter ++;          $file_counter ++;
Line 1990  KEYWORDS Line 2046  KEYWORDS
     my %seen = ();      my %seen = ();
     my @partlist;      my @partlist;
     my @gradePartRespid;      my @gradePartRespid;
     for my $part_resp (sort(keys(%$handgrade))) {      my @part_response_id = &flatten_responseType($responseType);
  my ($partid,$respid) = split(/_/, $part_resp);      foreach my $part_response_id (@part_response_id) {
       my ($partid,$respid) = @{ $part_response_id };
    my $part_resp = join('_',@{ $part_response_id });
  next if ($seen{$partid} > 0);   next if ($seen{$partid} > 0);
  $seen{$partid}++;   $seen{$partid}++;
  next if ($$handgrade{$part_resp} =~ /:no$/ && $env{'form.lastSub'} =~ /^(hdgrade)$/);   next if ($$handgrade{$part_resp} ne 'yes' 
    && $env{'form.lastSub'} eq 'hdgrade');
  push @partlist,$partid;   push @partlist,$partid;
  push @gradePartRespid,$partid.'.'.$respid;   push @gradePartRespid,$partid.'.'.$respid;
  $request->print(&gradeBox($request,$symb,$uname,$udom,$counter,$partid,\%record));   $request->print(&gradeBox($request,$symb,$uname,$udom,$counter,$partid,\%record));
Line 2022  KEYWORDS Line 2081  KEYWORDS
     '<option>3</option><option>5</option>'.      '<option>3</option><option>5</option>'.
     '<option>7</option><option>10</option></select>'."\n";      '<option>7</option><option>10</option></select>'."\n";
  my $nsel = ($env{'form.NTSTU'} ne '' ? $env{'form.NTSTU'} : '1');   my $nsel = ($env{'form.NTSTU'} ne '' ? $env{'form.NTSTU'} : '1');
  $ntstu =~ s/<option>$nsel</<option selected="on">$nsel</;   $ntstu =~ s/<option>$nsel</<option selected="selected">$nsel</;
  $endform.=$ntstu.'student(s) &nbsp;&nbsp;';   $endform.=$ntstu.'student(s) &nbsp;&nbsp;';
  $endform.='<input type="button" value="Previous" '.   $endform.='<input type="button" value="Previous" '.
     'onClick="javascript:checksubmit(this.form,\'Previous\');" TARGET=_self> &nbsp;'."\n".      'onClick="javascript:checksubmit(this.form,\'Previous\');" TARGET=_self> &nbsp;'."\n".
Line 2046  sub get_last_submission { Line 2105  sub get_last_submission {
  my %lasthash=();   my %lasthash=();
  my ($version);   my ($version);
  for ($version=1;$version<=$$returnhash{'version'};$version++) {   for ($version=1;$version<=$$returnhash{'version'};$version++) {
     foreach (sort(split(/\:/,$$returnhash{$version.':keys'}))) {      foreach my $key (sort(split(/\:/,
  $lasthash{$_}=$$returnhash{$version.':'.$_};   $$returnhash{$version.':keys'}))) {
    $timestamp = scalar(localtime($$returnhash{$version.':timestamp'}));   $lasthash{$key}=$$returnhash{$version.':'.$key};
    $timestamp = 
       scalar(localtime($$returnhash{$version.':timestamp'}));
     }      }
  }   }
  foreach ((keys %lasthash)) {   foreach my $key (keys(%lasthash)) {
     if ($_ =~ /\.submission$/) {      next if ($key !~ /\.submission$/);
  my ($partid,$foo) = split(/submission$/,$_);  
  my $draft  = $lasthash{$partid.'awarddetail'} eq 'DRAFT' ?      my ($partid,$foo) = split(/submission$/,$key);
     '<font color="red">Draft Copy</font> ' : '';      my $draft  = $lasthash{$partid.'awarddetail'} eq 'DRAFT' ?
  push @string, (join(':',$_,$draft.$lasthash{$_}));   '<span class="LC_warning">Draft Copy</span> ' : '';
     }      push(@string, join(':', $key, $draft.$lasthash{$key}));
  }   }
     }      }
     @string = $string[0] eq '' ? '<font color="red">Nothing submitted - no attempts.</font>' : @string;      if (!@string) {
     return \@string,\$timestamp;   $string[0] =
       '<span class="LC_warning">Nothing submitted - no attempts.</span>';
       }
       return (\@string,\$timestamp);
 }  }
   
 #--- High light keywords, with style choosen by user.  #--- High light keywords, with style choosen by user.
Line 2071  sub keywords_highlight { Line 2135  sub keywords_highlight {
     my $styleon   = $env{'form.kwstyle'} eq ''  ? '' : $env{'form.kwstyle'};      my $styleon   = $env{'form.kwstyle'} eq ''  ? '' : $env{'form.kwstyle'};
     (my $styleoff = $styleon) =~ s/\</\<\//;      (my $styleoff = $styleon) =~ s/\</\<\//;
     my @keylist   = split(/[,\s+]/,$env{'form.keywords'});      my @keylist   = split(/[,\s+]/,$env{'form.keywords'});
     foreach (@keylist) {      foreach my $keyword (@keylist) {
  $string =~ s/\b\Q$_\E(\b|\.)/<font color\=$env{'form.kwclr'} $size\>$styleon$_$styleoff<\/font>/gi;   $string =~ s/\b\Q$keyword\E(\b|\.)/<font color\=$env{'form.kwclr'} $size\>$styleon$keyword$styleoff<\/font>/gi;
     }      }
     return $string;      return $string;
 }  }
Line 2098  sub processHandGrade { Line 2162  sub processHandGrade {
  next;   next;
     }      }
     if ($errorflag eq 'not_allowed') {      if ($errorflag eq 'not_allowed') {
  $request->print("<font color=\"red\">Not allowed to modify grades for $uname:$udom</font>");   $request->print("<span class=\"LC_warning\">Not allowed to modify grades for $uname:$udom</span>");
  $ctr++;   $ctr++;
  next;   next;
     }      }
     my $includemsg = $env{'form.includemsg'.$ctr};      my $includemsg = $env{'form.includemsg'.$ctr};
     my ($subject,$message,$msgstatus) = ('','','');      my ($subject,$message,$msgstatus) = ('','','');
               my $restitle = &Apache::lonnet::gettitle($symb);
               my $encrypturl=&Apache::lonnet::EXT('resource.0.encrypturl',
                                                   $symb,$udom,$uname);
               my ($feedurl,$baseurl,$showsymb,$messagetail);
               $feedurl = &Apache::lonnet::clutter($url);
               if ($encrypturl =~ /^yes$/i) {
                   $baseurl = &Apache::lonenc::encrypted($feedurl,1);
                   $showsymb = &Apache::lonenc::encrypted($symb,1);
               } else {
                   $baseurl = $feedurl;
                   $showsymb = $symb;
               }
     if ($includemsg =~ /savemsg|newmsg\Q$ctr\E/) {      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'); }   unless ($subject=~/\w/) { $subject=&mt('Grading Feedback'); }
    $subject.=' ['.$restitle.']';
  my (@msgnum) = split(/,/,$includemsg);   my (@msgnum) = split(/,/,$includemsg);
  foreach (@msgnum) {   foreach (@msgnum) {
     $message.=$env{'form.'.$_} if ($_ =~ /savemsg|newmsg/ && $_ ne '');      $message.=$env{'form.'.$_} if ($_ =~ /savemsg|newmsg/ && $_ ne '');
Line 2114  sub processHandGrade { Line 2191  sub processHandGrade {
  $message =&Apache::lonfeedback::clear_out_html($message);   $message =&Apache::lonfeedback::clear_out_html($message);
  if ($env{'form.withgrades'.$ctr}) {   if ($env{'form.withgrades'.$ctr}) {
     $message.="\n\nPoint".($pts > 1 ? 's':'').' awarded = '.$pts.' out of '.$wgt;      $message.="\n\nPoint".($pts > 1 ? 's':'').' awarded = '.$pts.' out of '.$wgt;
     $message.=" for <a href=\"".      $messagetail = " for <a href=\"".
     &Apache::lonnet::clutter($url).                     $baseurl."?symb=$showsymb\">$env{'form.probTitle'}</a>";
     "?symb=$symb\">$env{'form.probTitle'}</a>";   }
  }   $msgstatus = 
  $msgstatus = &Apache::lonmsg::user_normal_msg($uname,$udom,                      &Apache::lonmsg::user_normal_msg($uname,$udom,$subject,
       $subject.' ['.       $message.$messagetail,
       &Apache::lonnet::declutter($url).']',$message);                                                       undef,$baseurl,undef,
  $request->print('<br />'.&mt('Sending message to [_1]@[_2]',$uname,$udom).': '.                                                       undef,undef,$showsymb,
                                                        $restitle);
    $request->print('<br />'.&mt('Sending message to [_1]:[_2]',$uname,$udom).': '.
  $msgstatus);   $msgstatus);
     }      }
     if ($env{'form.collaborator'.$ctr}) {      if ($env{'form.collaborator'.$ctr}) {
Line 2133  sub processHandGrade { Line 2212  sub processHandGrade {
     &saveHandGrade($request,$symb,$collaborator,$udom,$ctr,      &saveHandGrade($request,$symb,$collaborator,$udom,$ctr,
    $env{'form.unamedom'.$ctr},$part);     $env{'form.unamedom'.$ctr},$part);
  if ($errorflag eq 'not_allowed') {   if ($errorflag eq 'not_allowed') {
     $request->print("<font color=\"red\">Not allowed to modify grades for $collaborator:$udom</font>");      $request->print("<span class=\"LC_error\">".&mt('Not allowed to modify grades for [_1]',"$collaborator:$udom")."</span>");
     next;      next;
  } else {   } else {
     if ($message ne '') {      if ($message ne '') {
  $msgstatus = &Apache::lonmsg::user_normal_msg($collaborator,$udom,$env{'form.msgsub'},$message);                                  $encrypturl=
                                     &Apache::lonnet::EXT('resource.0.encrypturl',
                                                          $symb,$udom,$collaborator);
                                   if ($encrypturl =~ /^yes$/i) {
                                       $baseurl = &Apache::lonenc::encrypted($feedurl,1);
                                       $showsymb = &Apache::lonenc::encrypted($symb,1);
                                   } else {
                                       $baseurl = $feedurl;
                                       $showsymb = $symb;
                                   }
                                   if ($env{'form.withgrades'.$ctr}) {
                                       $messagetail = " for <a href=\"".
                                       $baseurl."?symb=$showsymb\">$env{'form.probTitle'}</a>";
   
                                   }
    $msgstatus = 
                                       &Apache::lonmsg::user_normal_msg($collaborator,$udom,$subject,$message.$messagetail,undef,$baseurl,undef,undef,undef,$showsymb,$restitle);
     }      }
  }   }
     }      }
Line 2296  sub processHandGrade { Line 2391  sub processHandGrade {
  $ctr++;   $ctr++;
     }      }
     if ($total < 0) {      if ($total < 0) {
  my $the_end = '<h3><font color="red">LON-CAPA User Message</font></h3><br />'."\n";   my $the_end = '<h3><span class="LC_info">LON-CAPA User Message</span></h3><br />'."\n";
  $the_end.='<b>Message: </b> No more students for this section or class.<br /><br />'."\n";   $the_end.='<b>Message: </b> No more students for this section or class.<br /><br />'."\n";
  $the_end.='Click on the button below to return to the grading menu.<br /><br />'."\n";   $the_end.='Click on the button below to return to the grading menu.<br /><br />'."\n";
  $the_end.=&show_grading_menu_form($symb);   $the_end.=&show_grading_menu_form($symb);
Line 2329  sub saveHandGrade { Line 2424  sub saveHandGrade {
  if (exists($record{'resource.'.$new_part.'.awarded'})) {   if (exists($record{'resource.'.$new_part.'.awarded'})) {
     $newrecord{'resource.'.$new_part.'.awarded'} = '';      $newrecord{'resource.'.$new_part.'.awarded'} = '';
  }   }
     $newrecord{'resource.'.$new_part.'.regrader'}="$env{'user.name'}:$env{'user.domain'}";          $newrecord{'resource.'.$new_part.'.regrader'}="$env{'user.name'}:$env{'user.domain'}";
     }      }
  } elsif ($dropMenu eq 'reset status'   } elsif ($dropMenu eq 'reset status'
  && exists($record{'resource.'.$new_part.'.solved'})) { #don't bother if no old records -> no attempts   && exists($record{'resource.'.$new_part.'.solved'})) { #don't bother if no old records -> no attempts
Line 2389  sub saveHandGrade { Line 2484  sub saveHandGrade {
     }      }
     $newrecord{'resource.'.$new_part.'.regrader'}=      $newrecord{'resource.'.$new_part.'.regrader'}=
  "$env{'user.name'}:$env{'user.domain'}";   "$env{'user.name'}:$env{'user.domain'}";
             &handback_files($request,$symb,$stuname,$domain,$newflg,$new_part,\%newrecord);  
  }   }
  # unless problem has been graded, set flag to version the submitted files   # unless problem has been graded, set flag to version the submitted files
  unless ($record{'resource.'.$new_part.'.solved'} =~ /^correct_/  ||    unless ($record{'resource.'.$new_part.'.solved'} =~ /^correct_/  || 
Line 2404  sub saveHandGrade { Line 2498  sub saveHandGrade {
   
     if (%newrecord) {      if (%newrecord) {
         if (@version_parts) {          if (@version_parts) {
             my @changed_keys = &version_portfiles(\%record, \@parts_graded, $env{'request.course.id'}, $symb, $domain, $stuname, \@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};      @newrecord{@changed_keys} = @record{@changed_keys};
       foreach my $new_part (@version_parts) {
    &handback_files($request,$symb,$stuname,$domain,$newflg,
    $new_part,\%newrecord);
       }
         }          }
  &Apache::lonnet::cstore(\%newrecord,$symb,   &Apache::lonnet::cstore(\%newrecord,$symb,
  $env{'request.course.id'},$domain,$stuname);   $env{'request.course.id'},$domain,$stuname);
  my @ungraded_parts;   &check_and_remove_from_queue(\@parts,\%record,\%newrecord,$symb,
  foreach my $part (@parts) {       $cdom,$cnum,$domain,$stuname);
     if ( !defined($record{'resource.'.$part.'.awarded'})  
  && !defined($newrecord{'resource.'.$part.'.awarded'}) ) {  
  push(@ungraded_parts, $part);  
     }  
  }  
  if ( !@ungraded_parts ) {  
     &Apache::bridgetask::remove_from_queue('gradingqueue',$symb,$cdom,  
    $cnum,$domain,$stuname);  
  }  
     }      }
     if ($aggregateflag) {      if ($aggregateflag) {
         &Apache::lonnet::cinc('nohist_resourcetracker',\%aggregate,          &Apache::lonnet::cinc('nohist_resourcetracker',\%aggregate,
Line 2428  sub saveHandGrade { Line 2518  sub saveHandGrade {
     return ('',$pts,$wgt);      return ('',$pts,$wgt);
 }  }
   
   sub check_and_remove_from_queue {
       my ($parts,$record,$newrecord,$symb,$cdom,$cnum,$domain,$stuname) = @_;
       my @ungraded_parts;
       foreach my $part (@{$parts}) {
    if (    $record->{   'resource.'.$part.'.awarded'} eq ''
        && $record->{   'resource.'.$part.'.solved' } ne 'excused'
        && $newrecord->{'resource.'.$part.'.awarded'} eq ''
        && $newrecord->{'resource.'.$part.'.solved' } ne 'excused'
    ) {
       push(@ungraded_parts, $part);
    }
       }
       if ( !@ungraded_parts ) {
    &Apache::bridgetask::remove_from_queue('gradingqueue',$symb,$cdom,
          $cnum,$domain,$stuname);
       }
   }
   
 sub handback_files {  sub handback_files {
     my ($request,$symb,$stuname,$domain,$newflg,$new_part,$newrecord) = @_;      my ($request,$symb,$stuname,$domain,$newflg,$new_part,$newrecord) = @_;
     my $portfolio_root = &propath($domain,$stuname).'/userfiles/portfolio';      my $portfolio_root = &propath($domain,$stuname).'/userfiles/portfolio';
     my ($partlist,$handgrade,$responseType) = &response_type($symb);      my ($partlist,$handgrade,$responseType) = &response_type($symb);
         foreach my $part_resp (sort(keys(%$handgrade))) {  
             my ($part_id, $resp_id) = split(/_/,$part_resp);      my @part_response_id = &flatten_responseType($responseType);
       foreach my $part_response_id (@part_response_id) {
       my ($part_id,$resp_id) = @{ $part_response_id };
    my $part_resp = join('_',@{ $part_response_id });
             if (($env{'form.'.$newflg.'_'.$part_resp.'_returndoc1'}) && ($new_part == $part_id)) {              if (($env{'form.'.$newflg.'_'.$part_resp.'_returndoc1'}) && ($new_part == $part_id)) {
                 # if multiple files are uploaded names will be 'returndoc2','returndoc3'                  # if multiple files are uploaded names will be 'returndoc2','returndoc3'
                 my $file_counter = 1;                  my $file_counter = 1;
    my $file_msg;
                 while ($env{'form.'.$newflg.'_'.$part_resp.'_returndoc'.$file_counter}) {                  while ($env{'form.'.$newflg.'_'.$part_resp.'_returndoc'.$file_counter}) {
                     my $fname=$env{'form.'.$newflg.'_'.$part_resp.'_returndoc'.$file_counter.'.filename'};                      my $fname=$env{'form.'.$newflg.'_'.$part_resp.'_returndoc'.$file_counter.'.filename'};
                     my ($directory,$answer_file) =                       my ($directory,$answer_file) = 
Line 2446  sub handback_files { Line 2558  sub handback_files {
     my ($portfolio_path) = ($directory =~ /^.+$stuname\/portfolio(.*)/);      my ($portfolio_path) = ($directory =~ /^.+$stuname\/portfolio(.*)/);
     my @dir_list = &Apache::lonnet::dirlist($portfolio_path,$domain,$stuname,$portfolio_root);      my @dir_list = &Apache::lonnet::dirlist($portfolio_path,$domain,$stuname,$portfolio_root);
     my $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, $stuname, $portfolio_path, $answer_file, $version);  
                     $$newrecord{"resource.$new_part.$resp_id.handback"} = $new_answer;  
                     $version++;  
                     # fix file name                      # fix file name
                     my ($save_file_name) = (($directory.$answer_name.".$version.".$answer_ext) =~ /^.+\/${stuname}\/(.*)/);                      my ($save_file_name) = (($directory.$answer_name.".$version.".$answer_ext) =~ /^.+\/${stuname}\/(.*)/);
                     my $result=&Apache::lonnet::finishuserfileupload($stuname,$domain,                      my $result=&Apache::lonnet::finishuserfileupload($stuname,$domain,
                                            $newflg.'_'.$part_resp.'_returndoc'.$file_counter,                                             $newflg.'_'.$part_resp.'_returndoc'.$file_counter,
                                            $save_file_name);                                             $save_file_name);
                     if ($result !~ m|^/uploaded/|) {                      if ($result !~ m|^/uploaded/|) {
                         $request->print('<font color="red"> An errror occured ('.$result.                          $request->print('<span class="LC_error">An error occurred ('.$result.
                         ') while trying to upload '.$newflg.'_'.$part_resp.'_returndoc'.$file_counter.'</font><br />');                          ') while trying to upload '.$newflg.'_'.$part_resp.'_returndoc'.$file_counter.'</span><br />');
                     } else {                      } else {
                         # mark the file as read only                          # mark the file as read only
                         my @files = ($save_file_name);                          my @files = ($save_file_name);
                         my @what = ($symb,'handback');                          my @what = ($symb,$env{'request.course.id'},'handback');
                         &Apache::lonnet::mark_as_readonly($domain,$stuname,\@files,\@what);                          &Apache::lonnet::mark_as_readonly($domain,$stuname,\@files,\@what);
                         my $subject = "File Handed Back by Instructor ";   if (exists($$newrecord{"resource.$new_part.$resp_id.handback"})) {
                         my $message = "A file has been returned that was originally submitted in reponse to: <br />";      $$newrecord{"resource.$new_part.$resp_id.handback"}.=',';
                         $message .= "<strong>".&Apache::lonnet::gettitle($symb)."</strong><br />";   }
                         $message .= " The returned file is named: <br /><strong>".$save_file_name."</strong><br />";                          $$newrecord{"resource.$new_part.$resp_id.handback"} .= $save_file_name;
                         $message .= " and can be found in your portfolio space.";   $file_msg.= "\n".'<br /><span class="LC_filename"><a href="/uploaded/'."$domain/$stuname/".$save_file_name.'">'.$save_file_name."</a></span><br />";
                         &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("<br />".$fname." will be the uploaded file name");
                     $request->print(" ".$env{'form.'.$newflg.'_'.$part_resp.'_origdoc'.$file_counter});                      $request->print(" ".$env{'form.'.$newflg.'_'.$part_resp.'_origdoc'.$file_counter});
                     $file_counter++;                      $file_counter++;
                 }                  }
    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(s) are named: '. $file_msg;
    $message .= " and can be found in your portfolio space.";
    my $url = (&Apache::lonnet::decode_symb($symb))[2];
    my $feedurl = &Apache::lonnet::clutter($url);
                   my $encrypturl=&Apache::lonnet::EXT('resource.0.encrypturl',
                                                       $symb,$domain,$stuname);
                   my ($baseurl,$showsymb);
                   if ($encrypturl =~ /^yes$/i) {
                       $baseurl = &Apache::lonenc::encrypted($feedurl,1);
                       $showsymb = &Apache::lonenc::encrypted($symb,1);
                   } else {
                       $baseurl = $feedurl;
                       $showsymb = $symb;
                   }
                   my $restitle = &Apache::lonnet::gettitle($symb);
    my $msgstatus = 
                      &Apache::lonmsg::user_normal_msg($stuname,$domain,$subject.
    ' (File Returned) ['.$restitle.']',$message,undef,
                            $baseurl,undef,undef,undef,$showsymb,$restitle);
             }              }
         }          }
     return;      return;
Line 2566  sub version_portfiles { Line 2695  sub version_portfiles {
         my $new_portfiles;          my $new_portfiles;
         if ($key =~ /^resource\.($version_parts)\./ && $key =~ /\.portfiles$/ ) {          if ($key =~ /^resource\.($version_parts)\./ && $key =~ /\.portfiles$/ ) {
             my @versioned_portfiles;              my @versioned_portfiles;
             my @portfiles = split(/,/,$$record{$key});              my @portfiles = split(/\s*,\s*/,$$record{$key});
             foreach my $file (@portfiles) {              foreach my $file (@portfiles) {
                 &Apache::lonnet::unmark_as_readonly($domain,$stu_name,[$symb,$env{'request.course.id'}],$file);                  &Apache::lonnet::unmark_as_readonly($domain,$stu_name,[$symb,$env{'request.course.id'}],$file);
                 my ($directory,$answer_file) =($file =~ /^(.*?)([^\/]*)$/);                  my ($directory,$answer_file) =($file =~ /^(.*?)([^\/]*)$/);
Line 2578  sub version_portfiles { Line 2707  sub version_portfiles {
                 if ($new_answer ne 'problem getting file') {                  if ($new_answer ne 'problem getting file') {
                     push(@versioned_portfiles, $directory.$new_answer);                      push(@versioned_portfiles, $directory.$new_answer);
                     &Apache::lonnet::mark_as_readonly($domain,$stu_name,                      &Apache::lonnet::mark_as_readonly($domain,$stu_name,
                         ['/portfolio'.$directory.$new_answer],                          [$directory.$new_answer],
                         [$symb,$env{'request.course.id'},'graded']);                          [$symb,$env{'request.course.id'},'graded']);
                 }                  }
             }              }
Line 2832  sub viewgrades { Line 2961  sub viewgrades {
                  $env{'course.'.$env{'request.course.id'}.'.domain'});                   $env{'course.'.$env{'request.course.id'}.'.domain'});
     &Apache::lonnet::clear_EXT_cache_status();      &Apache::lonnet::clear_EXT_cache_status();
   
     my $result='<h3><font color="#339933">'.&mt('Manual Grading').'</font></h3>';      my $result='<h3><span class="LC_info">'.&mt('Manual Grading').'</span></h3>';
     $result.='<font size=+1><b>Current Resource: </b>'.$env{'form.probTitle'}.'</font>'."\n";      $result.='<h4><b>Current Resource: </b>'.$env{'form.probTitle'}.'</h4>'."\n";
   
     #view individual student submission form - called using Javascript viewOneStudent      #view individual student submission form - called using Javascript viewOneStudent
     $result.=&jscriptNform($symb);      $result.=&jscriptNform($symb);
Line 2860  sub viewgrades { Line 2989  sub viewgrades {
  '<table border=0><tr bgcolor="#ffffdd"><td>';   '<table border=0><tr bgcolor="#ffffdd"><td>';
     #radio buttons/text box for assigning points for a section or class.      #radio buttons/text box for assigning points for a section or class.
     #handles different parts of a problem      #handles different parts of a problem
     my ($partlist,$handgrade) = &response_type($symb);      my ($partlist,$handgrade,$responseType) = &response_type($symb);
     my %weight = ();      my %weight = ();
     my $ctsparts = 0;      my $ctsparts = 0;
     $result.='<table border="0">';      $result.='<table border="0">';
     my %seen = ();      my %seen = ();
     for (sort keys(%$handgrade)) {      my @part_response_id = &flatten_responseType($responseType);
  my ($partid,$respid) = split (/_/,$_,2);      foreach my $part_response_id (@part_response_id) {
       my ($partid,$respid) = @{ $part_response_id };
    my $part_resp = join('_',@{ $part_response_id });
  next if $seen{$partid};   next if $seen{$partid};
  $seen{$partid}++;   $seen{$partid}++;
  my $handgrade=$$handgrade{$_};   my $handgrade=$$handgrade{$part_resp};
  my $wgt = &Apache::lonnet::EXT('resource.'.$partid.'.weight',$symb);   my $wgt = &Apache::lonnet::EXT('resource.'.$partid.'.weight',$symb);
  $weight{$partid} = $wgt eq '' ? '1' : $wgt;   $weight{$partid} = $wgt eq '' ? '1' : $wgt;
   
Line 2896  sub viewgrades { Line 3027  sub viewgrades {
  $result.= '</td><td><select name="SELVAL_'.$partid.'"'.   $result.= '</td><td><select name="SELVAL_'.$partid.'"'.
     'onChange="javascript:writeRadText(\''.$partid.'\','.      'onChange="javascript:writeRadText(\''.$partid.'\','.
  $weight{$partid}.')"> '.   $weight{$partid}.')"> '.
     '<option selected="on"> </option>'.      '<option selected="selected"> </option>'.
     '<option>excused</option>'.      '<option>excused</option>'.
     '<option>reset status</option></select></td>'.      '<option>reset status</option></select></td>'.
             '<td><label><input type="checkbox" name="FORCE_'.$partid.'" /> Override "Correct"</label></td></tr>'."\n";              '<td><label><input type="checkbox" name="FORCE_'.$partid.'" /> Override "Correct"</label></td></tr>'."\n";
Line 2904  sub viewgrades { Line 3035  sub viewgrades {
     }      }
     $result.='</table>'.'</td></tr></table>'.'</td></tr></table>'."\n".      $result.='</table>'.'</td></tr></table>'.'</td></tr></table>'."\n".
  '<input type="hidden" name="totalparts" value="'.$ctsparts.'" />';   '<input type="hidden" name="totalparts" value="'.$ctsparts.'" />';
     $result.='<input type="button" value="Reset" '.      $result.='<input type="button" value="Revert to Default" '.
  'onClick="javascript:resetEntry('.$ctsparts.');" TARGET=_self>';   'onClick="javascript:resetEntry('.$ctsparts.');" TARGET=_self>';
   
     #table listing all the students in a section/class      #table listing all the students in a section/class
Line 2959  sub viewgrades { Line 3090  sub viewgrades {
  'onClick="javascript:submit();" TARGET=_self /></form>'."\n";   'onClick="javascript:submit();" TARGET=_self /></form>'."\n";
     if (scalar(%$fullname) eq 0) {      if (scalar(%$fullname) eq 0) {
  my $colspan=3+scalar(@parts);   my $colspan=3+scalar(@parts);
  $result='<font color="red">There are no students in section "'.$env{'form.section'}.   $result='<span class="LC_warning">There are no students in section "'.$env{'form.section'}.
     '" with enrollment status "'.$env{'form.Status'}.'" to modify or grade.</font>';      '" with enrollment status "'.$env{'form.Status'}.'" to modify or grade.</span>';
     }      }
     $result.=&show_grading_menu_form($symb);      $result.=&show_grading_menu_form($symb);
     return $result;      return $result;
Line 2977  sub viewstudentgrade { Line 3108  sub viewstudentgrade {
  "\n".$ctr.'&nbsp;</td><td>&nbsp;'.   "\n".$ctr.'&nbsp;</td><td>&nbsp;'.
  '<a href="javascript:viewOneStudent(\''.$uname.'\',\''.$udom.   '<a href="javascript:viewOneStudent(\''.$uname.'\',\''.$udom.
  '\')"; TARGET=_self>'.$fullname.'</a> '.   '\')"; TARGET=_self>'.$fullname.'</a> '.
  '<font color="#999999">('.$uname.($env{'user.domain'} eq $udom ? '' : ':'.$udom).')</font></td>'."\n";   '<span class="LC_internal_info">('.$uname.($env{'user.domain'} eq $udom ? '' : ':'.$udom).')</span></td>'."\n";
     $student=~s/:/_/; # colon doen't work in javascript for names      $student=~s/:/_/; # colon doen't work in javascript for names
     foreach my $apart (@$parts) {      foreach my $apart (@$parts) {
  my ($part,$type) = &split_part_type($apart);   my ($part,$type) = &split_part_type($apart);
Line 3014  sub viewstudentgrade { Line 3145  sub viewstudentgrade {
     $result.='&nbsp;<select name="'.      $result.='&nbsp;<select name="'.
  'GD_'.$student.'_'.$part.'_solved" '.   'GD_'.$student.'_'.$part.'_solved" '.
  'onChange="javascript:changeOneScore(\''.$part.'\',\''.$student.'\')" >'."\n";   'onChange="javascript:changeOneScore(\''.$part.'\',\''.$student.'\')" >'."\n";
     $result.= (($status eq 'excused') ? '<option> </option><option selected="on">excused</option>'       $result.= (($status eq 'excused') ? '<option> </option><option selected="selected">excused</option>' 
  : '<option selected="on"> </option><option>excused</option>')."\n";   : '<option selected="selected"> </option><option>excused</option>')."\n";
     $result.='<option>reset status</option>';      $result.='<option>reset status</option>';
     $result.="</select>&nbsp;</td>\n";      $result.="</select>&nbsp;</td>\n";
  } else {   } else {
Line 3037  sub editgrades { Line 3168  sub editgrades {
     my ($request) = @_;      my ($request) = @_;
   
     my $symb=&get_symb($request);      my $symb=&get_symb($request);
     my $title='<h3><font color="#339933">Current Grade Status</font></h3>';      my $title='<h3><span class="LC_info">Current Grade Status</span></h3>';
     $title.='<font size=+1><b>Current Resource: </b>'.$env{'form.probTitle'}.'</font><br />'."\n";      $title.='<h4><b>Current Resource: </b>'.$env{'form.probTitle'}.'</h4><br />'."\n";
     $title.='<font size=+1><b>Section: </b>'.$env{'form.section'}.'</font>'."\n";      $title.='<h4><b>Section: </b>'.$env{'form.section'}.'</h4>'."\n";
   
     my $result= '<table border="0"><tr><td bgcolor="#777777">'."\n";      my $result= '<table border="0"><tr><td bgcolor="#777777">'."\n";
     $result.= '<table border="0"><tr bgcolor="#deffff">'.      $result.= '<table border="0"><tr bgcolor="#deffff">'.
Line 3107  sub editgrades { Line 3238  sub editgrades {
  my $usec=$classlist->{"$uname:$udom"}[5];   my $usec=$classlist->{"$uname:$udom"}[5];
  if (!&canmodify($usec)) {   if (!&canmodify($usec)) {
     my $numcols=scalar(@partid)*4+2;      my $numcols=scalar(@partid)*4+2;
     $noupdate.=$line."<td colspan=\"$numcols\"><font color=\"red\">Not allowed to modify student</font></td></tr>";      $noupdate.=$line."<td colspan=\"$numcols\"><span class=\"LC_warning\">Not allowed to modify student</span></td></tr>";
     next;      next;
  }   }
         my %aggregate = ();          my %aggregate = ();
Line 3342  sub csvuploadmap_header { Line 3473  sub csvuploadmap_header {
     my $ignore=&mt('Ignore First Line');      my $ignore=&mt('Ignore First Line');
     $request->print(<<ENDPICK);      $request->print(<<ENDPICK);
 <form method="post" enctype="multipart/form-data" action="/adm/grades" name="gradesupload">  <form method="post" enctype="multipart/form-data" action="/adm/grades" name="gradesupload">
 <h3><font color="#339933">Uploading Class Grades</font></h3>  <h3><span class="LC_info">Uploading Class Grades</span></h3>
 $result  $result
 <hr />  <hr />
 <h3>Identify fields</h3>  <h3>Identify fields</h3>
Line 3428  sub upcsvScores_form { Line 3559  sub upcsvScores_form {
     $result.=$table;      $result.=$table;
     $result.='<br /><table width="100%" border="0"><tr><td bgcolor="#777777">'."\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.='<table width="100%" border="0"><tr bgcolor="#e6ffff"><td>'."\n";
     $result.='&nbsp;<b>Specify a file containing the class scores for current resource'.      $result.='&nbsp;<b>'.&mt('Specify a file containing the class scores for current resource').
  '.</b></td></tr>'."\n";   '.</b></td></tr>'."\n";
     $result.='<tr bgcolor=#ffffe6><td>'."\n";      $result.='<tr bgcolor=#ffffe6><td>'."\n";
       my $upload=&mt("Upload Scores");
     my $upfile_select=&Apache::loncommon::upfile_select_html();      my $upfile_select=&Apache::loncommon::upfile_select_html();
     my $ignore=&mt('Ignore First Line');      my $ignore=&mt('Ignore First Line');
     $result.=<<ENDUPFORM;      $result.=<<ENDUPFORM;
Line 3440  sub upcsvScores_form { Line 3572  sub upcsvScores_form {
 <input type="hidden" name="probTitle" value="$env{'form.probTitle'}" />  <input type="hidden" name="probTitle" value="$env{'form.probTitle'}" />
 <input type="hidden" name="saveState"  value="$env{'form.saveState'}" />  <input type="hidden" name="saveState"  value="$env{'form.saveState'}" />
 $upfile_select  $upfile_select
 <br /><input type="button" onClick="javascript:checkUpload(this.form);" value="Upload Scores" />  <br /><input type="button" onClick="javascript:checkUpload(this.form);" value="$upload" />
 <label><input type="checkbox" name="noFirstLine" />$ignore</label>  <label><input type="checkbox" name="noFirstLine" />$ignore</label>
 </form>  </form>
 ENDUPFORM  ENDUPFORM
     $result.='</td></tr></table>'."\n";      $result.=&Apache::loncommon::help_open_topic("Course_Convert_To_CSV",
                              &mt("How do I create a CSV file from a spreadsheet"))
       .'</td></tr></table>'."\n";
     $result.='</td></tr></table><br /><br />'."\n";      $result.='</td></tr></table><br /><br />'."\n";
     $result.=&show_grading_menu_form($symb);      $result.=&show_grading_menu_form($symb);
     return $result;      return $result;
Line 3502  sub csvuploadoptions { Line 3636  sub csvuploadoptions {
     my $ignore=&mt('Ignore First Line');      my $ignore=&mt('Ignore First Line');
     $request->print(<<ENDPICK);      $request->print(<<ENDPICK);
 <form method="post" enctype="multipart/form-data" action="/adm/grades" name="gradesupload">  <form method="post" enctype="multipart/form-data" action="/adm/grades" name="gradesupload">
 <h3><font color="#339933">Uploading Class Grade Options</font></h3>  <h3><span class="LC_info">Uploading Class Grade Options</span></h3>
 <input type="hidden" name="command"    value="csvuploadassign" />  <input type="hidden" name="command"    value="csvuploadassign" />
 <!--  <!--
 <p>  <p>
Line 3636  sub csvuploadassign { Line 3770  sub csvuploadassign {
  $grades{$store_key}=$entries{$fields{$dest}};   $grades{$store_key}=$entries{$fields{$dest}};
     }      }
  }   }
  if (! %grades) { push(@skipped,"$username:$domain no data to store"); }   if (! %grades) { push(@skipped,"$username:$domain no data to save"); }
  $grades{"resource.regrader"}="$env{'user.name'}:$env{'user.domain'}";   $grades{"resource.regrader"}="$env{'user.name'}:$env{'user.domain'}";
 # &Apache::lonnet::logthis(" storing ".(join('-',%grades)));  # &Apache::lonnet::logthis(" storing ".(join('-',%grades)));
  my $result=&Apache::lonnet::cstore(\%grades,$symb,   my $result=&Apache::lonnet::cstore(\%grades,$symb,
Line 3646  sub csvuploadassign { Line 3780  sub csvuploadassign {
     $request->print('.');      $request->print('.');
  } else {   } else {
     $request->print("<p>      $request->print("<p>
                               <font color='red'>                                <span class=\"LC_error\">
                                  Failed to store student $username\@$domain.                                   Failed to save student $username:$domain.
                                  Message when trying to store was ($result)                                   Message when trying to save was ($result)
                               </font>                                </span>
                              </p>" );                               </p>" );
  }   }
  $request->rflush();   $request->rflush();
  $countdone++;   $countdone++;
     }      }
     $request->print("<br />Stored $countdone students\n");      $request->print("<br />Saved $countdone students\n");
     if (@skipped) {      if (@skipped) {
  $request->print('<p><font size="+1"><b>Skipped Students</b></font></p>');   $request->print('<p><h4><b>Skipped Students</b></h4></p>');
  foreach my $student (@skipped) { $request->print("$student<br />\n"); }   foreach my $student (@skipped) { $request->print("$student<br />\n"); }
     }      }
     if (@notallowed) {      if (@notallowed) {
  $request->print('<p><font size="+1" color="red"><b>Students Not Allowed to Modify</b></font></p>');   $request->print('<p><span class="LC_error">Students Not Allowed to Modify</span></p>');
  foreach my $student (@notallowed) { $request->print("$student<br />\n"); }   foreach my $student (@notallowed) { $request->print("$student<br />\n"); }
     }      }
     $request->print("<br />\n");      $request->print("<br />\n");
Line 3700  LISTJAVASCRIPT Line 3834  LISTJAVASCRIPT
     my $cnum      = $env{"course.$env{'request.course.id'}.num"};      my $cnum      = $env{"course.$env{'request.course.id'}.num"};
     my $getsec    = $env{'form.section'} eq '' ? 'all' : $env{'form.section'};      my $getsec    = $env{'form.section'} eq '' ? 'all' : $env{'form.section'};
   
     my $result='<h3><font color="#339933">&nbsp;'.      my $result='<h3><span class="LC_info">&nbsp;'.
  'Manual Grading by Page or Sequence</font></h3>';   'Manual Grading by Page or Sequence</span></h3>';
   
     $result.='<form action="/adm/grades" method="post" name="displayPage">'."\n";      $result.='<form action="/adm/grades" method="post" name="displayPage">'."\n";
     $result.='&nbsp;<b>Problems from:</b> <select name="selectpage">'."\n";      $result.='&nbsp;<b>Problems from:</b> <select name="selectpage">'."\n";
Line 3713  LISTJAVASCRIPT Line 3847  LISTJAVASCRIPT
     foreach (@$titles) {      foreach (@$titles) {
  my ($minder,$showtitle) = ($_ =~ /(\d+)\.(.*)/);   my ($minder,$showtitle) = ($_ =~ /(\d+)\.(.*)/);
  $result.='<option value="'.$ctr.'" '.   $result.='<option value="'.$ctr.'" '.
     ($$symbx{$_} =~ /$curpage$/ ? 'selected="on"' : '').      ($$symbx{$_} =~ /$curpage$/ ? 'selected="selected"' : '').
     '>'.$showtitle.'</option>'."\n";      '>'.$showtitle.'</option>'."\n";
  $ctr++;   $ctr++;
     }      }
Line 3728  LISTJAVASCRIPT Line 3862  LISTJAVASCRIPT
     $result.='<input type="hidden" name="page" />'."\n".      $result.='<input type="hidden" name="page" />'."\n".
  '<input type="hidden" name="title" />'."\n";   '<input type="hidden" name="title" />'."\n";
   
     $result.='&nbsp;<b>View Problems Text: </b><label><input type="radio" name="vProb" value="no" checked="on" /> no </label>'."\n".      $result.='&nbsp;<b>View Problems Text: </b><label><input type="radio" name="vProb" value="no" checked="checked" /> no </label>'."\n".
  '<label><input type="radio" name="vProb" value="yes" /> yes </label>'."<br />\n";   '<label><input type="radio" name="vProb" value="yes" /> yes </label>'."<br />\n";
   
     $result.='&nbsp;<b>Submission Details: </b>'.      $result.='&nbsp;<b>Submission Details: </b>'.
  '<label><input type="radio" name="lastSub" value="none" /> none</label>'."\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="datesub" checked="checked" /> 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>'."\n";
   
     $result.='<input type="hidden" name="section"     value="'.$getsec.'" />'."\n".      $result.='<input type="hidden" name="section"     value="'.$getsec.'" />'."\n".
Line 3742  LISTJAVASCRIPT Line 3876  LISTJAVASCRIPT
  '<input type="hidden" name="symb"    value="'.$symb.'" />'."\n".   '<input type="hidden" name="symb"    value="'.$symb.'" />'."\n".
  '<input type="hidden" name="saveState" value="'.$env{'form.saveState'}.'" />'."<br />\n";   '<input type="hidden" name="saveState" value="'.$env{'form.saveState'}.'" />'."<br />\n";
   
       $result.='&nbsp;<b>'.&mt('Use CODE:').' </b>'.
    '<input type="text" name="CODE" value="" /><br />'."\n";
   
     $result.='&nbsp;<input type="button" '.      $result.='&nbsp;<input type="button" '.
  'onClick="javascript:checkPickOne(this.form);"value="Next->" /><br />'."\n";   'onClick="javascript:checkPickOne(this.form);"value="Next->" /><br />'."\n";
   
Line 3772  LISTJAVASCRIPT Line 3909  LISTJAVASCRIPT
  $studentTable.=($ptr%2 == 0 ? '</td></tr>' : '');   $studentTable.=($ptr%2 == 0 ? '</td></tr>' : '');
  $ptr++;   $ptr++;
     }      }
     $studentTable.='</td><td>&nbsp;</td><td>&nbsp;' if ($ptr%2 == 0);      $studentTable.='</td><td>&nbsp;</td><td>&nbsp;</td></tr>' if ($ptr%2 == 0);
     $studentTable.='</td></tr></table></td></tr></table>'."\n";      $studentTable.='</table></td></tr></table>'."\n";
     $studentTable.='<input type="button" '.      $studentTable.='<input type="button" '.
  'onClick="javascript:checkPickOne(this.form);"value="Next->" /></form>'."\n";   'onClick="javascript:checkPickOne(this.form);"value="Next->" /></form>'."\n";
   
Line 3796  sub getSymbMap { Line 3933  sub getSymbMap {
        1,0,1);         1,0,1);
     for my $sequence ($navmap->getById('0.0'), @sequences) {      for my $sequence ($navmap->getById('0.0'), @sequences) {
  if ($navmap->hasResource($sequence, sub { shift->is_problem(); }, 0) ) {   if ($navmap->hasResource($sequence, sub { shift->is_problem(); }, 0) ) {
     my $title = $minder.'.'.$sequence->compTitle();      my $title = $minder.'.'.
     push @titles, $title; # minder in case two titles are identical   &HTML::Entities::encode($sequence->compTitle(),'"\'&');
     $symbx{$title} = $sequence->symb();      push(@titles, $title); # minder in case two titles are identical
       $symbx{$title} = &HTML::Entities::encode($sequence->symb(),'"\'&');
     $minder++;      $minder++;
  }   }
     }      }
Line 3827  sub displayPage { Line 3965  sub displayPage {
     &Apache::lonnet::clear_EXT_cache_status();      &Apache::lonnet::clear_EXT_cache_status();
   
     if (!&canview($usec)) {      if (!&canview($usec)) {
  $request->print('<font color="red">Unable to view requested student.('.$env{'form.student'}.')</font>');   $request->print('<span class="LC_warning">Unable to view requested student.('.$env{'form.student'}.')</span>');
  $request->print(&show_grading_menu_form($symb));   $request->print(&show_grading_menu_form($symb));
  return;   return;
     }      }
     my $result='<h3><font color="#339933">&nbsp;'.$env{'form.title'}.'</font></h3>';      my $result='<h3><span class="LC_info">&nbsp;'.$env{'form.title'}.'</span></h3>';
     $result.='<h3>&nbsp;Student: '.&nameUserString(undef,$$fullname{$env{'form.student'}},$uname,$udom).      $result.='<h3>&nbsp;Student: '.&nameUserString(undef,$$fullname{$env{'form.student'}},$uname,$udom).
  '</h3>'."\n";   '</h3>'."\n";
       if (&Apache::lonnet::validCODE($env{'form.CODE'})) {
    $result.='<h3>&nbsp;CODE: '.$env{'form.CODE'}.'</h3>'."\n";
       } else {
    delete($env{'form.CODE'});
       }
     &sub_page_js($request);      &sub_page_js($request);
     $request->print($result);      $request->print($result);
   
Line 3841  sub displayPage { Line 3984  sub displayPage {
     my ($mapUrl, $id, $resUrl)=&Apache::lonnet::decode_symb($env{'form.page'});      my ($mapUrl, $id, $resUrl)=&Apache::lonnet::decode_symb($env{'form.page'});
     my $map = $navmap->getResourceByUrl($resUrl); # add to navmaps      my $map = $navmap->getResourceByUrl($resUrl); # add to navmaps
     if (!$map) {      if (!$map) {
  $request->print('<font color="red">Unable to view requested sequence. ('.$resUrl.')</font>');   $request->print('<span class="LC_warning">Unable to view requested sequence. ('.$resUrl.')</span>');
  $request->print(&show_grading_menu_form($symb));   $request->print(&show_grading_menu_form($symb));
  return;    return; 
     }      }
Line 3858  sub displayPage { Line 4001  sub displayPage {
  '<input type="hidden" name="overRideScore" value="no" />'."\n".   '<input type="hidden" name="overRideScore" value="no" />'."\n".
  '<input type="hidden" name="saveState" value="'.$env{'form.saveState'}.'" />'."\n";   '<input type="hidden" name="saveState" value="'.$env{'form.saveState'}.'" />'."\n";
   
     my $checkIcon = '<img src="'.$request->dir_config('lonIconsURL').      if (defined($env{'form.CODE'})) {
    $studentTable.=
       '<input type="hidden" name="CODE" value="'.$env{'form.CODE'}.'" />'."\n";
       }
       my $checkIcon = '<img alt="'.&mt('Check Mark').
    '" src="'.$request->dir_config('lonIconsURL').
  '/check.gif" height="16" border="0" />';   '/check.gif" height="16" border="0" />';
   
     $studentTable.='&nbsp;<b>Note:</b> Problems graded correct by the computer are marked with a '.$checkIcon.      $studentTable.='&nbsp;<b>Note:</b> Problems graded correct by the computer are marked with a '.$checkIcon.
Line 3876  sub displayPage { Line 4024  sub displayPage {
         if($curRes == $iterator->BEGIN_MAP) { $depth++; }          if($curRes == $iterator->BEGIN_MAP) { $depth++; }
         if($curRes == $iterator->END_MAP) { $depth--; }          if($curRes == $iterator->END_MAP) { $depth--; }
   
         if (ref($curRes) && $curRes->is_problem() && !$curRes->randomout) {          if (ref($curRes) && $curRes->is_problem()) {
     my $parts = $curRes->parts();      my $parts = $curRes->parts();
             my $title = $curRes->compTitle();              my $title = $curRes->compTitle();
     my $symbx = $curRes->symb();      my $symbx = $curRes->symb();
     $studentTable.='<tr bgcolor="#ffffe6"><td align="center" valign="top" >'.$prob.      $studentTable.='<tr bgcolor="#ffffe6"><td align="center" valign="top" >'.$prob.
  (scalar(@{$parts}) == 1 ? '' : '<br />('.scalar(@{$parts}).'&nbsp;parts)').'</td>';   (scalar(@{$parts}) == 1 ? '' : '<br />('.scalar(@{$parts}).'&nbsp;parts)').'</td>';
     $studentTable.='<td valign="top">';      $studentTable.='<td valign="top">';
       my %form = ('CODE' => $env{'form.CODE'},);
     if ($env{'form.vProb'} eq 'yes' ) {      if ($env{'form.vProb'} eq 'yes' ) {
  $studentTable.=&show_problem($request,$symbx,$uname,$udom,1,   $studentTable.=&show_problem($request,$symbx,$uname,$udom,1,
      undef,'both');       undef,'both',\%form);
     } else {      } else {
  my $companswer = &Apache::loncommon::get_student_answers($symbx,$uname,$udom,$env{'request.course.id'});   my $companswer = &Apache::loncommon::get_student_answers($symbx,$uname,$udom,$env{'request.course.id'},%form);
  $companswer =~ s|<form(.*?)>||g;   $companswer =~ s|<form(.*?)>||g;
  $companswer =~ s|</form>||g;   $companswer =~ s|</form>||g;
 # while ($companswer =~ /(<a href\=\"javascript:newWindow.*?Script Vars<\/a>)/s) { #<a href="javascript:newWindow</a>  # while ($companswer =~ /(<a href\=\"javascript:newWindow.*?Script Vars<\/a>)/s) { #<a href="javascript:newWindow</a>
Line 3902  sub displayPage { Line 4051  sub displayPage {
   
     if ($env{'form.lastSub'} eq 'datesub') {      if ($env{'form.lastSub'} eq 'datesub') {
  if ($record{'version'} eq '') {   if ($record{'version'} eq '') {
     $studentTable.='<br />&nbsp;<font color="red">No recorded submission for this problem</font><br />';      $studentTable.='<br />&nbsp;<span class="LC_warning">No recorded submission for this problem</span><br />';
  } else {   } else {
     my %responseType = ();      my %responseType = ();
     foreach my $partid (@{$parts}) {      foreach my $partid (@{$parts}) {
Line 3938  sub displayPage { Line 4087  sub displayPage {
         $curRes = $iterator->next();          $curRes = $iterator->next();
     }      }
   
     $studentTable.='</td></tr></table></td></tr></table>'."\n".      $studentTable.='</table></td></tr></table>'."\n".
  '<input type="button" value="Save" '.   '<input type="button" value="Save" '.
  'onClick="javascript:checkSubmitPage(this.form,'.$question.');" TARGET=_self />'.   'onClick="javascript:checkSubmitPage(this.form,'.$question.');" />'.
  '</form>'."\n";   '</form>'."\n";
     $studentTable.=&show_grading_menu_form($symb);      $studentTable.=&show_grading_menu_form($symb);
     $request->print($studentTable);      $request->print($studentTable);
Line 3964  sub displaySubByDates { Line 4113  sub displaySubByDates {
     my %orders;      my %orders;
     $mark{'correct_by_student'} = $checkIcon;      $mark{'correct_by_student'} = $checkIcon;
     if (!exists($$record{'1:timestamp'})) {      if (!exists($$record{'1:timestamp'})) {
  return '<br />&nbsp;<font color="red">Nothing submitted - no attempts</font><br />';   return '<br />&nbsp;<span class="LC_warning">Nothing submitted - no attempts</span><br />';
     }      }
   
     my $interaction;      my $interaction;
Line 3998  sub displaySubByDates { Line 4147  sub displaySubByDates {
                : ($matchKey=~ /^resource\.\Q$partid\E\.(.*?)\.submission$/));                 : ($matchKey=~ /^resource\.\Q$partid\E\.(.*?)\.submission$/));
     #&Apache::lonnet::logthis("match $matchKey $responseId (".$$record{$version.':'.$matchKey});      #&Apache::lonnet::logthis("match $matchKey $responseId (".$$record{$version.':'.$matchKey});
     $displaySub[0].='<b>Part:</b>&nbsp;'.$display_part.'&nbsp;';      $displaySub[0].='<b>Part:</b>&nbsp;'.$display_part.'&nbsp;';
     $displaySub[0].='<font color="#999999">(ID&nbsp;'.      $displaySub[0].='<span class="LC_internal_info">(ID&nbsp;'.
  $responseId.')</font>&nbsp;<b>';   $responseId.')</span>&nbsp;<b>';
     if ($$record{"$where.$partid.tries"} eq '') {      if ($$record{"$where.$partid.tries"} eq '') {
  $displaySub[0].='Trial&nbsp;not&nbsp;counted';   $displaySub[0].='Trial&nbsp;not&nbsp;counted';
     } else {      } else {
Line 4064  sub updateGradeByPage { Line 4213  sub updateGradeByPage {
     my ($uname,$udom) = split(/:/,$env{'form.student'});      my ($uname,$udom) = split(/:/,$env{'form.student'});
     my $usec=$classlist->{$env{'form.student'}}[5];      my $usec=$classlist->{$env{'form.student'}}[5];
     if (!&canmodify($usec)) {      if (!&canmodify($usec)) {
  $request->print('<font color="red">Unable to modify requested student.('.$env{'form.student'}.'</font>');   $request->print('<span class="LC_warning">Unable to modify requested student.('.$env{'form.student'}.'</span>');
  $request->print(&show_grading_menu_form($env{'form.symb'}));   $request->print(&show_grading_menu_form($env{'form.symb'}));
  return;   return;
     }      }
     my $result='<h3><font color="#339933">&nbsp;'.$env{'form.title'}.'</font></h3>';      my $result='<h3><span class="LC_info">&nbsp;'.$env{'form.title'}.'</span></h3>';
     $result.='<h3>&nbsp;Student: '.&nameUserString(undef,$env{'form.fullname'},$uname,$udom).      $result.='<h3>&nbsp;Student: '.&nameUserString(undef,$env{'form.fullname'},$uname,$udom).
  '</h3>'."\n";   '</h3>'."\n";
   
Line 4078  sub updateGradeByPage { Line 4227  sub updateGradeByPage {
     my ($mapUrl, $id, $resUrl) = &Apache::lonnet::decode_symb( $env{'form.page'});      my ($mapUrl, $id, $resUrl) = &Apache::lonnet::decode_symb( $env{'form.page'});
     my $map = $navmap->getResourceByUrl($resUrl); # add to navmaps      my $map = $navmap->getResourceByUrl($resUrl); # add to navmaps
     if (!$map) {      if (!$map) {
  $request->print('<font color="red">Unable to grade requested sequence. ('.$resUrl.')</font>');   $request->print('<span class="LC_warning">Unable to grade requested sequence. ('.$resUrl.')</span>');
  my ($symb)=&get_symb($request);   my ($symb)=&get_symb($request);
  $request->print(&show_grading_menu_form($symb));   $request->print(&show_grading_menu_form($symb));
  return;    return; 
Line 4100  sub updateGradeByPage { Line 4249  sub updateGradeByPage {
         if($curRes == $iterator->BEGIN_MAP) { $depth++; }          if($curRes == $iterator->BEGIN_MAP) { $depth++; }
         if($curRes == $iterator->END_MAP) { $depth--; }          if($curRes == $iterator->END_MAP) { $depth--; }
   
         if (ref($curRes) && $curRes->is_problem() && !$curRes->randomout) {          if (ref($curRes) && $curRes->is_problem()) {
     my $parts = $curRes->parts();      my $parts = $curRes->parts();
             my $title = $curRes->compTitle();              my $title = $curRes->compTitle();
     my $symbx = $curRes->symb();      my $symbx = $curRes->symb();
Line 4155  sub updateGradeByPage { Line 4304  sub updateGradeByPage {
  $displayPts[1].='&nbsp;<b>Part:</b> '.$display_part.' = '.   $displayPts[1].='&nbsp;<b>Part:</b> '.$display_part.' = '.
      (($score eq 'excused') ? 'excused' : $newpts).       (($score eq 'excused') ? 'excused' : $newpts).
     '&nbsp;<br />';      '&nbsp;<br />';
   
  $question++;   $question++;
  next if ($dropMenu eq 'reset status' || ($newpts == $oldpts && $score ne 'excused'));   next if ($dropMenu eq 'reset status' || ($newpts eq $oldpts && $score ne 'excused'));
   
  $newrecord{'resource.'.$partid.'.awarded'}  = $partial if $partial ne '';   $newrecord{'resource.'.$partid.'.awarded'}  = $partial if $partial ne '';
  $newrecord{'resource.'.$partid.'.solved'}   = $score if $score ne '';   $newrecord{'resource.'.$partid.'.solved'}   = $score if $score ne '';
Line 4167  sub updateGradeByPage { Line 4315  sub updateGradeByPage {
  $changeflag++;   $changeflag++;
     }      }
     if (scalar(keys(%newrecord)) > 0) {      if (scalar(keys(%newrecord)) > 0) {
    my %record = 
       &Apache::lonnet::restore($symbx,$env{'request.course.id'},
        $udom,$uname);
   
    if (&Apache::lonnet::validCODE($env{'form.CODE'})) {
       $newrecord{'resource.CODE'} = $env{'form.CODE'};
    } elsif (&Apache::lonnet::validCODE($record{'resource.CODE'})) {
       $newrecord{'resource.CODE'} = '';
    }
  &Apache::lonnet::cstore(\%newrecord,$symbx,$env{'request.course.id'},   &Apache::lonnet::cstore(\%newrecord,$symbx,$env{'request.course.id'},
  $udom,$uname);   $udom,$uname);
    %record = &Apache::lonnet::restore($symbx,
      $env{'request.course.id'},
      $udom,$uname);
    &check_and_remove_from_queue($parts,\%record,undef,$symbx,
        $cdom,$cnum,$udom,$uname);
     }      }
       
             if ($aggregateflag) {              if ($aggregateflag) {
                 &Apache::lonnet::cinc('nohist_resourcetracker',\%aggregate,                  &Apache::lonnet::cinc('nohist_resourcetracker',\%aggregate,
                       $env{'course.'.$env{'request.course.id'}.'.domain'},                        $env{'course.'.$env{'request.course.id'}.'.domain'},
Line 4220  sub getSequenceDropDown { Line 4383  sub getSequenceDropDown {
     foreach (@$titles) {      foreach (@$titles) {
  my ($minder,$showtitle) = ($_ =~ /(\d+)\.(.*)/);   my ($minder,$showtitle) = ($_ =~ /(\d+)\.(.*)/);
  $result.='<option value="'.$$symbx{$_}.'" '.   $result.='<option value="'.$$symbx{$_}.'" '.
     ($$symbx{$_} =~ /$curpage$/ ? 'selected="on"' : '').      ($$symbx{$_} =~ /$curpage$/ ? 'selected="selected"' : '').
     '>'.$showtitle.'</option>'."\n";      '>'.$showtitle.'</option>'."\n";
  $ctr++;   $ctr++;
     }      }
Line 4248  sub scantron_uploads { Line 4411  sub scantron_uploads {
     my $result= '<select name="scantron_selectfile">';      my $result= '<select name="scantron_selectfile">';
     $result.="<option></option>";      $result.="<option></option>";
     foreach my $filename (sort(&scantron_filenames())) {      foreach my $filename (sort(&scantron_filenames())) {
  $result.="<option".($filename eq $file2grade ? ' selected="on"':'').">$filename</option>\n";   $result.="<option".($filename eq $file2grade ? ' selected="selected"':'').">$filename</option>\n";
     }      }
     $result.="</select>";      $result.="</select>";
     return $result;      return $result;
Line 4283  sub scantron_CODElist { Line 4446  sub scantron_CODElist {
 }  }
   
 sub scantron_CODEunique {  sub scantron_CODEunique {
     my $result='<nobr>      my $result='<span style="white-space: nowrap;">
                  <label><input type="radio" name="scantron_CODEunique"                   <label><input type="radio" name="scantron_CODEunique"
                         value="yes" checked="checked" /> Yes </label>                          value="yes" checked="checked" /> Yes </label>
                 </nobr>                  </span>
                 <nobr>                  <span style="white-space: nowrap;">
                  <label><input type="radio" name="scantron_CODEunique"                   <label><input type="radio" name="scantron_CODEunique"
                         value="no" /> No </label>                          value="no" /> No </label>
                 </nobr>';                  </span>';
     return $result;      return $result;
 }  }
   
Line 4409  SCANTRONFORM Line 4572  SCANTRONFORM
     <tr>      <tr>
       <form action='/adm/grades' name='scantron_download'>        <form action='/adm/grades' name='scantron_download'>
         <td bgcolor="#777777">          <td bgcolor="#777777">
     $default_form_data
           <input type="hidden" name="command" value="scantron_download" />            <input type="hidden" name="command" value="scantron_download" />
           <table width="100%" border="0">            <table width="100%" border="0">
             <tr bgcolor="#e6ffff">              <tr bgcolor="#e6ffff">
Line 4525  sub scantron_fixup_scanline { Line 4689  sub scantron_fixup_scanline {
  $answer=$alphabet[$args->{'response'}];   $answer=$alphabet[$args->{'response'}];
     } elsif ($on eq 'number') {      } elsif ($on eq 'number') {
  $answer=$args->{'response'}+1;   $answer=$args->{'response'}+1;
    if ($answer == 10) { $answer = '0'; }
     } else {      } else {
  substr($answer,$args->{'response'},1)=$on;   substr($answer,$args->{'response'},1)=$on;
     }      }
Line 4591  sub scantron_parse_scanline { Line 4756  sub scantron_parse_scanline {
  substr($questions,0,$$scantron_config{'Qlength'})='';   substr($questions,0,$$scantron_config{'Qlength'})='';
  if (length($currentquest) < $$scantron_config{'Qlength'}) { next; }   if (length($currentquest) < $$scantron_config{'Qlength'}) { next; }
  if ($$scantron_config{'Qon'} eq 'letter') {   if ($$scantron_config{'Qon'} eq 'letter') {
     if ($currentquest eq '?') {      if ($currentquest eq '?'
    || $currentquest eq '*') {
  push(@{$record{'scantron.doubleerror'}},$questnum);   push(@{$record{'scantron.doubleerror'}},$questnum);
  $record{"scantron.$questnum.answer"}='';   $record{"scantron.$questnum.answer"}='';
     } elsif (!$currentquest       } elsif (!defined($currentquest)
      || $currentquest eq $$scantron_config{'Qoff'}       || $currentquest eq $$scantron_config{'Qoff'}
      || $currentquest !~ /^[A-Z]$/) {       || $currentquest !~ /^[A-Z]$/) {
  $record{"scantron.$questnum.answer"}='';   $record{"scantron.$questnum.answer"}='';
Line 4605  sub scantron_parse_scanline { Line 4771  sub scantron_parse_scanline {
  $record{"scantron.$questnum.answer"}=$currentquest;   $record{"scantron.$questnum.answer"}=$currentquest;
     }      }
  } elsif ($$scantron_config{'Qon'} eq 'number') {   } elsif ($$scantron_config{'Qon'} eq 'number') {
     if ($currentquest eq '?') {      if ($currentquest eq '?'
    || $currentquest eq '*') {
  push(@{$record{'scantron.doubleerror'}},$questnum);   push(@{$record{'scantron.doubleerror'}},$questnum);
  $record{"scantron.$questnum.answer"}='';   $record{"scantron.$questnum.answer"}='';
  } elsif (!$currentquest       } elsif (!defined($currentquest)
  || $currentquest eq $$scantron_config{'Qoff'}        || $currentquest eq $$scantron_config{'Qoff'} 
  || $currentquest !~ /^\d$/) {       || $currentquest !~ /^\d$/) {
  $record{"scantron.$questnum.answer"}='';   $record{"scantron.$questnum.answer"}='';
  if (!&scan_data($scan_data,"$whichline.no_bubble.$questnum")) {   if (!&scan_data($scan_data,"$whichline.no_bubble.$questnum")) {
     push(@{$record{"scantron.missingerror"}},$questnum);      push(@{$record{"scantron.missingerror"}},$questnum);
  }   }
     } else {      } else {
  $record{"scantron.$questnum.answer"}=   # wrap zero back to J
     $alphabet[$currentquest-1];   if ($currentquest eq '0') {
       $record{"scantron.$questnum.answer"}=
    $alphabet[9];
    } else {
       $record{"scantron.$questnum.answer"}=
    $alphabet[$currentquest-1];
    }
     }      }
  } else {   } else {
     my @array=split($$scantron_config{'Qon'},$currentquest,-1);      my @array=split($$scantron_config{'Qon'},$currentquest,-1);
Line 4734  sub scantron_process_corrections { Line 4907  sub scantron_process_corrections {
  }   }
     }      }
     if ($err) {      if ($err) {
  $r->print("<font color='red'>Unable to accept last correction, an error occurred :$errmsg:</font>");   $r->print("<span class=\"LC_warning\">Unable to accept last correction, an error occurred :$errmsg:</span>");
     } else {      } else {
  &scantron_put_line($scanlines,$scan_data,$which,$line,$skip);   &scantron_put_line($scanlines,$scan_data,$which,$line,$skip);
  &scantron_putfile($scanlines,$scan_data);   &scantron_putfile($scanlines,$scan_data);
Line 4747  sub reset_skipping_status { Line 4920  sub reset_skipping_status {
     &scantron_putfile(undef,$scan_data);      &scantron_putfile(undef,$scan_data);
 }  }
   
 sub allow_skipping {  sub start_skipping {
     my ($scan_data,$i)=@_;      my ($scan_data,$i)=@_;
     my %remembered=split(':',&scan_data($scan_data,'remember_skipping'));      my %remembered=split(':',&scan_data($scan_data,'remember_skipping'));
     delete($remembered{$i});      if ($env{'form.scantron_options_redo'} =~ /^redo_/) {
    $remembered{$i}=2;
       } else {
    $remembered{$i}=1;
       }
     &scan_data($scan_data,'remember_skipping',join(':',%remembered));      &scan_data($scan_data,'remember_skipping',join(':',%remembered));
 }  }
   
 sub should_be_skipped {  sub should_be_skipped {
     my ($scan_data,$i)=@_;      my ($scanlines,$scan_data,$i)=@_;
     if ($env{'form.scantron_options_redo'} !~ /^redo_/) {      if ($env{'form.scantron_options_redo'} !~ /^redo_/) {
  # not redoing old skips   # not redoing old skips
    if ($scanlines->{'skipped'}[$i]) { return 1; }
  return 0;   return 0;
     }      }
     my %remembered=split(':',&scan_data($scan_data,'remember_skipping'));      my %remembered=split(':',&scan_data($scan_data,'remember_skipping'));
     if (exists($remembered{$i})) { return 0; }  
       if (exists($remembered{$i}) && $remembered{$i} != 2 ) {
    return 0;
       }
     return 1;      return 1;
 }  }
   
Line 4773  sub remember_current_skipped { Line 4954  sub remember_current_skipped {
     $to_remember{$i}=1;      $to_remember{$i}=1;
  }   }
     }      }
   
     &scan_data($scan_data,'remember_skipping',join(':',%to_remember));      &scan_data($scan_data,'remember_skipping',join(':',%to_remember));
     &scantron_putfile(undef,$scan_data);      &scantron_putfile(undef,$scan_data);
 }  }
Line 4780  sub remember_current_skipped { Line 4962  sub remember_current_skipped {
 sub check_for_error {  sub check_for_error {
     my ($r,$result)=@_;      my ($r,$result)=@_;
     if ($result ne 'ok' && $result ne 'not_found' ) {      if ($result ne 'ok' && $result ne 'not_found' ) {
  $r->print("An error occured ($result) when trying to Remove the existing corrections.");   $r->print("An error occurred ($result) when trying to Remove the existing corrections.");
     }      }
 }  }
   
Line 4788  sub scantron_warning_screen { Line 4970  sub scantron_warning_screen {
     my ($button_text)=@_;      my ($button_text)=@_;
     my $title=&Apache::lonnet::gettitle($env{'form.selectpage'});      my $title=&Apache::lonnet::gettitle($env{'form.selectpage'});
     my %scantron_config=&get_scantron_config($env{'form.scantron_format'});      my %scantron_config=&get_scantron_config($env{'form.scantron_format'});
     my $CODElist="a";      my $CODElist;
     if ($scantron_config{'CODElocation'} &&      if ($scantron_config{'CODElocation'} &&
  $scantron_config{'CODEstart'} &&   $scantron_config{'CODEstart'} &&
  $scantron_config{'CODElength'}) {   $scantron_config{'CODElength'}) {
  $CODElist=$env{'form.scantron_CODElist'};   $CODElist=$env{'form.scantron_CODElist'};
  if ($CODElist eq '') { $CODElist='<font color="red">None</font>'; }   if ($env{'form.scantron_CODElist'} eq '') { $CODElist='<span class="LC_warning">None</span>'; }
  $CODElist=   $CODElist=
     '<tr><td><b>List of CODES to validate against:</b></td><td><tt>'.      '<tr><td><b>List of CODES to validate against:</b></td><td><tt>'.
     $CODElist.'</tt></td></tr>';      $env{'form.scantron_CODElist'}.'</tt></td></tr>';
     }      }
     return (<<STUFF);      return (<<STUFF);
 <p>  <p>
 <font color="red">Please double check the information  <span class="LC_warning">Please double check the information
                  below before clicking on '$button_text'</font>                   below before clicking on '$button_text'</span>
 </p>  </p>
 <table>  <table>
 <tr><td><b>Sequence to be Graded:</b></td><td>$title</td></tr>  <tr><td><b>Sequence to be Graded:</b></td><td>$title</td></tr>
 <tr><td><b>Data File that will be used:</b></td><td><tt>$env{'form.scantron_selectfile'}</tt></td></tr>  <tr><td><b>Data File that will be used:</b></td><td><tt>$env{'form.scantron_selectfile'}</tt></td></tr>
 $CODElist  $CODElist
 </table>  </table>
 </font>  
 <br />  <br />
 <p> If this information is correct, please click on '$button_text'.</p>  <p> If this information is correct, please click on '$button_text'.</p>
 <p> If something is incorrect, please click the 'Grading Menu' button to start over.</p>  <p> If something is incorrect, please click the 'Grading Menu' button to start over.</p>
Line 4828  sub scantron_do_warning { Line 5009  sub scantron_do_warning {
  $env{'form.scantron_format'} eq '' ) {   $env{'form.scantron_format'} eq '' ) {
  $r->print("<p>You have forgetten to specify some information. Please go Back and try again.</p>");   $r->print("<p>You have forgetten to specify some information. Please go Back and try again.</p>");
  if ( $env{'form.selectpage'} eq '') {   if ( $env{'form.selectpage'} eq '') {
     $r->print('<p><font color="red">You have not selected a Sequence to grade</font></p>');      $r->print('<p><span class="LC_error">You have not selected a Sequence to grade</span></p>');
  }    } 
  if ( $env{'form.scantron_selectfile'} eq '') {   if ( $env{'form.scantron_selectfile'} eq '') {
     $r->print('<p><font color="red">You have not selected a file that contains the student\'s response data.</font></p>');      $r->print('<p><span class="LC_error">You have not selected a file that contains the student\'s response data.</span></p>');
  }    } 
  if ( $env{'form.scantron_format'} eq '') {   if ( $env{'form.scantron_format'} eq '') {
     $r->print('<p><font color="red">You have not selected a the format of the student\'s response data.</font></p>');      $r->print('<p><span class="LC_error">You have not selected a the format of the student\'s response data.</span></p>');
  }    } 
     } else {      } else {
  my $warning=&scantron_warning_screen('Grading: Validate Records');   my $warning=&scantron_warning_screen('Grading: Validate Records');
Line 4878  sub scantron_validate_file { Line 5059  sub scantron_validate_file {
     }      }
     if ($env{'form.scantron_options_redo'} eq 'redo_skipped') {      if ($env{'form.scantron_options_redo'} eq 'redo_skipped') {
  &remember_current_skipped();   &remember_current_skipped();
  &scantron_remove_file('skipped');  
  $env{'form.scantron_options_redo'}='redo_skipped_ready';   $env{'form.scantron_options_redo'}='redo_skipped_ready';
     }      }
   
Line 5048  sub scantron_putfile { Line 5228  sub scantron_putfile {
   
 sub scantron_get_line {  sub scantron_get_line {
     my ($scanlines,$scan_data,$i)=@_;      my ($scanlines,$scan_data,$i)=@_;
     if (&should_be_skipped($scan_data,$i)) { return undef; }      if (&should_be_skipped($scanlines,$scan_data,$i)) { return undef; }
     if ($scanlines->{'skipped'}[$i]) { return undef; }      #if ($scanlines->{'skipped'}[$i]) { return undef; }
     if ($scanlines->{'corrected'}[$i]) {return $scanlines->{'corrected'}[$i];}      if ($scanlines->{'corrected'}[$i]) {return $scanlines->{'corrected'}[$i];}
     return $scanlines->{'orig'}[$i];       return $scanlines->{'orig'}[$i]; 
 }  }
Line 5069  sub scantron_put_line { Line 5249  sub scantron_put_line {
     my ($scanlines,$scan_data,$i,$newline,$skip)=@_;      my ($scanlines,$scan_data,$i,$newline,$skip)=@_;
     if ($skip) {      if ($skip) {
  $scanlines->{'skipped'}[$i]=$newline;   $scanlines->{'skipped'}[$i]=$newline;
  &allow_skipping($scan_data,$i);   &start_skipping($scan_data,$i);
  return;   return;
     }      }
     $scanlines->{'corrected'}[$i]=$newline;      $scanlines->{'corrected'}[$i]=$newline;
 }  }
   
   sub scantron_clear_skip {
       my ($scanlines,$scan_data,$i)=@_;
       if (exists($scanlines->{'skipped'}[$i])) {
    undef($scanlines->{'skipped'}[$i]);
    return 1;
       }
       return 0;
   }
   
 sub scantron_filter_not_exam {  sub scantron_filter_not_exam {
     my ($curres)=@_;      my ($curres)=@_;
           
Line 5235  sub scantron_get_correction { Line 5424  sub scantron_get_correction {
     if ($closest > 0) {      if ($closest > 0) {
  foreach my $testcode (@{$closest}) {   foreach my $testcode (@{$closest}) {
     my $checked='';      my $checked='';
     if (!$i) { $checked=' checked="on" '; }      if (!$i) { $checked=' checked="checked" '; }
     $r->print("<label><input type='radio' name='scantron_CODE_resolution' value='use_closest_$i' $checked /> Use the similar CODE <b><tt>".$testcode."</tt></b> instead.</label><input type='hidden' name='scantron_CODE_closest_$i' value='$testcode' />");      $r->print("<label><input type='radio' name='scantron_CODE_resolution' value='use_closest_$i' $checked /> Use the similar CODE <b><tt>".$testcode."</tt></b> instead.</label><input type='hidden' name='scantron_CODE_closest_$i' value='$testcode' />");
     $r->print("\n<br />");      $r->print("\n<br />");
     $i++;      $i++;
Line 5243  sub scantron_get_correction { Line 5432  sub scantron_get_correction {
     }      }
  }   }
  if ($$scan_record{'scantron.CODE'}=~/\S/ ) {   if ($$scan_record{'scantron.CODE'}=~/\S/ ) {
     my $checked; if (!$i) { $checked=' checked="on" '; }      my $checked; if (!$i) { $checked=' checked="checked" '; }
     $r->print("<label><input type='radio' name='scantron_CODE_resolution' value='use_unfound' $checked /> Use the CODE <b><tt>".$$scan_record{'scantron.CODE'}."</tt></b> that is was on the paper, ignoring the error.</label>");      $r->print("<label><input type='radio' name='scantron_CODE_resolution' value='use_unfound' $checked /> Use the CODE <b><tt>".$$scan_record{'scantron.CODE'}."</tt></b> that is was on the paper, ignoring the error.</label>");
     $r->print("\n<br />");      $r->print("\n<br />");
  }   }
Line 5561  SCANTRONFORM Line 5750  SCANTRONFORM
   
  &Apache::lonxml::clear_problem_counter();   &Apache::lonxml::clear_problem_counter();
   &Apache::lonnet::appenv(%$scan_record);    &Apache::lonnet::appenv(%$scan_record);
   
    if (&scantron_clear_skip($scanlines,$scan_data,$i)) {
       &scantron_putfile($scanlines,$scan_data);
    }
   
  my $i=0;   my $i=0;
  foreach my $resource (@resources) {   foreach my $resource (@resources) {
Line 5571  SCANTRONFORM Line 5764  SCANTRONFORM
       'grade_domain'  =>$udom,        'grade_domain'  =>$udom,
       'grade_courseid'=>$env{'request.course.id'},        'grade_courseid'=>$env{'request.course.id'},
       'grade_symb'    =>$resource->symb());        'grade_symb'    =>$resource->symb());
     if (exists($scan_record->{'scantron.CODE'}) &&      if (exists($scan_record->{'scantron.CODE'})
  $scan_record->{'scantron.CODE'}) {   && 
    &Apache::lonnet::validCODE($scan_record->{'scantron.CODE'})) {
  $form{'CODE'}=$scan_record->{'scantron.CODE'};   $form{'CODE'}=$scan_record->{'scantron.CODE'};
     } else {      } else {
  $form{'CODE'}='';   $form{'CODE'}='';
Line 5673  sub scantron_upload_scantron_data_save { Line 5867  sub scantron_upload_scantron_data_save {
     my $uploadedfile=$fname;      my $uploadedfile=$fname;
     $fname='scantron_orig_'.$fname;      $fname='scantron_orig_'.$fname;
     if (length($env{'form.upfile'}) < 2) {      if (length($env{'form.upfile'}) < 2) {
  $r->print("<font color='red'>Error:</font> The file you attempted to upload, <tt>".&HTML::Entities::encode($env{'form.upfile.filename'},'<>&"')."</tt>, contained no information. Please check that you entered the correct filename.");   $r->print("<span class=\"LC_error\">Error:</span> The file you attempted to upload, <tt>".&HTML::Entities::encode($env{'form.upfile.filename'},'<>&"')."</tt>, contained no information. Please check that you entered the correct filename.");
     } else {      } else {
  my $result=&Apache::lonnet::finishuserfileupload($env{'form.courseid'},$env{'form.domainid'},'upfile',$fname);   my $result=&Apache::lonnet::finishuserfileupload($env{'form.courseid'},$env{'form.domainid'},'upfile',$fname);
  if ($result =~ m|^/uploaded/|) {   if ($result =~ m|^/uploaded/|) {
     $r->print("<font color='green'>Success:</font> Successfully uploaded ".(length($env{'form.upfile'})-1)." bytes of data into location <tt>".$result."</tt>");      $r->print("<span class=\"LC_success\">Success:</span> Successfully uploaded ".(length($env{'form.upfile'})-1)." bytes of data into location <tt>".$result."</tt>");
  } else {   } else {
     $r->print("<font color='red'>Error:</font> An error (".$result.") occurred when attempting to upload the file, <tt>".&HTML::Entities::encode($env{'form.upfile.filename'},'<>&"')."</tt>");      $r->print("<span class=\"LC_error\">Error:</span> An error (".$result.") occurred when attempting to upload the file, <tt>".&HTML::Entities::encode($env{'form.upfile.filename'},'<>&"')."</tt>");
  }   }
     }      }
     if ($symb) {      if ($symb) {
Line 5808  sub gradingmenu { Line 6002  sub gradingmenu {
 </script>  </script>
 GRADINGMENUJS  GRADINGMENUJS
     &commonJSfunctions($request);      &commonJSfunctions($request);
     my $result='<h3>&nbsp;<font color="#339933">Manual Grading/View Submission</font></h3>';      my $result='<h3>&nbsp;<span class="LC_info">Manual Grading/View Submission</span></h3>';
     my ($table,undef,$hdgrade) = &showResourceInfo($symb,$probTitle);      my ($table,undef,$hdgrade) = &showResourceInfo($symb,$probTitle);
     $result.=$table;      $result.=$table;
     my (undef,$sections) = &getclasslist('all','0');      my (undef,$sections) = &getclasslist('all','0');
Line 5838  GRADINGMENUJS Line 6032  GRADINGMENUJS
     if (ref($sections)) {      if (ref($sections)) {
  foreach (sort (@$sections)) {   foreach (sort (@$sections)) {
     $result.='<option value="'.$_.'" '.      $result.='<option value="'.$_.'" '.
  ($saveSec eq $_ ? 'selected="on"':'').'>'.$_.'</option>'."\n";   ($saveSec eq $_ ? 'selected="selected"':'').'>'.$_.'</option>'."\n";
  }   }
     }      }
     $result.= '<option value="all" '.($saveSec eq 'all' ? 'selected="on"' : ''). '>all</option></select> &nbsp; ';      $result.= '<option value="all" '.($saveSec eq 'all' ? 'selected="selected"' : ''). '>all</option></select> &nbsp; ';
   
     $result.=&mt('Student Status').':</b>'.&Apache::lonhtmlcommon::StatusOptions($saveStatus,undef,1,undef);      $result.=&mt('Student Status').':'.&Apache::lonhtmlcommon::StatusOptions($saveStatus,undef,1,undef);
   
     $result.='</td></tr>';      $result.='</td></tr>';
   
     $result.='<tr bgcolor="#ffffe6"valign="top"><td><label>'.      $result.='<tr bgcolor="#ffffe6"valign="top"><td><label>'.
  '<input type="radio" name="radioChoice" value="submission" '.   '<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="checked"' : '').' /> '.'<b>'.&mt('Current Resource').':</b> '.&mt('For one or more students').
  '</label> <select name="submitonly">'.   '</label> <select name="submitonly">'.
  '<option value="yes" '.   '<option value="yes" '.
  ($saveSub eq 'yes' ? 'selected="on"' : '').' />'.&mt('with submissions').'</option>'.   ($saveSub eq 'yes' ? 'selected="selected"' : '').'>'.&mt('with submissions').'</option>'.
  '<option value="queued" '.   '<option value="queued" '.
  ($saveSub eq 'queued' ? 'selected="on"' : '').' />'.&mt('in grading queue').'</option>'.   ($saveSub eq 'queued' ? 'selected="selected"' : '').'>'.&mt('in grading queue').'</option>'.
  '<option value="graded" '.   '<option value="graded" '.
  ($saveSub eq 'graded' ? 'selected="on"' : '').' />'.&mt('with ungraded submissions').'</option>'.   ($saveSub eq 'graded' ? 'selected="selected"' : '').'>'.&mt('with ungraded submissions').'</option>'.
  '<option value="incorrect" '.   '<option value="incorrect" '.
  ($saveSub eq 'incorrect' ? 'selected="on"' : '').' />'.&mt('with incorrect submissions').'</option>'.   ($saveSub eq 'incorrect' ? 'selected="selected"' : '').'>'.&mt('with incorrect submissions').'</option>'.
  '<option value="all" '.   '<option value="all" '.
  ($saveSub eq 'all' ? 'selected="on"' : '').' />'.&mt('with any status').'</option></select></td></tr>'."\n";   ($saveSub eq 'all' ? 'selected="selected"' : '').'>'.&mt('with any status').'</option></select></td></tr>'."\n";
   
     $result.='<tr bgcolor="#ffffe6"valign="top"><td>'.      $result.='<tr bgcolor="#ffffe6"valign="top"><td>'.
  '<label><input type="radio" name="radioChoice" value="viewgrades" '.   '<label><input type="radio" name="radioChoice" value="viewgrades" '.
  ($saveCmd eq 'viewgrades' ? 'checked' : '').' /> '.   ($saveCmd eq 'viewgrades' ? 'checked="checked"' : '').' /> '.
  '<b>Current Resource:</b> For all students in selected section or course</label></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>'.      $result.='<tr bgcolor="#ffffe6" valign="top"><td>'.
  '<label><input type="radio" name="radioChoice" value="pickStudentPage" '.   '<label><input type="radio" name="radioChoice" value="pickStudentPage" '.
  ($saveCmd eq 'pickStudentPage' ? 'checked' : '').' /> '.   ($saveCmd eq 'pickStudentPage' ? 'checked="checked"' : '').' /> '.
  'The <b>complete</b> set/page/sequence: For one student</label></td></tr>'."\n";   'The <b>complete</b> set/page/sequence: For one student</label></td></tr>'."\n";
   
     $result.='<tr bgcolor="#ffffe6"><td><br />'.      $result.='<tr bgcolor="#ffffe6"><td><br />'.
Line 5883  GRADINGMENUJS Line 6077  GRADINGMENUJS
  '<input type="button" onClick="javascript:checkChoice(this.form,\'3\',\'csvform\');" value="'.&mt('Upload').'" />'.   '<input type="button" onClick="javascript:checkChoice(this.form,\'3\',\'csvform\');" value="'.&mt('Upload').'" />'.
  ' '.&mt('scores from file').' </td></tr>'."\n";   ' '.&mt('scores from file').' </td></tr>'."\n";
   
       $result.='<tr bgcolor="#ffffe6"><td>'.
           '<input type="button" onClick="javascript:checkChoice(this.form,\'6\',\'processclicker\');" value="'.&mt('Process').'" />'.
           ' '.&mt('clicker file').' </td></tr>'."\n";
   
     $result.='<tr bgcolor="#ffffe6"valign="top"><td colspan="2">'.      $result.='<tr bgcolor="#ffffe6"valign="top"><td colspan="2">'.
  '<input type="button" onClick="javascript:checkChoice(this.form,\'4\',\'scantron_selectphase\');'.   '<input type="button" onClick="javascript:checkChoice(this.form,\'4\',\'scantron_selectphase\');'.
  '" value="'.&mt('Grade').'" /> scantron forms</td></tr>'."\n";   '" value="'.&mt('Grade').'" /> scantron forms</td></tr>'."\n";
Line 5902  GRADINGMENUJS Line 6100  GRADINGMENUJS
  '<input type="button" onClick="javascript:this.form.command.value=\'codelist\';this.form.action=\'/adm/pickcode\';this.form.submit();'.   '<input type="button" onClick="javascript:this.form.command.value=\'codelist\';this.form.action=\'/adm/pickcode\';this.form.submit();'.
  '" value="'.&mt('View').'" /> saved CODEs.</td></tr>'."\n";   '" value="'.&mt('View').'" /> saved CODEs.</td></tr>'."\n";
   
     $result.='</form></td></tr></table>'."\n".      $result.='</table>'."\n".
  '</td></tr></table>'."\n".   '</td></tr></table>'."\n".
  '</td></tr></table>'."\n";   '</td></tr></table></form>'."\n";
     return $result;      return $result;
 }  }
   
Line 5930  sub init_perm { Line 6128  sub init_perm {
     }      }
 }  }
   
   sub gather_clicker_ids {
       my %clicker_ids;
   
       my $classlist = &Apache::loncoursedata::get_classlist();
   
       # Set up a couple variables.
       my $username_idx = &Apache::loncoursedata::CL_SNAME();
       my $domain_idx   = &Apache::loncoursedata::CL_SDOM();
   
       foreach my $student (keys(%$classlist)) {
   
           my $username = $classlist->{$student}->[$username_idx];
           my $domain   = $classlist->{$student}->[$domain_idx];
           my $clickers =
       (&Apache::lonnet::userenvironment($domain,$username,'clickers'))[1];
           foreach my $id (split(/\,/,$clickers)) {
               $id=~s/^0+//;
               if (exists($clicker_ids{$id})) {
    $clicker_ids{$id}.=','.$username.':'.$domain;
               } else {
    $clicker_ids{$id}=$username.':'.$domain;
               }
           }
       }
       return %clicker_ids;
   }
   
   sub gather_adv_clicker_ids {
       my %clicker_ids;
       my $cnum=$env{'course.'.$env{'request.course.id'}.'.num'};
       my $cdom=$env{'course.'.$env{'request.course.id'}.'.domain'};
       my %coursepersonnel=&Apache::lonnet::get_course_adv_roles($cdom.'/'.$cnum);
       foreach my $element (sort(keys(%coursepersonnel))) {
           foreach my $person (split(/\,/,$coursepersonnel{$element})) {
               my ($puname,$pudom)=split(/\:/,$person);
               my $clickers =
    (&Apache::lonnet::userenvironment($pudom,$puname,'clickers'))[1];
               foreach my $id (split(/\,/,$clickers)) {
    $id=~s/^0+//;
    if (exists($clicker_ids{$id})) {
       $clicker_ids{$id}.=','.$puname.':'.$pudom;
    } else {
       $clicker_ids{$id}=$puname.':'.$pudom;
    }
               }
           }
       }
       return %clicker_ids;
   }
   
   sub process_clicker {
       my ($r)=@_;
       my ($symb)=&get_symb($r);
       if (!$symb) {return '';}
       my $result=&checkforfile_js();
       $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.='&nbsp;<b>'.&mt('Specify a file containing the clicker information for this resource').
           '.</b></td></tr>'."\n";
       $result.='<tr bgcolor=#ffffe6><td>'."\n";
       my $upload=&mt("Upload File");
       my $type=&mt("Type");
       my $attendance=&mt("Award points just for participation");
       my $personnel=&mt("Correctness determined from response by course personnel");
       my $specific=&mt("Correctness determined from response with clicker ID"); 
       my $pcorrect=&mt("Percentage points for correct solution");
       my $pincorrect=&mt("Percentage points for incorrect solution");
       my $selectform=&Apache::loncommon::select_form('iclicker','upfiletype',
      ('iclicker' => 'i>clicker'));
   
       $result.=<<ENDUPFORM;
   <script type="text/javascript">
   function sanitycheck() {
   // Accept only integer percentages
      document.forms.gradesupload.pcorrect.value=Math.round(document.forms.gradesupload.pcorrect.value);
      document.forms.gradesupload.pincorrect.value=Math.round(document.forms.gradesupload.pincorrect.value);
   // Find out grading choice
      for (i=0; i<document.forms.gradesupload.gradingmechanism.length; i++) {
         if (document.forms.gradesupload.gradingmechanism[i].checked) {
            gradingchoice=document.forms.gradesupload.gradingmechanism[i].value;
         }
      }
   // By default, new choice equals user selection
      newgradingchoice=gradingchoice;
   // Not good to give more points for false answers than correct ones
      if (Math.round(document.forms.gradesupload.pcorrect.value)<Math.round(document.forms.gradesupload.pincorrect.value)) {
         document.forms.gradesupload.pcorrect.value=document.forms.gradesupload.pincorrect.value;
      }
   // If new choice is attendance only, and old choice was correctness-based, restore defaults
      if ((gradingchoice=='attendance') && (document.forms.gradesupload.waschecked.value!='attendance')) {
         document.forms.gradesupload.pcorrect.value=100;
         document.forms.gradesupload.pincorrect.value=100;
      }
   // If the values are different, cannot be attendance only
      if ((Math.round(document.forms.gradesupload.pcorrect.value)!=Math.round(document.forms.gradesupload.pincorrect.value)) &&
          (gradingchoice=='attendance')) {
          newgradingchoice='personnel';
      }
   // Change grading choice to new one
      for (i=0; i<document.forms.gradesupload.gradingmechanism.length; i++) {
         if (document.forms.gradesupload.gradingmechanism[i].value==newgradingchoice) {
            document.forms.gradesupload.gradingmechanism[i].checked=true;
         } else {
            document.forms.gradesupload.gradingmechanism[i].checked=false;
         }
      }
   // Remember the old state
      document.forms.gradesupload.waschecked.value=newgradingchoice;
   }
   </script>
   <form method="post" enctype="multipart/form-data" action="/adm/grades" name="gradesupload">
   <input type="hidden" name="symb" value="$symb" />
   <input type="hidden" name="command" value="processclickerfile" />
   <input type="hidden" name="probTitle" value="$env{'form.probTitle'}" />
   <input type="hidden" name="saveState"  value="$env{'form.saveState'}" />
   <input type="file" name="upfile" size="50" />
   <br /><label>$type: $selectform</label>
   <br /><label>$attendance: <input type="radio" name="gradingmechanism" value="attendance" checked="checked" onClick="sanitycheck()" /></label>
   <br /><label>$personnel: <input type="radio" name="gradingmechanism" value="personnel" onClick="sanitycheck()" /></label>
   <br /><label>$specific: <input type="radio" name="gradingmechanism" value="specific" onClick="sanitycheck()" /></label>
   <input type="text" name="specificid" size="15" />
   <input type="hidden" name="waschecked" value="attendance" />
   <br /><label>$pcorrect: <input type="text" name="pcorrect" size="4" value="100" onChange="sanitycheck()" /></label>
   <br /><label>$pincorrect: <input type="text" name="pincorrect" size="4" value="100" onChange="sanitycheck()" /></label>
   <br /><input type="button" onClick="javascript:checkUpload(this.form);" value="$upload" />
   </form>
   ENDUPFORM
       $result.='</td></tr></table>'."\n".
                '</td></tr></table><br /><br />'."\n";
       $result.=&show_grading_menu_form($symb);
       return $result;
   }
   
   sub process_clicker_file {
       my ($r)=@_;
       my ($symb)=&get_symb($r);
       if (!$symb) {return '';}
       my ($result) = &showResourceInfo($symb,$env{'form.probTitle'});
       if (($env{'form.gradingmechanism'} eq 'specific') && ($env{'form.specificid'}!~/\w/)) {
    $result.='<span class="LC_error">'.&mt('You need to specify a clicker ID for the correct answer').'</span>';
    return $result.&show_grading_menu_form($symb);
       }
       my %clicker_ids=&gather_clicker_ids();
       my %correct_ids;
       if ($env{'form.gradingmechanism'} eq 'personnel') {
    %correct_ids=&gather_adv_clicker_ids();
       }
       if ($env{'form.gradingmechanism'} eq 'specific') {
    my $correct_id=$env{'form.specificid'};
    $correct_id=~tr/a-z/A-Z/;
    $correct_id=~s/\s//gs;
    $correct_id=~s/^0+//;
    $correct_ids{$correct_id}='specified';
       }
       if ($env{'form.gradingmechanism'} eq 'attendance') {
    $result.=&mt('Score based on attendance only');
       } else {
    my $number=0;
    $result.='<h3>'.&mt('Correctness determined by the following IDs').'</h3>';
    foreach my $id (sort(keys(%correct_ids))) {
       $result.='<tt>'.$id.'</tt> - ';
       if ($correct_ids{$id} eq 'specified') {
    $result.=&mt('specified');
       } else {
    my ($uname,$udom)=split(/\:/,$correct_ids{$id});
    $result.=&Apache::loncommon::plainname($uname,$udom);
       }
       $result.='<br />';
       $number++;
    }
    if ($number==0) {
       $result.='<span class="LC_error">'.&mt('No IDs found to determine correct answer').'</span>';
       return $result.&show_grading_menu_form($symb);
    }
       }
       if (length($env{'form.upfile'}) < 2) {
           $result.=&mt('[_1] Error: [_2] The file you attempted to upload, [_3] contained no information. Please check that you entered the correct filename.',
        '<span class="LC_error">',
        '</span>',
        '<span class="LC_filename">'.&HTML::Entities::encode($env{'form.upfile.filename'},'<>&"').'</span>');
           return $result.&show_grading_menu_form($symb);
       }
   
   # Were able to get all the info needed, now analyze the file
   
       my $heading=&mt('Scanning clicker file');
       $result.=(<<ENDHEADER);
   <br /><table width="100%" border="0"><tr><td bgcolor="#777777">
   <table width="100%" border="0"><tr bgcolor="#e6ffff"><td>
   <b>$heading</b></td></tr><tr bgcolor=#ffffe6><td>
   <form method="post" action="/adm/grades" name="clickeranalysis">
   <input type="hidden" name="symb" value="$symb" />
   <input type="hidden" name="command" value="assignclickergrades" />
   <input type="hidden" name="probTitle" value="$env{'form.probTitle'}" />
   <input type="hidden" name="saveState"  value="$env{'form.saveState'}" />
   ENDHEADER
       my %responses;
       my @questiontitles;
       my $errormsg='';
       my $number=0;
       if ($env{'form.upfiletype'} eq 'iclicker') {
    ($errormsg,$number)=&iclicker_eval(\@questiontitles,\%responses);
       }
       $result.='<br />'.&mt('Found [_1] question(s)',$number).'<br />';
       my $found_correct_flag=0;
       foreach my $id (keys(%responses)) {
          if ($correct_ids{$id}) {
             $result.="\n".'<input type="hidden" name="correct:'.$correct_ids{$id}.'" value="'.$responses{$id}.'" />';
             $found_correct_flag++;
          } elsif ($clicker_ids{$id}) {
             $result.="\n".'<input type="hidden" name="student:'.$clicker_ids{$id}.'" value="'.$responses{$id}.'" />';
          } else {
             $result.="\n<br />Unknown: ".$id." - ".$responses{$id};
          }
       }
       $result.='</form>';
       $result.='</td></tr></table>'."\n".
                '</td></tr></table><br /><br />'."\n";
       return $result.&show_grading_menu_form($symb);
   }
   
   sub iclicker_eval {
       my ($questiontitles,$responses)=@_;
       my $number=0;
       my $errormsg='';
       foreach my $line (split(/[\n\r]/,$env{'form.upfile'})) {
           my %components=&Apache::loncommon::record_sep($line);
           my @entries=map {$components{$_}} (sort(keys(%components)));
    if ($entries[0] eq 'Question') {
       for (my $i=3;$i<$#entries;$i+=6) {
    $$questiontitles[$number]=$entries[$i];
    $number++;
       }
    }
    if ($entries[0]=~/^\#/) {
       my $id=$entries[0];
       my @idresponses;
       $id=~s/^[\#0]+//;
       for (my $i=0;$i<$number;$i++) {
    my $idx=3+$i*6;
    push(@idresponses,$entries[$idx]);
       }
       $$responses{$id}=join(',',@idresponses);
    }
       }
       return ($errormsg,$number);
   }
   
 sub handler {  sub handler {
     my $request=$_[0];      my $request=$_[0];
   
Line 5997  sub handler { Line 6446  sub handler {
     $request->print(&editgrades($request));      $request->print(&editgrades($request));
  } elsif ($command eq 'verify' && $perm{'vgr'}) {   } elsif ($command eq 'verify' && $perm{'vgr'}) {
     $request->print(&verifyreceipt($request));      $request->print(&verifyreceipt($request));
           } elsif ($command eq 'processclicker' && $perm{'mgr'}) {
               $request->print(&process_clicker($request));
           } elsif ($command eq 'processclickerfile' && $perm{'mgr'}) {
               $request->print(&process_clicker_file($request));
  } elsif ($command eq 'csvform' && $perm{'mgr'}) {   } elsif ($command eq 'csvform' && $perm{'mgr'}) {
     $request->print(&upcsvScores_form($request));      $request->print(&upcsvScores_form($request));
  } elsif ($command eq 'csvupload' && $perm{'mgr'}) {   } elsif ($command eq 'csvupload' && $perm{'mgr'}) {

Removed from v.1.360  
changed lines
  Added in v.1.410


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.