Diff for /loncom/homework/grades.pm between versions 1.596.2.13 and 1.597

version 1.596.2.13, 2012/08/09 23:25:48 version 1.597, 2010/03/11 16:29:42
Line 40  use Apache::lonhomework; Line 40  use Apache::lonhomework;
 use Apache::lonpickcode;  use Apache::lonpickcode;
 use Apache::loncoursedata;  use Apache::loncoursedata;
 use Apache::lonmsg();  use Apache::lonmsg();
 use Apache::Constants qw(:common :http);  use Apache::Constants qw(:common);
 use Apache::lonlocal;  use Apache::lonlocal;
 use Apache::lonenc;  use Apache::lonenc;
 use Apache::bridgetask();  
 use String::Similarity;  use String::Similarity;
 use LONCAPA;  use LONCAPA;
   
Line 52  use POSIX qw(floor); Line 51  use POSIX qw(floor);
   
   
 my %perm=();  my %perm=();
 my %old_essays=();  
   
 #  These variables are used to recover from ssi errors  #  These variables are used to recover from ssi errors
   
Line 129  sub get_symb { Line 127  sub get_symb {
     my $symb=($env{'form.symb'} ne '' ? $env{'form.symb'} : (&Apache::lonnet::symbread($url)));      my $symb=($env{'form.symb'} ne '' ? $env{'form.symb'} : (&Apache::lonnet::symbread($url)));
     if ($symb eq '') {       if ($symb eq '') { 
  if (!$silent) {   if (!$silent) {
             $request->print(&mt("Unable to handle ambiguous references: [_1].",$url));      $request->print("Unable to handle ambiguous references:$url:.");
     return ();      return ();
  }   }
     }      }
Line 261  sub showResourceInfo { Line 259  sub showResourceInfo {
 sub reset_caches {  sub reset_caches {
     &reset_analyze_cache();      &reset_analyze_cache();
     &reset_perm();      &reset_perm();
     &reset_old_essays();  
 }  }
   
 {  {
Line 274  sub reset_caches { Line 271  sub reset_caches {
     }      }
   
     sub get_analyze {      sub get_analyze {
  my ($symb,$uname,$udom,$no_increment,$add_to_hash,$type,$trial,$rndseed)=@_;   my ($symb,$uname,$udom,$no_increment,$add_to_hash)=@_;
  my $key = "$symb\0$uname\0$udom";   my $key = "$symb\0$uname\0$udom";
         if ($type eq 'randomizetry') {  
             if ($trial ne '') {  
                 $key .= "\0".$trial;  
             }  
         }  
  if (exists($analyze_cache{$key})) {   if (exists($analyze_cache{$key})) {
             my $getupdate = 0;              my $getupdate = 0;
             if (ref($add_to_hash) eq 'HASH') {              if (ref($add_to_hash) eq 'HASH') {
Line 308  sub reset_caches { Line 300  sub reset_caches {
                     'grade_courseid'    =>  $env{'request.course.id'},                      'grade_courseid'    =>  $env{'request.course.id'},
                     'grade_username'    => $uname,                      'grade_username'    => $uname,
                     'grade_noincrement' => $no_increment);                      'grade_noincrement' => $no_increment);
         if ($type eq 'randomizetry') {  
             $form{'grade_questiontype'} = $type;  
             if ($rndseed ne '') {  
                 $form{'grade_rndseed'} = $rndseed;  
             }  
         }  
         if (ref($add_to_hash)) {          if (ref($add_to_hash)) {
             %form = (%form,%{$add_to_hash});              %form = (%form,%{$add_to_hash});
         }          } 
  my $subresult=&ssi_with_retries($url, $ssi_retries,%form);   my $subresult=&ssi_with_retries($url, $ssi_retries,%form);
  (undef,$subresult)=split(/_HASH_REF__/,$subresult,2);   (undef,$subresult)=split(/_HASH_REF__/,$subresult,2);
  my %analyze=&Apache::lonnet::str2hash($subresult);   my %analyze=&Apache::lonnet::str2hash($subresult);
Line 329  sub reset_caches { Line 315  sub reset_caches {
     }      }
   
     sub get_order {      sub get_order {
  my ($partid,$respid,$symb,$uname,$udom,$no_increment,$type,$trial,$rndseed)=@_;   my ($partid,$respid,$symb,$uname,$udom,$no_increment)=@_;
  my $analyze = &get_analyze($symb,$uname,$udom,$no_increment,undef,$type,$trial,$rndseed);   my $analyze = &get_analyze($symb,$uname,$udom,$no_increment);
  return $analyze->{"$partid.$respid.shown"};   return $analyze->{"$partid.$respid.shown"};
     }      }
   
     sub get_radiobutton_correct_foil {      sub get_radiobutton_correct_foil {
  my ($partid,$respid,$symb,$uname,$udom,$type,$trial,$rndseed)=@_;   my ($partid,$respid,$symb,$uname,$udom)=@_;
  my $analyze = &get_analyze($symb,$uname,$udom,undef,undef,$type,$trial,$rndseed);   my $analyze = &get_analyze($symb,$uname,$udom);
         my $foils = &get_order($partid,$respid,$symb,$uname,$udom,undef,$type,$trial,$rndseed);          my $foils = &get_order($partid,$respid,$symb,$uname,$udom);
         if (ref($foils) eq 'ARRAY') {          if (ref($foils) eq 'ARRAY') {
     foreach my $foil (@{$foils}) {      foreach my $foil (@{$foils}) {
         if ($analyze->{"$partid.$respid.foil.value.$foil"} eq 'true') {          if ($analyze->{"$partid.$respid.foil.value.$foil"} eq 'true') {
Line 379  sub reset_caches { Line 365  sub reset_caches {
 #        response types only.  #        response types only.
 sub cleanRecord {  sub cleanRecord {
     my ($answer,$response,$symb,$partid,$respid,$record,$order,$version,      my ($answer,$response,$symb,$partid,$respid,$record,$order,$version,
  $uname,$udom,$type,$trial,$rndseed) = @_;   $uname,$udom) = @_;
     my $grayFont = '<span class="LC_internal_info">';      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);
Line 396  sub cleanRecord { Line 382  sub cleanRecord {
  return '<blockquote><table border="1">'.   return '<blockquote><table border="1">'.
     '<tr valign="top"><td>'.&mt('Answer').'</td>'.$toprow.'</tr>'.      '<tr valign="top"><td>'.&mt('Answer').'</td>'.$toprow.'</tr>'.
     '<tr valign="top"><td>'.$grayFont.&mt('Option ID').'</span></td>'.      '<tr valign="top"><td>'.$grayFont.&mt('Option ID').'</span></td>'.
     $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);
  my %grading=&Apache::lonnet::str2hash($record->{$version."resource.$partid.$respid.submissiongrading"});   my %grading=&Apache::lonnet::str2hash($record->{$version."resource.$partid.$respid.submissiongrading"});
Line 418  sub cleanRecord { Line 404  sub cleanRecord {
     '<tr valign="top"><td>'.$grayFont.&mt('Item ID').'</span></td>'.      '<tr valign="top"><td>'.$grayFont.&mt('Item ID').'</span></td>'.
     $middlerow.'</tr>'.      $middlerow.'</tr>'.
     '<tr valign="top"><td>'.$grayFont.&mt('Option ID').'</span></td>'.      '<tr valign="top"><td>'.$grayFont.&mt('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);
  my ($toprow,$bottomrow);   my ($toprow,$bottomrow);
  my $correct =    my $correct = 
     &get_radiobutton_correct_foil($partid,$respid,$symb,$uname,$udom,$type,$trial,$rndseed);      &get_radiobutton_correct_foil($partid,$respid,$symb,$uname,$udom);
  foreach my $foil (@$order) {   foreach my $foil (@$order) {
     if (exists($answer{$foil})) {      if (exists($answer{$foil})) {
  if ($foil eq $correct) {   if ($foil eq $correct) {
Line 439  sub cleanRecord { Line 425  sub cleanRecord {
  return '<blockquote><table border="1">'.   return '<blockquote><table border="1">'.
     '<tr valign="top"><td>'.&mt('Answer').'</td>'.$toprow.'</tr>'.      '<tr valign="top"><td>'.&mt('Answer').'</td>'.$toprow.'</tr>'.
     '<tr valign="top"><td>'.$grayFont.&mt('Option ID').'</span></td>'.      '<tr valign="top"><td>'.$grayFont.&mt('Option ID').'</span></td>'.
     $bottomrow.'</tr></table></blockquote>';      $bottomrow.'</tr>'.'</table></blockquote>';
     } elsif ($response eq 'essay') {      } elsif ($response eq 'essay') {
  if (! exists ($env{'form.'.$symb})) {   if (! exists ($env{'form.'.$symb})) {
     my (%keyhash) = &Apache::lonnet::dump('nohist_handgrade',      my (%keyhash) = &Apache::lonnet::dump('nohist_handgrade',
Line 501  sub cleanRecord { Line 487  sub cleanRecord {
 #-- A couple of common js functions  #-- A couple of common js functions
 sub commonJSfunctions {  sub commonJSfunctions {
     my $request = shift;      my $request = shift;
     $request->print(<<COMMONJSFUNCTIONS);      $request->print(&Apache::lonhtmlcommon::scripttag(<<COMMONJSFUNCTIONS));
 <script type="text/javascript" language="javascript">  
     function radioSelection(radioButton) {      function radioSelection(radioButton) {
  var selection=null;   var selection=null;
  if (radioButton.length > 1) {   if (radioButton.length > 1) {
Line 530  sub commonJSfunctions { Line 515  sub commonJSfunctions {
     return selectOne.value;      return selectOne.value;
  }   }
     }      }
 </script>  
 COMMONJSFUNCTIONS  COMMONJSFUNCTIONS
 }  }
   
Line 685  sub student_gradeStatus { Line 669  sub student_gradeStatus {
 sub jscriptNform {  sub jscriptNform {
     my ($symb) = @_;      my ($symb) = @_;
     my $stu_status = join(':',&Apache::loncommon::get_env_multiple('form.Status'));      my $stu_status = join(':',&Apache::loncommon::get_env_multiple('form.Status'));
     my $jscript='<script type="text/javascript" language="javascript">'."\n".      my $jscript= &Apache::lonhtmlcommon::scripttag(
  '    function viewOneStudent(user,domain) {'."\n".   '    function viewOneStudent(user,domain) {'."\n".
  ' document.onestudent.student.value = user;'."\n".   ' document.onestudent.student.value = user;'."\n".
  ' document.onestudent.userdom.value = domain;'."\n".   ' document.onestudent.userdom.value = domain;'."\n".
  ' document.onestudent.submit();'."\n".   ' document.onestudent.submit();'."\n".
  '    }'."\n".   '    }'."\n".
  '</script>'."\n";   "\n");
     $jscript.= '<form action="/adm/grades" method="post" name="onestudent">'."\n".      $jscript.= '<form action="/adm/grades" method="post" name="onestudent">'."\n".
  '<input type="hidden" name="symb"    value="'.&Apache::lonenc::check_encrypt($symb).'" />'."\n".   '<input type="hidden" name="symb"    value="'.&Apache::lonenc::check_encrypt($symb).'" />'."\n".
  '<input type="hidden" name="saveState" value="'.$env{'form.saveState'}.'" />'."\n".   '<input type="hidden" name="saveState" value="'.$env{'form.saveState'}.'" />'."\n".
Line 740  sub compute_points { Line 724  sub compute_points {
 #  #
   
 sub most_similar {  sub most_similar {
     my ($uname,$udom,$symb,$uessay)=@_;      my ($uname,$udom,$uessay,$old_essays)=@_;
   
     unless ($symb) { return ''; }  
   
     unless (ref($old_essays{$symb}) eq 'HASH') { return ''; }  
   
 # ignore spaces and punctuation  # ignore spaces and punctuation
   
Line 752  sub most_similar { Line 732  sub most_similar {
   
 # ignore empty submissions (occuring when only files are sent)  # ignore empty submissions (occuring when only files are sent)
   
     unless ($uessay=~/\w+/s) { return ''; }      unless ($uessay=~/\w+/) { return ''; }
   
 # these will be returned. Do not care if not at least 50 percent similar  # these will be returned. Do not care if not at least 50 percent similar
     my $limit=0.6;      my $limit=0.6;
Line 761  sub most_similar { Line 741  sub most_similar {
     my $scrsid='';      my $scrsid='';
     my $sessay='';      my $sessay='';
 # go through all essays ...  # go through all essays ...
     foreach my $tkey (keys(%{$old_essays{$symb}})) {      foreach my $tkey (keys(%$old_essays)) {
  my ($tname,$tdom,$tcrsid)=map {&unescape($_)} (split(/\./,$tkey));   my ($tname,$tdom,$tcrsid)=map {&unescape($_)} (split(/\./,$tkey));
 # ... except the same student  # ... except the same student
         next if (($tname eq $uname) && ($tdom eq $udom));          next if (($tname eq $uname) && ($tdom eq $udom));
  my $tessay=$old_essays{$symb}{$tkey};   my $tessay=$old_essays->{$tkey};
  $tessay=~s/\W+/ /gs;   $tessay=~s/\W+/ /gs;
 # String similarity gives up if not even limit  # String similarity gives up if not even limit
  my $tsimilar=&String::Similarity::similarity($uessay,$tessay,$limit);   my $tsimilar=&String::Similarity::similarity($uessay,$tessay,$limit);
Line 775  sub most_similar { Line 755  sub most_similar {
     $sname=$tname;      $sname=$tname;
     $sdom=$tdom;      $sdom=$tdom;
     $scrsid=$tcrsid;      $scrsid=$tcrsid;
     $sessay=$old_essays{$symb}{$tkey};      $sessay=$old_essays->{$tkey};
  }   }
     }      }
     if ($limit>0.6) {      if ($limit>0.6) {
Line 904  sub listStudents { Line 884  sub listStudents {
  'multiple' => 'Please select a student or group of students before clicking on the Next button.',   'multiple' => 'Please select a student or group of students before clicking on the Next button.',
  'single'   => 'Please select the student before clicking on the Next button.',   'single'   => 'Please select the student before clicking on the Next button.',
      );       );
     $request->print(<<LISTJAVASCRIPT);      $request->print(&Apache::lonhtmlcommon::scripttag(<<LISTJAVASCRIPT));
 <script type="text/javascript" language="javascript">  
     function checkSelect(checkBox) {      function checkSelect(checkBox) {
  var ctr=0;   var ctr=0;
  var sense="";   var sense="";
Line 934  sub listStudents { Line 913  sub listStudents {
  formname.command.value = 'submission';   formname.command.value = 'submission';
  formname.submit();   formname.submit();
     }      }
 </script>  
 LISTJAVASCRIPT  LISTJAVASCRIPT
   
     &commonJSfunctions($request);      &commonJSfunctions($request);
Line 1170  LISTJAVASCRIPT Line 1148  LISTJAVASCRIPT
   
 sub check_script {  sub check_script {
     my ($form, $type)=@_;      my ($form, $type)=@_;
     my $chkallscript='<script type="text/javascript">      my $chkallscript= &Apache::lonhtmlcommon::scripttag('
     function checkall() {      function checkall() {
         for (i=0; i<document.forms.'.$form.'.elements.length; i++) {          for (i=0; i<document.forms.'.$form.'.elements.length; i++) {
             ele = document.forms.'.$form.'.elements[i];              ele = document.forms.'.$form.'.elements[i];
Line 1201  sub check_script { Line 1179  sub check_script {
         }          }
     }      }
   
 </script>'."\n";  '."\n");
     return $chkallscript;      return $chkallscript;
 }  }
   
Line 1240  sub processGroup { Line 1218  sub processGroup {
 sub sub_page_js {  sub sub_page_js {
     my $request = shift;      my $request = shift;
     my $alertmsg = &mt('A number equal or greater than 0 is expected. Entered value = ');      my $alertmsg = &mt('A number equal or greater than 0 is expected. Entered value = ');
     $request->print(<<SUBJAVASCRIPT);      $request->print(&Apache::lonhtmlcommon::scripttag(<<SUBJAVASCRIPT));
 <script type="text/javascript" language="javascript">  
     function updateRadio(formname,id,weight) {      function updateRadio(formname,id,weight) {
  var gradeBox = formname["GD_BOX"+id];   var gradeBox = formname["GD_BOX"+id];
  var radioButton = formname["RADVAL"+id];   var radioButton = formname["RADVAL"+id];
Line 1409  sub sub_page_js { Line 1386  sub sub_page_js {
   
  formname.submit();   formname.submit();
     }      }
 </script>  
 SUBJAVASCRIPT  SUBJAVASCRIPT
 }  }
   
Line 1419  sub sub_page_kw_js { Line 1395  sub sub_page_kw_js {
     my $iconpath = $request->dir_config('lonIconsURL');      my $iconpath = $request->dir_config('lonIconsURL');
     &commonJSfunctions($request);      &commonJSfunctions($request);
   
     my $inner_js_msg_central=<<INNERJS;      my $inner_js_msg_central= &Apache::lonhtmlcommon::scripttag(<<INNERJS);
     <script text="text/javascript">  
     function checkInput() {      function checkInput() {
       opener.document.SCORE.msgsub.value = opener.checkEntities(document.msgcenter.msgsub.value);        opener.document.SCORE.msgsub.value = opener.checkEntities(document.msgcenter.msgsub.value);
       var nmsg   = opener.document.SCORE.savemsgN.value;        var nmsg   = opener.document.SCORE.savemsgN.value;
Line 1457  sub sub_page_kw_js { Line 1432  sub sub_page_kw_js {
       self.close()        self.close()
   
     }      }
     </script>  
 INNERJS  INNERJS
   
     my $inner_js_highlight_central=<<INNERJS;      my $inner_js_highlight_central= &Apache::lonhtmlcommon::scripttag(<<INNERJS);
  <script type="text/javascript">  
     function updateChoice(flag) {      function updateChoice(flag) {
       opener.document.SCORE.kwclr.value = opener.radioSelection(document.hlCenter.kwdclr);        opener.document.SCORE.kwclr.value = opener.radioSelection(document.hlCenter.kwdclr);
       opener.document.SCORE.kwsize.value = opener.radioSelection(document.hlCenter.kwdsize);        opener.document.SCORE.kwsize.value = opener.radioSelection(document.hlCenter.kwdsize);
Line 1472  INNERJS Line 1445  INNERJS
       }        }
       self.close()        self.close()
     }      }
 </script>  
 INNERJS  INNERJS
   
     my $start_page_msg_central =       my $start_page_msg_central = 
Line 1495  INNERJS Line 1467  INNERJS
   
     my $docopen=&Apache::lonhtmlcommon::javascript_docopen();      my $docopen=&Apache::lonhtmlcommon::javascript_docopen();
     $docopen=~s/^document\.//;      $docopen=~s/^document\.//;
     my %lt = &Apache::lonlocal::texthash(      my $alertmsg = &mt('Please select a word or group of words from document and then click this link.');
                 keyw => 'Keywords list, separated by a space. Add/delete to list if desired.',      $request->print(&Apache::lonhtmlcommon::scripttag(<<SUBJAVASCRIPT));
                 plse => 'Please select a word or group of words from document and then click this link.',  
                 adds => 'Add selection to keyword list? Edit if desired.',  
                 comp => 'Compose Message for: ',  
                 incl => 'Include',  
                 type => 'Type',  
                 subj => 'Subject',  
                 mesa => 'Message',  
                 new  => 'New',  
                 save => 'Save',  
                 canc => 'Cancel',  
                 kehi => 'Keyword Highlight Options',  
                 txtc => 'Text Color',  
                 font => 'Font Size',  
                 fnst => 'Font Style',  
              );  
     $request->print(<<SUBJAVASCRIPT);  
 <script type="text/javascript" language="javascript">  
   
 //===================== Show list of keywords ====================  //===================== Show list of keywords ====================
   function keywords(formname) {    function keywords(formname) {
     var nret = prompt("$lt{'keyw'}",formname.keywords.value);      var nret = prompt("Keywords list, separated by a space. Add/delete to list if desired.",formname.keywords.value);
     if (nret==null) return;      if (nret==null) return;
     formname.keywords.value = nret;      formname.keywords.value = nret;
   
Line 1544  INNERJS Line 1499  INNERJS
     else return;      else return;
     var cleantxt = txt.replace(new RegExp('([\\f\\n\\r\\t\\v ])+', 'g')," ");      var cleantxt = txt.replace(new RegExp('([\\f\\n\\r\\t\\v ])+', 'g')," ");
     if (cleantxt=="") {      if (cleantxt=="") {
  alert("$lt{'plse'}");   alert("$alertmsg");
  return;   return;
     }      }
     var nret = prompt("$lt{'adds'}",cleantxt);      var nret = prompt("Add selection to keyword list? Edit if desired.",cleantxt);
     if (nret==null) return;      if (nret==null) return;
     document.SCORE.keywords.value = document.SCORE.keywords.value+" "+nret;      document.SCORE.keywords.value = document.SCORE.keywords.value+" "+nret;
     if (document.SCORE.keywords.value != "") {      if (document.SCORE.keywords.value != "") {
Line 1621  INNERJS Line 1576  INNERJS
     var ypos = (screen.height-height)/2-30;      var ypos = (screen.height-height)/2-30;
     ypos = (ypos < 0) ? '0' : ypos;      ypos = (ypos < 0) ? '0' : ypos;
   
     pWin = window.open('', 'MessageCenter', 'resizable=yes,toolbar=no,location=no,scrollbars='+scrollbar+',screenx='+xpos+',screeny='+ypos+',width=700,height='+height);      pWin = window.open('', 'MessageCenter', 'resizable=yes,toolbar=no,location=no,scrollbars='+scrollbar+',screenx='+xpos+',screeny='+ypos+',width=600,height='+height);
     pWin.focus();      pWin.focus();
     pDoc = pWin.document;      pDoc = pWin.document;
     pDoc.$docopen;      pDoc.$docopen;
Line 1629  INNERJS Line 1584  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("<h3><span class=\\"LC_info\\">&nbsp;$lt{'comp'}\"+fullname+\"<\\/span><\\/h3><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">');
     pDoc.write("<td><b>$lt{'type'}<\\/b><\\/td><td><b>$lt{'incl'}<\\/b><\\/td><td><b>$lt{'mesa'}<\\/td><\\/tr>");      pDoc.write("<td><b>Type<\\/b><\\/td><td><b>Include<\\/b><\\/td><td><b>Message<\\/td><\\/tr>");
 }  }
     function displaySubject(msg,shwsel) {      function displaySubject(msg,shwsel) {
     pDoc = pWin.document;      pDoc = pWin.document;
     pDoc.write("<tr bgcolor=\\"#ffffdd\\">");      pDoc.write("<tr bgcolor=\\"#ffffdd\\">");
     pDoc.write("<td>$lt{'subj'}<\\/td>");      pDoc.write("<td>Subject<\\/td>");
     pDoc.write("<td align=\\"center\\"><input name=\\"subchk\\" type=\\"checkbox\\"" +shwsel+"><\\/td>");      pDoc.write("<td align=\\"center\\"><input name=\\"subchk\\" type=\\"checkbox\\"" +shwsel+"><\\/td>");
     pDoc.write("<td><input name=\\"msgsub\\" type=\\"text\\" value=\\""+msg+"\\"size=\\"60\\" maxlength=\\"80\\"><\\/td><\\/tr>");      pDoc.write("<td><input name=\\"msgsub\\" type=\\"text\\" value=\\""+msg+"\\"size=\\"60\\" maxlength=\\"80\\"><\\/td><\\/tr>");
 }  }
Line 1654  INNERJS Line 1609  INNERJS
   function newMsg(newmsg,shwsel) {    function newMsg(newmsg,shwsel) {
     pDoc = pWin.document;      pDoc = pWin.document;
     pDoc.write("<tr bgcolor=\\"#ffffdd\\">");      pDoc.write("<tr bgcolor=\\"#ffffdd\\">");
     pDoc.write("<td align=\\"center\\">$lt{'new'}<\\/td>");      pDoc.write("<td align=\\"center\\">New<\\/td>");
     pDoc.write("<td align=\\"center\\"><input name=\\"newmsgchk\\" type=\\"checkbox\\"" +shwsel+"><\\/td>");      pDoc.write("<td align=\\"center\\"><input name=\\"newmsgchk\\" type=\\"checkbox\\"" +shwsel+"><\\/td>");
     pDoc.write("<td><textarea name=\\"newmsg\\" cols=\\"60\\" rows=\\"3\\" onchange=\\"javascript:this.form.newmsgchk.checked=true\\" >"+newmsg+"<\\/textarea><\\/td><\\/tr>");      pDoc.write("<td><textarea name=\\"newmsg\\" cols=\\"60\\" rows=\\"3\\" onchange=\\"javascript:this.form.newmsgchk.checked=true\\" >"+newmsg+"<\\/textarea><\\/td><\\/tr>");
 }  }
Line 1663  INNERJS Line 1618  INNERJS
     pDoc = pWin.document;      pDoc = pWin.document;
     pDoc.write("<\\/table>");      pDoc.write("<\\/table>");
     pDoc.write("<\\/td><\\/tr><\\/table>&nbsp;");      pDoc.write("<\\/td><\\/tr><\\/table>&nbsp;");
     pDoc.write("<input type=\\"button\\" value=\\"$lt{'save'}\\" onclick=\\"javascript:checkInput()\\">&nbsp;&nbsp;");      pDoc.write("<input type=\\"button\\" value=\\"Save\\" onclick=\\"javascript:checkInput()\\">&nbsp;&nbsp;");
     pDoc.write("<input type=\\"button\\" value=\\"$lt{'canc'}\\" onclick=\\"self.close()\\"><br /><br />");      pDoc.write("<input type=\\"button\\" value=\\"Cancel\\" onclick=\\"self.close()\\"><br /><br />");
     pDoc.write("<\\/form>");      pDoc.write("<\\/form>");
     pDoc.write('$end_page_msg_central');      pDoc.write('$end_page_msg_central');
     pDoc.close();      pDoc.close();
Line 1714  INNERJS Line 1669  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("<h3><span class=\\"LC_info\\">&nbsp;$lt{'kehi'}<\\/span><\\/h3><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">');
     hDoc.write("<td><b>$lt{'txtc'}<\\/b><\\/td><td><b>$lt{'font'}<\\/b><\\/td><td><b>$lt{'fnst'}<\\/td><\\/tr>");      hDoc.write("<td><b>Text Color<\\/b><\\/td><td><b>Font Size<\\/b><\\/td><td><b>Font Style<\\/td><\\/tr>");
   }    }
   
   function highlightbody(clrval,clrtxt,clrsel,szval,sztxt,szsel,syval,sytxt,sysel) {     function highlightbody(clrval,clrtxt,clrsel,szval,sztxt,szsel,syval,sytxt,sysel) { 
Line 1737  INNERJS Line 1692  INNERJS
     var hDoc = hwdWin.document;      var hDoc = hwdWin.document;
     hDoc.write("<\\/table>");      hDoc.write("<\\/table>");
     hDoc.write("<\\/td><\\/tr><\\/table>&nbsp;");      hDoc.write("<\\/td><\\/tr><\\/table>&nbsp;");
     hDoc.write("<input type=\\"button\\" value=\\"$lt{'save'}\\" onclick=\\"javascript:updateChoice(1)\\">&nbsp;&nbsp;");      hDoc.write("<input type=\\"button\\" value=\\"Save\\" onclick=\\"javascript:updateChoice(1)\\">&nbsp;&nbsp;");
     hDoc.write("<input type=\\"button\\" value=\\"$lt{'canc'}\\" onclick=\\"self.close()\\"><br /><br />");      hDoc.write("<input type=\\"button\\" value=\\"Cancel\\" onclick=\\"self.close()\\"><br /><br />");
     hDoc.write("<\\/form>");      hDoc.write("<\\/form>");
     hDoc.write('$end_page_highlight_central');      hDoc.write('$end_page_highlight_central');
     hDoc.close();      hDoc.close();
   }    }
   
 </script>  
 SUBJAVASCRIPT  SUBJAVASCRIPT
 }  }
   
Line 1855  sub handback_box { Line 1809  sub handback_box {
     my ($symb,$uname,$udom,$counter,$partid,$record,$res_error) = @_;      my ($symb,$uname,$udom,$counter,$partid,$record,$res_error) = @_;
     my ($partlist,$handgrade,$responseType) = &response_type($symb,$res_error);      my ($partlist,$handgrade,$responseType) = &response_type($symb,$res_error);
     my (@respids);      my (@respids);
     my @part_response_id = &flatten_responseType($responseType);       my @part_response_id = &flatten_responseType($responseType);
     foreach my $part_response_id (@part_response_id) {      foreach my $part_response_id (@part_response_id) {
     my ($part,$resp) = @{ $part_response_id };      my ($part,$resp) = @{ $part_response_id };
         if ($part eq $partid) {          if ($part eq $partid) {
Line 1867  sub handback_box { Line 1821  sub handback_box {
  my $prefix = $counter.'_'.$partid.'_'.$respid.'_';   my $prefix = $counter.'_'.$partid.'_'.$respid.'_';
  my $files=&get_submitted_files($udom,$uname,$partid,$respid,$record);   my $files=&get_submitted_files($udom,$uname,$partid,$respid,$record);
  next if (!@$files);   next if (!@$files);
  my $file_counter = 0;   my $file_counter = 1;
  foreach my $file (@$files) {   foreach my $file (@$files) {
     if ($file =~ /\/portfolio\//) {      if ($file =~ /\/portfolio\//) {
                 $file_counter++;  
            my ($file_path, $file_disp) = ($file =~ m|(.+/)(.+)$|);             my ($file_path, $file_disp) = ($file =~ m|(.+/)(.+)$|);
            my ($name,$version,$ext) = &file_name_version_ext($file_disp);             my ($name,$version,$ext) = &file_name_version_ext($file_disp);
            $file_disp = "$name.$ext";             $file_disp = "$name.$ext";
Line 1878  sub handback_box { Line 1831  sub handback_box {
            $result.=&mt('Return commented version of [_1] to student.',             $result.=&mt('Return commented version of [_1] to student.',
     '<span class="LC_filename">'.$file_disp.'</span>');      '<span class="LC_filename">'.$file_disp.'</span>');
            $result.='<input type="file"   name="'.$prefix.'returndoc'.$file_counter.'" />'."\n";             $result.='<input type="file"   name="'.$prefix.'returndoc'.$file_counter.'" />'."\n";
            $result.='<input type="hidden" name="'.$prefix.'origdoc'.$file_counter.'" value="'.$file.'" /><br />'."\n";             $result.='<input type="hidden" name="'.$prefix.'origdoc'.$file_counter.'" value="'.$file.'" /><br />';
              $result.='('.&mt('File will be uploaded when you click on Save &amp; Next below.').')<br />';
              $file_counter++;
     }      }
  }   }
         if ($file_counter) {  
             $result .= '<input type="hidden" name="'.$prefix.'countreturndoc" value="'.$file_counter.'" />'."\n".  
                        '<span class="LC_info">'.  
                        '('.&mt('File(s) will be uploaded when you click on Save &amp; Next below.',$file_counter).')</span><br /><br />';  
         }  
     }      }
     return $result;          return $result;    
 }  }
Line 2015  sub submission { Line 1965  sub submission {
  '" src="'.$request->dir_config('lonIconsURL').   '" src="'.$request->dir_config('lonIconsURL').
  '/check.gif" height="16" border="0" />';   '/check.gif" height="16" border="0" />';
   
       my %old_essays;
     # header info      # header info
     if ($counter == 0) {      if ($counter == 0) {
  &sub_page_js($request);   &sub_page_js($request);
Line 2106  sub submission { Line 2057  sub submission {
  $request->print($prnmsg);   $request->print($prnmsg);
   
  if ($env{'form.handgrade'} eq 'yes' && $env{'form.showgrading'} eq 'yes') {   if ($env{'form.handgrade'} eq 'yes' && $env{'form.showgrading'} eq 'yes') {
   
             my %lt = &Apache::lonlocal::texthash(  
                           keyw => 'Keyword Options',  
                           list => 'List',  
                           past => 'Paste Selection to List',  
                           high => 'Highlight Attribute',  
                      );  
 #  #
 # Print out the keyword options line  # Print out the keyword options line
 #  #
     $request->print(<<KEYWORDS);      $request->print(<<KEYWORDS);
 &nbsp;<b>$lt{'keyw'}:</b>&nbsp;  &nbsp;<b>Keyword Options:</b>&nbsp;
 <a href="javascript:keywords(document.SCORE);" target="_self">$lt{'list'}</a>&nbsp; &nbsp;  <a href="javascript:keywords(document.SCORE);" target="_self">List</a>&nbsp; &nbsp;
 <a href="#" onmousedown="javascript:getSel(); return false"  <a href="#" onmousedown="javascript:getSel(); return false"
  CLASS="page">$lt{'past'}</a>&nbsp; &nbsp;   CLASS="page">Paste Selection to List</a>&nbsp; &nbsp;
 <a href="javascript:kwhighlight();" target="_self">$lt{'high'}</a><br /><br />  <a href="javascript:kwhighlight();" target="_self">Highlight Attribute</a><br /><br />
 KEYWORDS  KEYWORDS
 #  #
 # Load the other essays for similarity check  # Load the other essays for similarity check
Line 2130  KEYWORDS Line 2074  KEYWORDS
     my ($adom,$aname,$apath)=($essayurl=~/^($LONCAPA::domain_re)\/($LONCAPA::username_re)\/(.*)$/);      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;
     &init_old_essays($symb,$apath,$adom,$aname);      %old_essays=&Apache::lonnet::dump('nohist_essay_'.$apath,$adom,$aname);
         }          }
     }      }
   
Line 2248  KEYWORDS Line 2192  KEYWORDS
                     $lastsubonly.="\n".'<div class="LC_grade_submission_part">'.                      $lastsubonly.="\n".'<div class="LC_grade_submission_part">'.
                         '<b>'.&mt('Part: [_1]',$display_part).'</b>'.                          '<b>'.&mt('Part: [_1]',$display_part).'</b>'.
                         ' <span class="LC_internal_info">'.                          ' <span class="LC_internal_info">'.
                         '('.&mt('Response ID: [_1]',$respid).')'.                          '('.&mt('Part ID: [_1]',$respid).')'.
                         '</span>&nbsp; &nbsp;'.                          '</span>&nbsp; &nbsp;'.
  '<span class="LC_warning">'.&mt('Nothing submitted - no attempts.').'</span><br /><br /></div>';   '<span class="LC_warning">'.&mt('Nothing submitted - no attempts.').'</span><br /><br /></div>';
     next;      next;
Line 2259  KEYWORDS Line 2203  KEYWORDS
     my ($ressub,$hide,$subval) = split(/:/,$submission,3);      my ($ressub,$hide,$subval) = split(/:/,$submission,3);
     # Similarity check      # Similarity check
     my $similar='';      my $similar='';
                     my ($type,$trial,$rndseed);  
                     if ($hide eq 'rand') {  
                         $type = 'randomizetry';  
                         $trial = $record{"resource.$partid.tries"};  
                         $rndseed = $record{"resource.$partid.rndseed"};  
                     }  
     if($env{'form.checkPlag'}){      if($env{'form.checkPlag'}){
  my ($oname,$odom,$ocrsid,$oessay,$osim)=   my ($oname,$odom,$ocrsid,$oessay,$osim)=
     &most_similar($uname,$udom,$symb,$subval);      &most_similar($uname,$udom,$subval,\%old_essays);
  if ($osim) {   if ($osim) {
     $osim=int($osim*100.0);      $osim=int($osim*100.0);
     my %old_course_desc =       my %old_course_desc = 
  &Apache::lonnet::coursedescription($ocrsid,   &Apache::lonnet::coursedescription($ocrsid,
    {'one_time' => 1});     {'one_time' => 1});
   
                             if ($hide eq 'anon') {                              if ($hide) {
                                 $similar='<hr /><span class="LC_warning">'.&mt("Essay was found to be similar to another essay submitted for this assignment.").'<br />'.                                  $similar='<hr /><span class="LC_warning">'.&mt("Essay was found to be similar to another essay submitted for this assignment.").'<br />'.
                                          &mt('As the current submission is for an anonymous survey, no other details are available.').'</span><hr />';                                           &mt('As the current submission is for an anonymous survey, no other details are available.').'</span><hr />';
                             } else {                              } else {
Line 2291  KEYWORDS Line 2229  KEYWORDS
                             }                              }
  }   }
     }      }
     my $order=&get_order($partid,$respid,$symb,$uname,$udom,      my $order=&get_order($partid,$respid,$symb,$uname,$udom);
                                          undef,$type,$trial,$rndseed);  
     if ($env{'form.lastSub'} eq 'lastonly' ||       if ($env{'form.lastSub'} eq 'lastonly' || 
  ($env{'form.lastSub'} eq 'hdgrade' &&    ($env{'form.lastSub'} eq 'hdgrade' && 
  $$handgrade{$$part[0].'_'.$$part[1]} eq 'yes')) {   $$handgrade{$$part[0].'_'.$$part[1]} eq 'yes')) {
Line 2300  KEYWORDS Line 2237  KEYWORDS
                         $lastsubonly.='<div class="LC_grade_submission_part">'.                          $lastsubonly.='<div class="LC_grade_submission_part">'.
                             '<b>'.&mt('Part: [_1]',$display_part).'</b>'.                              '<b>'.&mt('Part: [_1]',$display_part).'</b>'.
                             ' <span class="LC_internal_info">'.                              ' <span class="LC_internal_info">'.
                             '('.&mt('Response ID: [_1]',$respid).')'.                              '('.&mt('Part ID: [_1]',$respid).')'.
                             '</span>&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) {
                             if ($hide eq 'anon') {                              if ($hide) {
                                 $lastsubonly.='<br />'.&mt('[quant,_1,file] uploaded to this anonymous survey',scalar(@{$files}));                                  $lastsubonly.='<br />'.&mt('[quant,_1,file] uploaded to this anonymous survey',scalar(@{$files}));
                             } else {                              } else {
                                 $lastsubonly.='<br /><span class="LC_warning">'.&mt('Like all files provided by users, this file may contain viruses').'</span><br />';                                  $lastsubonly.='<br /><span class="LC_warning">'.&mt('Like all files provided by users, this file may contain viruses').'</span><br />';
Line 2315  KEYWORDS Line 2252  KEYWORDS
                             }                              }
     $lastsubonly.='<br />';      $lastsubonly.='<br />';
  }   }
                         if ($hide eq 'anon') {                          if ($hide) {
                             $lastsubonly.='<b>'.&mt('Anonymous Survey').'</b>';                               $lastsubonly.='<b>'.&mt('Anonymous Survey').'</b>'; 
                         } else {                          } else {
     $lastsubonly.='<b>'.&mt('Submitted Answer:').' </b>'.      $lastsubonly.='<b>'.&mt('Submitted Answer:').' </b>'.
         &cleanRecord($subval,$responsetype,$symb,$partid,          &cleanRecord($subval,$responsetype,$symb,$partid,
      $respid,\%record,$order,undef,$uname,$udom,$type,$trial,$rndseed);       $respid,\%record,$order,undef,$uname,$udom);
                         }                          }
  if ($similar) {$lastsubonly.="<br /><br />$similar\n";}   if ($similar) {$lastsubonly.="<br /><br />$similar\n";}
  $lastsubonly.='</div>';   $lastsubonly.='</div>';
Line 2470  sub check_collaborators { Line 2407  sub check_collaborators {
  next if ($record->{'resource.'.$part.'.collaborators'} eq '');   next if ($record->{'resource.'.$part.'.collaborators'} eq '');
  my (@good_collaborators, @bad_collaborators);   my (@good_collaborators, @bad_collaborators);
  foreach my $possible_collaborator   foreach my $possible_collaborator
     (split(/[,;\s]+/,$record->{'resource.'.$part.'.collaborators'})) {       (split(/,?\s+/,$record->{'resource.'.$part.'.collaborators'})) { 
     $possible_collaborator =~ s/[\$\^\(\)]//g;      $possible_collaborator =~ s/[\$\^\(\)]//g;
     next if ($possible_collaborator eq '');      next if ($possible_collaborator eq '');
     my ($co_name,$co_dom) = split(/:/,$possible_collaborator);      my ($co_name,$co_dom) = split(/\@|:/,$possible_collaborator);
     $co_dom = $udom if (! defined($co_dom) || $co_dom =~ /^domain$/i);      $co_dom = $udom if (! defined($co_dom) || $co_dom =~ /^domain$/i);
     next if ($co_name eq $uname && $co_dom eq $udom);      next if ($co_name eq $uname && $co_dom eq $udom);
     # Doing this grep allows 'fuzzy' specification      # Doing this grep allows 'fuzzy' specification
Line 2486  sub check_collaborators { Line 2423  sub check_collaborators {
     }      }
  }   }
  if (scalar(@good_collaborators) != 0) {   if (scalar(@good_collaborators) != 0) {
     $result.='<br />'.&mt('Collaborators:').'<ol>';      $result.='<br />'.&mt('Collaborators: ');
     foreach my $name (@good_collaborators) {      foreach my $name (@good_collaborators) {
  my ($lastname,$givenn) = split(/,/,$$fullname{$name});   my ($lastname,$givenn) = split(/,/,$$fullname{$name});
  push(@col_fullnames, $givenn.' '.$lastname);   push(@col_fullnames, $givenn.' '.$lastname);
  $result.='<li>'.$fullname->{$name}.'</li>';   $result.=$fullname->{$name}.'&nbsp; &nbsp; &nbsp;';
     }      }
     $result.='</ol><br />'."\n";      $result.='<br />'."\n";
     my ($part)=split(/\./,$part);      my ($part)=split(/\./,$part);
     $result.='<input type="hidden" name="collaborator'.$counter.      $result.='<input type="hidden" name="collaborator'.$counter.
  '" value="'.$part.':'.(join ':',@good_collaborators).'" />'.   '" value="'.$part.':'.(join ':',@good_collaborators).'" />'.
Line 2528  sub get_last_submission { Line 2465  sub get_last_submission {
     &Apache::lonlocal::locallocaltime($$returnhash{$version.':timestamp'});      &Apache::lonlocal::locallocaltime($$returnhash{$version.':timestamp'});
     }      }
  }   }
         my (%typeparts,%randombytry);          my %typeparts;
         my $showsurv =           my $showsurv = 
             &Apache::lonnet::allowed('vas',$env{'request.course.id'});              &Apache::lonnet::allowed('vas',$env{'request.course.id'});
         foreach my $key (sort(keys(%lasthash))) {          foreach my $key (sort(keys(%lasthash))) {
             if ($key =~ /\.type$/) {              if ($key =~ /\.type$/) {
                 if (($lasthash{$key} eq 'anonsurvey') ||                   if (($lasthash{$key} eq 'anonsurvey') || 
                     ($lasthash{$key} eq 'anonsurveycred') ||                      ($lasthash{$key} eq 'anonsurveycred')) {
                     ($lasthash{$key} eq 'randomizetry')) {  
                     my ($ign,@parts) = split(/\./,$key);                      my ($ign,@parts) = split(/\./,$key);
                     pop(@parts);                      pop(@parts);
                     my $id = join('.',@parts);                      unless ($showsurv) {
                     if ($lasthash{$key} eq 'randomizetry') {                          my $id = join(',',@parts);
                         $randombytry{$ign.'.'.$id} = $lasthash{$key};                          $typeparts{$ign.'.'.$id} = $lasthash{$key};
                     } else {  
                         unless ($showsurv) {  
                             $typeparts{$ign.'.'.$id} = $lasthash{$key};  
                         }  
                     }                      }
                     delete($lasthash{$key});                      delete($lasthash{$key});
                 }                  }
             }              }
         }          }
         my @hidden = keys(%typeparts);          my @hidden = keys(%typeparts);
         my @randomize = keys(%randombytry);  
  foreach my $key (keys(%lasthash)) {   foreach my $key (keys(%lasthash)) {
     next if ($key !~ /\.submission$/);      next if ($key !~ /\.submission$/);
             my $hide;              my $hide;
             if (@hidden) {              if (@hidden) {
                 foreach my $id (@hidden) {                  foreach my $id (@hidden) {
                     if ($key =~ /^\Q$id\E/) {                      if ($key =~ /^\Q$id\E/) {
                         $hide = 'anon';                          $hide = 1;
                         last;                          last;
                     }                      }
                 }                  }
             }              }
             unless ($hide) {  
                 if (@randomize) {  
                     foreach my $id (@hidden) {  
                         if ($key =~ /^\Q$id\E/) {  
                             $hide = 'rand';  
                             last;  
                         }  
                     }  
                 }  
             }  
     my ($partid,$foo) = split(/submission$/,$key);      my ($partid,$foo) = split(/submission$/,$key);
     my $draft  = $lasthash{$partid.'awarddetail'} eq 'DRAFT' ?      my $draft  = $lasthash{$partid.'awarddetail'} eq 'DRAFT' ?
  '<span class="LC_warning">Draft Copy</span> ' : '';   '<span class="LC_warning">Draft Copy</span> ' : '';
Line 2651  sub processHandGrade { Line 2572  sub processHandGrade {
                                                      undef,undef,$showsymb,                                                       undef,undef,$showsymb,
                                                      $restitle);                                                       $restitle);
  $request->print('<br />'.&mt('Sending message to [_1]',$uname.':'.$udom).': '.   $request->print('<br />'.&mt('Sending message to [_1]',$uname.':'.$udom).': '.
  $msgstatus.'<br />');   $msgstatus);
     }      }
     if ($env{'form.collaborator'.$ctr}) {      if ($env{'form.collaborator'.$ctr}) {
  my @collabstrs=&Apache::loncommon::get_env_multiple("form.collaborator$ctr");   my @collabstrs=&Apache::loncommon::get_env_multiple("form.collaborator$ctr");
Line 2837  sub processHandGrade { Line 2758  sub processHandGrade {
     }      }
     if ($total < 0) {      if ($total < 0) {
  my $the_end = '<h3><span class="LC_info">'.&mt('LON-CAPA User Message').'</span></h3><br />'."\n";   my $the_end = '<h3><span class="LC_info">'.&mt('LON-CAPA User Message').'</span></h3><br />'."\n";
  $the_end.='<p>'.&mt('[_1]Message:[_2] No more students for this section or class.','<b>','</b>').'</p>'."\n";   $the_end.=&mt('<b>Message: </b> No more students for this section or class.').'<br /><br />'."\n";
  $the_end.=&mt('Click on the button below to return to the grading menu.').'<br /><br />'."\n";   $the_end.=&mt('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);
  $request->print($the_end);   $request->print($the_end);
Line 2990  sub handback_files { Line 2911  sub handback_files {
         $request->print('<br />'.&navmap_errormsg().'<br />');          $request->print('<br />'.&navmap_errormsg().'<br />');
         return;          return;
     }      }
     my @handedback;  
     my $file_msg;  
     my @part_response_id = &flatten_responseType($responseType);      my @part_response_id = &flatten_responseType($responseType);
     foreach my $part_response_id (@part_response_id) {      foreach my $part_response_id (@part_response_id) {
     my ($part_id,$resp_id) = @{ $part_response_id };      my ($part_id,$resp_id) = @{ $part_response_id };
  my $part_resp = join('_',@{ $part_response_id });   my $part_resp = join('_',@{ $part_response_id });
         if (($env{'form.'.$newflg.'_'.$part_resp.'_countreturndoc'} =~ /^\d+$/) & ($new_part eq $part_id)) {              if (($env{'form.'.$newflg.'_'.$part_resp.'_returndoc1'}) && ($new_part == $part_id)) {
             for (my $counter=1; $counter<=$env{'form.'.$newflg.'_'.$part_resp.'_countreturndoc'}; $counter++) {  
                 # if multiple files are uploaded names will be 'returndoc2','returndoc3'                  # if multiple files are uploaded names will be 'returndoc2','returndoc3'
  if ($env{'form.'.$newflg.'_'.$part_resp.'_returndoc'.$counter}) {                  my $file_counter = 1;
                     my $fname=$env{'form.'.$newflg.'_'.$part_resp.'_returndoc'.$counter.'.filename'};   my $file_msg;
                   while ($env{'form.'.$newflg.'_'.$part_resp.'_returndoc'.$file_counter}) {
                       my $fname=$env{'form.'.$newflg.'_'.$part_resp.'_returndoc'.$file_counter.'.filename'};
                     my ($directory,$answer_file) =                       my ($directory,$answer_file) = 
                         ($env{'form.'.$newflg.'_'.$part_resp.'_origdoc'.$counter} =~ /^(.*?)([^\/]*)$/);                          ($env{'form.'.$newflg.'_'.$part_resp.'_origdoc'.$file_counter} =~ /^(.*?)([^\/]*)$/);
                     my ($answer_name,$answer_ver,$answer_ext) =                      my ($answer_name,$answer_ver,$answer_ext) =
         &file_name_version_ext($answer_file);          &file_name_version_ext($answer_file);
     my ($portfolio_path) = ($directory =~ /^.+$stuname\/portfolio(.*)/);      my ($portfolio_path) = ($directory =~ /^.+$stuname\/portfolio(.*)/);
Line 3012  sub handback_files { Line 2932  sub handback_files {
                     # 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'.$counter,                                             $newflg.'_'.$part_resp.'_returndoc'.$file_counter,
                                            $save_file_name);                                             $save_file_name);
                     if ($result !~ m|^/uploaded/|) {                      if ($result !~ m|^/uploaded/|) {
                         $request->print('<br /><span class="LC_error">'.                          $request->print('<br /><span class="LC_error">'.
                             &mt('An error occurred ([_1]) while trying to upload [_2].',                              &mt('An error occurred ([_1]) while trying to upload [_2].',
                                 $result,$newflg.'_'.$part_resp.'_returndoc'.$counter).                                  $result,$newflg.'_'.$part_resp.'_returndoc'.$file_counter).
                                         '</span>');                                          '</span>');
                     } else {                      } else {
                         # mark the file as read only                          # mark the file as read only
                         push(@handedback,$save_file_name);                          my @files = ($save_file_name);
                           my @what = ($symb,$env{'request.course.id'},'handback');
                           &Apache::lonnet::mark_as_readonly($domain,$stuname,\@files,\@what);
  if (exists($$newrecord{"resource.$new_part.$resp_id.handback"})) {   if (exists($$newrecord{"resource.$new_part.$resp_id.handback"})) {
     $$newrecord{"resource.$new_part.$resp_id.handback"}.=',';      $$newrecord{"resource.$new_part.$resp_id.handback"}.=',';
  }   }
                         $$newrecord{"resource.$new_part.$resp_id.handback"} .= $save_file_name;                          $$newrecord{"resource.$new_part.$resp_id.handback"} .= $save_file_name;
  $file_msg.='<span class="LC_filename"><a href="/uploaded/'."$domain/$stuname/".$save_file_name.'">'.$save_file_name."</a></span> <br />";   $file_msg.= "\n".'<br /><span class="LC_filename"><a href="/uploaded/'."$domain/$stuname/".$save_file_name.'">'.$save_file_name."</a></span><br />";
   
                     }                      }
                     $request->print('<br />'.&mt('[_1] will be the uploaded file name [_2]','<span class="LC_info">'.$fname.'</span>','<span class="LC_filename">'.$env{'form.'.$newflg.'_'.$part_resp.'_origdoc'.$counter}.'</span>'));                      $request->print("<br />".$fname." will be the uploaded file name");
                       $request->print(" ".$env{'form.'.$newflg.'_'.$part_resp.'_origdoc'.$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 ($feedurl,$showsymb) = 
       &get_feedurl_and_symb($symb,$domain,$stuname);
                   my $restitle = &Apache::lonnet::gettitle($symb);
    my $msgstatus = 
                      &Apache::lonmsg::user_normal_msg($stuname,$domain,$subject.
    ' (File Returned) ['.$restitle.']',$message,undef,
                            $feedurl,undef,undef,undef,$showsymb,$restitle);
             }              }
         }          }
     }  
     if (@handedback > 0) {  
         $request->print('<br />');  
         my @what = ($symb,$env{'request.course.id'},'handback');  
         &Apache::lonnet::mark_as_readonly($domain,$stuname,\@handedback,\@what);  
         my $user_lh = &Apache::loncommon::user_lang($stuname,$domain,$env{'request.course.id'});  
         my ($subject,$message);  
         if (scalar(@handedback) == 1) {  
             $subject = &mt_user($user_lh,'File Handed Back by Instructor');  
         } else {  
             $subject = &mt_user($user_lh,'Files Handed Back by Instructor');  
             $message = &mt_user($user_lh,'Files have been returned that were originally submitted in response to: ');  
         }  
         $message .= "<p><strong>".&Apache::lonnet::gettitle($symb)." </strong></p>";  
         $message .= &mt_user($user_lh,'The returned file(s) are named: [_1]',"<br />$file_msg <br />").  
                     &mt_user($user_lh,'The file(s) can be found in your [_1]portfolio[_2].','<a href="/adm/portfolio">','</a>');  
         my ($feedurl,$showsymb) =  
             &get_feedurl_and_symb($symb,$domain,$stuname);  
         my $restitle = &Apache::lonnet::gettitle($symb);  
         $subject .= ' '.&mt_user($user_lh,'(File Returned)').' ['.$restitle.']';  
         my $msgstatus =  
              &Apache::lonmsg::user_normal_msg($stuname,$domain,$subject,  
                  $message,undef,$feedurl,undef,undef,undef,$showsymb,  
                  $restitle);  
         if ($msgstatus) {  
             $request->print(&mt('Notification message status: [_1]','<span class="LC_info">'.$msgstatus.'</span>').'<br />');  
         }  
     }  
     return;      return;
 }  }
   
Line 3250  sub viewgrades_js { Line 3158  sub viewgrades_js {
     my ($request) = shift;      my ($request) = shift;
   
     my $alertmsg = &mt('A number equal or greater than 0 is expected. Entered value = ');      my $alertmsg = &mt('A number equal or greater than 0 is expected. Entered value = ');
     $request->print(<<VIEWJAVASCRIPT);      $request->print(&Apache::lonhtmlcommon::scripttag(<<VIEWJAVASCRIPT));
 <script type="text/javascript" language="javascript">  
    function writePoint(partid,weight,point) {     function writePoint(partid,weight,point) {
  var radioButton = document.classgrade["RADVAL_"+partid];   var radioButton = document.classgrade["RADVAL_"+partid];
  var textbox = document.classgrade["TEXTVAL_"+partid];   var textbox = document.classgrade["TEXTVAL_"+partid];
Line 3412  sub viewgrades_js { Line 3319  sub viewgrades_js {
  }   }
     }      }
   
 </script>  
 VIEWJAVASCRIPT  VIEWJAVASCRIPT
 }  }
   
Line 4015  to this page if the data selected is ins Line 3921  to this page if the data selected is ins
 <input type="hidden" name="probTitle"  value="$env{'form.probTitle'}" />  <input type="hidden" name="probTitle"  value="$env{'form.probTitle'}" />
 <input type="hidden" name="command"    value="csvuploadoptions" />  <input type="hidden" name="command"    value="csvuploadoptions" />
 <hr />  <hr />
 <script type="text/javascript" language="Javascript">  
 $javascript  
 </script>  
 ENDPICK  ENDPICK
       $request->print(&Apache::lonhtmlcommon::scripttag($javascript));
     return '';      return '';
   
 }  }
Line 4063  ENDPICK Line 3967  ENDPICK
   
 sub checkforfile_js {  sub checkforfile_js {
     my $alertmsg = &mt('Please use the browse button to select a file from your local directory.');      my $alertmsg = &mt('Please use the browse button to select a file from your local directory.');
     my $result =<<CSVFORMJS;      my $result = &Apache::lonhtmlcommon::scripttag(<<CSVFORMJS);
 <script type="text/javascript" language="javascript">  
     function checkUpload(formname) {      function checkUpload(formname) {
  if (formname.upfile.value == "") {   if (formname.upfile.value == "") {
     alert("$alertmsg");      alert("$alertmsg");
Line 4072  sub checkforfile_js { Line 3975  sub checkforfile_js {
  }   }
  formname.submit();   formname.submit();
     }      }
     </script>  
 CSVFORMJS  CSVFORMJS
     return $result;      return $result;
 }  }
Line 4089  sub upcsvScores_form { Line 3991  sub upcsvScores_form {
     $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>'.&mt('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 $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');
Line 4237  sub csvuploadassign { Line 4139  sub csvuploadassign {
     my ($classlist) = &getclasslist('all',0);      my ($classlist) = &getclasslist('all',0);
     my @notallowed;      my @notallowed;
     my @skipped;      my @skipped;
     my @warnings;  
     my $countdone=0;      my $countdone=0;
     foreach my $grade (@gradedata) {      foreach my $grade (@gradedata) {
  my %entries=&Apache::loncommon::record_sep($grade);   my %entries=&Apache::loncommon::record_sep($grade);
Line 4286  sub csvuploadassign { Line 4187  sub csvuploadassign {
                     my $pcr=$entries{$fields{$dest}} / $wgt;                      my $pcr=$entries{$fields{$dest}} / $wgt;
                     my $award=($pcr == 0) ? 'incorrect_by_override'                      my $award=($pcr == 0) ? 'incorrect_by_override'
                                           : 'correct_by_override';                                            : 'correct_by_override';
                     if ($pcr>1) {  
                         push(@warnings,&mt("[_1]: point value larger than weight","$username:$domain"));  
                     }  
                     $grades{"resource.$part.awarded"}=$pcr;                      $grades{"resource.$part.awarded"}=$pcr;
                     $grades{"resource.$part.solved"}=$award;                      $grades{"resource.$part.solved"}=$award;
                     $points{$part}=1;                      $points{$part}=1;
Line 4317  sub csvuploadassign { Line 4215  sub csvuploadassign {
    $domain,$username);     $domain,$username);
    if ($result eq 'ok') {     if ($result eq 'ok') {
       $request->print('.');        $request->print('.');
 # Remove from grading queue  
               &Apache::bridgetask::remove_from_queue('gradingqueue',$symb,  
                                              $env{'course.'.$env{'request.course.id'}.'.domain'},  
                                              $env{'course.'.$env{'request.course.id'}.'.num'},  
                                              $domain,$username);  
    } else {     } else {
       $request->print("<p><span class=\"LC_error\">".        $request->print("<p><span class=\"LC_error\">".
                               &mt("Failed to save data for student [_1]. Message when trying to save was: [_2]",                                &mt("Failed to save data for student [_1]. Message when trying to save was: [_2]",
Line 4332  sub csvuploadassign { Line 4225  sub csvuploadassign {
         }          }
     }      }
     $request->print('<br />'.&Apache::lonhtmlcommon::confirm_success(&mt("Saved scores for [quant,_1,student]",$countdone),$countdone==0));      $request->print('<br />'.&Apache::lonhtmlcommon::confirm_success(&mt("Saved scores for [quant,_1,student]",$countdone),$countdone==0));
     if (@warnings) {  
         $request->print('<br />'.&Apache::lonhtmlcommon::confirm_success(&mt('Warnings generated for the following saved scores:'),1).'<br />');  
         $request->print(join(', ',@warnings));  
     }  
     if (@skipped) {      if (@skipped) {
  $request->print('<br />'.&Apache::lonhtmlcommon::confirm_success(&mt('No scores stored for the following username(s):'),1).'<br />');   $request->print('<br />'.&Apache::lonhtmlcommon::confirm_success(&mt('No scores stored for the following username(s):'),1).'<br />');
         $request->print(join(', ',@skipped));          $request->print(join(', ',@skipped));
Line 4359  sub pickStudentPage { Line 4248  sub pickStudentPage {
     my ($request) = shift;      my ($request) = shift;
   
     my $alertmsg = &mt('Please select the student you wish to grade.');      my $alertmsg = &mt('Please select the student you wish to grade.');
     $request->print(<<LISTJAVASCRIPT);      $request->print(&Apache::lonhtmlcommon::scripttag(<<LISTJAVASCRIPT));
 <script type="text/javascript" language="javascript">  
   
 function checkPickOne(formname) {  function checkPickOne(formname) {
     if (radioSelection(formname.student) == null) {      if (radioSelection(formname.student) == null) {
Line 4373  function checkPickOne(formname) { Line 4261  function checkPickOne(formname) {
     formname.submit();      formname.submit();
 }  }
   
 </script>  
 LISTJAVASCRIPT  LISTJAVASCRIPT
     &commonJSfunctions($request);      &commonJSfunctions($request);
     my ($symb) = &get_symb($request);      my ($symb) = &get_symb($request);
Line 4608  sub displayPage { Line 4495  sub displayPage {
  &Apache::loncommon::start_data_table_row().   &Apache::loncommon::start_data_table_row().
  '<td align="center" valign="top" >'.$prob.   '<td align="center" valign="top" >'.$prob.
  (scalar(@{$parts}) == 1 ? ''    (scalar(@{$parts}) == 1 ? '' 
                         : '<br />('.&mt('[_1]parts)',                          : '<br />('.&mt('[_1]&nbsp;parts)',
  scalar(@{$parts}).'&nbsp;')   scalar(@{$parts}))
  ).   ).
  '</td>';   '</td>';
     $studentTable.='<td valign="top">';      $studentTable.='<td valign="top">';
Line 4704  sub displaySubByDates { Line 4591  sub displaySubByDates {
   
     my $interaction;      my $interaction;
     my $no_increment = 1;      my $no_increment = 1;
     my %lastrndseed;  
     for ($version=1;$version<=$$record{'version'};$version++) {      for ($version=1;$version<=$$record{'version'};$version++) {
  my $timestamp =    my $timestamp = 
     &Apache::lonlocal::locallocaltime($$record{$version.':timestamp'});      &Apache::lonlocal::locallocaltime($$record{$version.':timestamp'});
Line 4722  sub displaySubByDates { Line 4608  sub displaySubByDates {
  my @versionKeys = split(/\:/,$$record{$version.':keys'});   my @versionKeys = split(/\:/,$$record{$version.':keys'});
  my @displaySub = ();   my @displaySub = ();
  foreach my $partid (@{$parts}) {   foreach my $partid (@{$parts}) {
             my ($hidden,$type);              my $hidden;
             $type = $$record{$version.':resource.'.$partid.'.type'};              if (($$record{$version.':resource.'.$partid.'.type'} eq 'anonsurvey') ||
             if (($type eq 'anonsurvey') || ($type eq 'anonsurveycred')) {                  ($$record{$version.':resource.'.$partid.'.type'} eq 'anonsurveycred')) {
                 $hidden = 1;                  $hidden = 1;
             }              }
     my @matchKey = ($isTask ? sort(grep /^resource\.\d+\.\Q$partid\E\.award$/,@versionKeys)      my @matchKey = ($isTask ? sort(grep /^resource\.\d+\.\Q$partid\E\.award$/,@versionKeys)
Line 4741  sub displaySubByDates { Line 4627  sub displaySubByDates {
                     $displaySub[0].='<span class="LC_nobreak"';                      $displaySub[0].='<span class="LC_nobreak"';
                     $displaySub[0].='<b>'.&mt('Part: [_1]',$display_part).'</b>'                      $displaySub[0].='<b>'.&mt('Part: [_1]',$display_part).'</b>'
                                    .' <span class="LC_internal_info">'                                     .' <span class="LC_internal_info">'
                                    .'('.&mt('Response ID: [_1]',$responseId).')'                                     .'('.&mt('Part ID: [_1]',$responseId).')'
                                    .'</span>'                                     .'</span>'
                                    .' <b>';                                     .' <b>';
                     if ($hidden) {                      if ($hidden) {
                         $displaySub[0].= &mt('Anonymous Survey').'</b>';                          $displaySub[0].= &mt('Anonymous Survey').'</b>';
                     } else {                      } else {
                         my ($trial,$rndseed,$newvariation);  
                         if ($type eq 'randomizetry') {  
                             $trial = $$record{"$where.$partid.tries"};  
                             $rndseed = $$record{"$where.$partid.rndseed"};  
                         }  
         if ($$record{"$where.$partid.tries"} eq '') {          if ($$record{"$where.$partid.tries"} eq '') {
     $displaySub[0].=&mt('Trial not counted');      $displaySub[0].=&mt('Trial not counted');
         } else {          } else {
     $displaySub[0].=&mt('Trial: [_1]',      $displaySub[0].=&mt('Trial: [_1]',
     $$record{"$where.$partid.tries"});      $$record{"$where.$partid.tries"});
                             if ($rndseed || $lastrndseed{$partid}) {  
                                 if ($rndseed ne $lastrndseed{$partid}) {  
                                     $newvariation = '&nbsp;('.&mt('New variation this try').')';  
                                 }  
                             }  
         }          }
         my $responseType=($isTask ? 'Task'          my $responseType=($isTask ? 'Task'
                                               : $responseType->{$partid}->{$responseId});                                                : $responseType->{$partid}->{$responseId});
         if (!exists($orders{$partid})) { $orders{$partid}={}; }          if (!exists($orders{$partid})) { $orders{$partid}={}; }
         if ((!exists($orders{$partid}->{$responseId})) || ($trial)) {          if (!exists($orders{$partid}->{$responseId})) {
     $orders{$partid}->{$responseId}=      $orders{$partid}->{$responseId}=
         &get_order($partid,$responseId,$symb,$uname,$udom,          &get_order($partid,$responseId,$symb,$uname,$udom,
                                            $no_increment,$type,$trial,$rndseed);                                             $no_increment);
         }          }
         $displaySub[0].='</b>'.$newvariation.'</span>'; # /nobreak          $displaySub[0].='</b></span>'; # /nobreak
         $displaySub[0].='&nbsp; '.          $displaySub[0].='&nbsp; '.
     &cleanRecord($$record{$version.':'.$matchKey},$responseType,$symb,$partid,$responseId,$record,$orders{$partid}->{$responseId},"$version:",$uname,$udom,$type,$trial,$rndseed).'<br />';      &cleanRecord($$record{$version.':'.$matchKey},$responseType,$symb,$partid,$responseId,$record,$orders{$partid}->{$responseId},"$version:",$uname,$udom).'<br />';
                     }                      }
  }   }
     }      }
Line 4875  sub updateGradeByPage { Line 4751  sub updateGradeByPage {
  &Apache::loncommon::start_data_table_row().   &Apache::loncommon::start_data_table_row().
  '<td align="center" valign="top" >'.$prob.   '<td align="center" valign="top" >'.$prob.
  (scalar(@{$parts}) == 1 ? ''    (scalar(@{$parts}) == 1 ? '' 
                                         : '<br />('.&mt('[quant,_1,part]',scalar(@{$parts}))                                          : '<br />('.&mt('[quant,_1,&nbsp;part]',scalar(@{$parts}))
  .')').'</td>';   .')').'</td>';
     $studentTable.='<td valign="top">&nbsp;<b>'.$title.'</b>&nbsp;</td>';      $studentTable.='<td valign="top">&nbsp;<b>'.$title.'</b>&nbsp;</td>';
   
Line 4998  sub updateGradeByPage { Line 4874  sub updateGradeByPage {
    from the file that we are parsing that represents one entire sheet     from the file that we are parsing that represents one entire sheet
   
    'bubble line' refers to the data     'bubble line' refers to the data
    representing the line of bubbles that are on the physical bubblesheet     representing the line of bubbles that are on the physical bubble sheet
   
   
 The overall process is that a scanned in bubblesheet data is uploaded  The overall process is that a scanned in bubble sheet data is uploaded
 into a course. When a user wants to grade, they select a  into a course. When a user wants to grade, they select a
 sequence/folder of resources, a file of bubblesheet info, and pick  sequence/folder of resources, a file of bubble sheet info, and pick
 one of the predefined configurations for what each scanline looks  one of the predefined configurations for what each scanline looks
 like.  like.
   
Line 5019  username:domain. Line 4895  username:domain.
   
 During the validation phase the instructor can choose to skip scanlines.   During the validation phase the instructor can choose to skip scanlines. 
   
 After the validation phase, there are now 3 bubblesheet files  After the validation phase, there are now 3 bubble sheet files
   
   scantron_original_filename (unmodified original file)    scantron_original_filename (unmodified original file)
   scantron_corrected_filename (file where the corrected information has replaced the original information)    scantron_corrected_filename (file where the corrected information has replaced the original information)
   scantron_skipped_filename (contains the exact text of scanlines that where skipped)    scantron_skipped_filename (contains the exact text of scanlines that where skipped)
   
 Also there is a separate hash nohist_scantrondata that contains extra  Also there is a separate hash nohist_scantrondata that contains extra
 correction information that isn't representable in the bubblesheet  correction information that isn't representable in the bubble sheet
 file (see &scantron_getfile() for more information)  file (see &scantron_getfile() for more information)
   
 After all scanlines are either valid, marked as valid or skipped, then  After all scanlines are either valid, marked as valid or skipped, then
Line 5323  sub scantron_CODEunique { Line 5199  sub scantron_CODEunique {
   
 =item scantron_selectphase  =item scantron_selectphase
   
   Generates the initial screen to start the bubblesheet process.    Generates the initial screen to start the bubble sheet process.
   Allows for - starting a grading run.    Allows for - starting a grading run.
              - downloading existing scan data (original, corrected               - downloading existing scan data (original, corrected
                                                 or skipped info)                                                  or skipped info)
Line 5356  sub scantron_selectphase { Line 5232  sub scantron_selectphase {
   
     $ssi_error = 0;      $ssi_error = 0;
   
     if (&Apache::lonnet::allowed('usc',$env{'request.role.domain'}) ||  
         &Apache::lonnet::allowed('usc',$env{'request.course.id'})) {  
   
         # Chunk of form to prompt for a scantron file upload.  
   
         $r->print('  
     <br />  
     '.&Apache::loncommon::start_data_table('LC_scantron_action').'  
        '.&Apache::loncommon::start_data_table_header_row().'  
             <th>  
               &nbsp;'.&mt('Specify a bubblesheet data file to upload.').'  
             </th>  
        '.&Apache::loncommon::end_data_table_header_row().'  
        '.&Apache::loncommon::start_data_table_row().'  
             <td>  
 ');  
     my $default_form_data=&defaultFormData(&get_symb($r,1));  
     my $cdom= $env{'course.'.$env{'request.course.id'}.'.domain'};  
     my $cnum= $env{'course.'.$env{'request.course.id'}.'.num'};  
     $r->print('  
               <script type="text/javascript" language="javascript">  
     function checkUpload(formname) {  
         if (formname.upfile.value == "") {  
             alert("'.&mt('Please use the browse button to select a file from your local directory.').'");  
             return false;  
         }  
         formname.submit();  
     }  
               </script>  
   
               <form enctype="multipart/form-data" action="/adm/grades" name="rules" method="post">  
                 '.$default_form_data.'  
                 <input name="courseid" type="hidden" value="'.$cnum.'" />  
                 <input name="domainid" type="hidden" value="'.$cdom.'" />  
                 <input name="command" value="scantronupload_save" type="hidden" />  
                 '.&mt('File to upload: [_1]','<input type="file" name="upfile" size="50" />').'  
                 <br />  
                 <input type="button" onclick="javascript:checkUpload(this.form);" value="'.&mt('Upload Bubblesheet Data').'" />  
               </form>  
 ');  
   
         $r->print('  
             </td>  
        '.&Apache::loncommon::end_data_table_row().'  
        '.&Apache::loncommon::end_data_table().'  
 ');  
     }  
   
     # Chunk of form to prompt for a file to grade and how:      # Chunk of form to prompt for a file to grade and how:
   
     $result.= '      $result.= '
Line 5451  sub scantron_selectphase { Line 5279  sub scantron_selectphase {
         
     $r->print($result);      $r->print($result);
   
       if (&Apache::lonnet::allowed('usc',$env{'request.role.domain'}) ||
           &Apache::lonnet::allowed('usc',$env{'request.course.id'})) {
   
    # Chunk of form to prompt for a scantron file upload.
   
           $r->print('
       <br />
       '.&Apache::loncommon::start_data_table('LC_scantron_action').'
          '.&Apache::loncommon::start_data_table_header_row().'
               <th>
                 &nbsp;'.&mt('Specify a bubblesheet data file to upload.').'
               </th>
          '.&Apache::loncommon::end_data_table_header_row().'
          '.&Apache::loncommon::start_data_table_row().'
               <td>
   ');
       my $default_form_data=&defaultFormData(&get_symb($r,1));
       my $cdom= $env{'course.'.$env{'request.course.id'}.'.domain'};
       my $cnum= $env{'course.'.$env{'request.course.id'}.'.num'};
       $r->print(&Apache::lonhtmlcommon::scripttag('
       function checkUpload(formname) {
    if (formname.upfile.value == "") {
       alert("'.&mt('Please use the browse button to select a file from your local directory.').'");
       return false;
    }
    formname.submit();
       }'));
       $r->print('
                 <form enctype="multipart/form-data" action="/adm/grades" name="rules" method="post">
                   '.$default_form_data.'
                   <input name="courseid" type="hidden" value="'.$cnum.'" />
                   <input name="domainid" type="hidden" value="'.$cdom.'" />
                   <input name="command" value="scantronupload_save" type="hidden" />
                   '.&mt('File to upload: [_1]','<input type="file" name="upfile" size="50" />').'
                   <br />
                   <input type="button" onclick="javascript:checkUpload(this.form);" value="'.&mt('Upload Bubblesheet Data').'" />
                 </form>
   ');
   
           $r->print('
               </td>
          '.&Apache::loncommon::end_data_table_row().'
          '.&Apache::loncommon::end_data_table().'
   ');
       }
   
     # Chunk of the form that prompts to view a scoring office file,      # Chunk of the form that prompts to view a scoring office file,
     # corrected file, skipped records in a file.      # corrected file, skipped records in a file.
   
Line 6346  sub remember_current_skipped { Line 6220  sub remember_current_skipped {
 =item check_for_error  =item check_for_error
   
     Checks if there was an error when attempting to remove a specific      Checks if there was an error when attempting to remove a specific
     scantron_.. bubblesheet data file. Prints out an error if      scantron_.. bubble sheet data file. Prints out an error if
     something went wrong.      something went wrong.
   
 =cut  =cut
Line 6417  sub scantron_do_warning { Line 6291  sub scantron_do_warning {
     if ( $env{'form.selectpage'} eq '' ||      if ( $env{'form.selectpage'} eq '' ||
  $env{'form.scantron_selectfile'} eq '' ||   $env{'form.scantron_selectfile'} eq '' ||
  $env{'form.scantron_format'} eq '' ) {   $env{'form.scantron_format'} eq '' ) {
  $r->print("<p>".&mt('You have forgotten to specify some information. Please go Back and try again.')."</p>");   $r->print("<p>".&mt('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><span class="LC_error">'.&mt('You have not selected a Sequence to grade').'</span></p>');      $r->print('<p><span class="LC_error">'.&mt('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><span class="LC_error">'.&mt("You have not selected a file that contains the student's response data.").'</span></p>');      $r->print('<p><span class="LC_error">'.&mt('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><span class="LC_error">'.&mt("You have not selected the format of the student's response data.").'</span></p>');      $r->print('<p><span class="LC_error">'.&mt('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 6482  SCANTRONFORM Line 6356  SCANTRONFORM
   
 =item scantron_validate_file  =item scantron_validate_file
   
     Dispatch routine for doing validation of a bubblesheet data file.      Dispatch routine for doing validation of a bubble sheet data file.
   
     Also processes any necessary information resets that need to      Also processes any necessary information resets that need to
     occur before validation begins (ignore previous corrections,      occur before validation begins (ignore previous corrections,
Line 6593  sub scantron_validate_file { Line 6467  sub scantron_validate_file {
   
 =item scantron_remove_file  =item scantron_remove_file
   
    Removes the requested bubblesheet data file, makes sure that     Removes the requested bubble sheet data file, makes sure that
    scantron_original_<filename> is never removed     scantron_original_<filename> is never removed
   
   
Line 6618  sub scantron_remove_file { Line 6492  sub scantron_remove_file {
   
 =item scantron_remove_scan_data  =item scantron_remove_scan_data
   
    Removes all scan_data correction for the requested bubblesheet     Removes all scan_data correction for the requested bubble sheet
    data file.  (In the case that both the are doing skipped records we need     data file.  (In the case that both the are doing skipped records we need
    to remember the old skipped lines for the time being so that element     to remember the old skipped lines for the time being so that element
    persists for a while.)     persists for a while.)
Line 6655  sub scantron_remove_scan_data { Line 6529  sub scantron_remove_scan_data {
   
 =item scantron_getfile  =item scantron_getfile
   
     Fetches the requested bubblesheet data file (all 3 versions), and      Fetches the requested bubble sheet data file (all 3 versions), and
     the scan_data hash      the scan_data hash
       
   Arguments:    Arguments:
Line 6755  sub lonnet_putfile { Line 6629  sub lonnet_putfile {
   
 =item scantron_putfile  =item scantron_putfile
   
     Stores the current version of the bubblesheet data files, and the      Stores the current version of the bubble sheet data files, and the
     scan_data hash. (Does not modify the original version only the      scan_data hash. (Does not modify the original version only the
     corrected and skipped versions.      corrected and skipped versions.
   
Line 6849  sub get_todo_count { Line 6723  sub get_todo_count {
   
 =item scantron_put_line  =item scantron_put_line
   
     Updates the 'corrected' or 'skipped' versions of the bubblesheet      Updates the 'corrected' or 'skipped' versions of the bubble sheet
     data file.      data file.
   
  Arguments:   Arguments:
Line 7038  sub scantron_get_correction { Line 6912  sub scantron_get_correction {
 #the previous one or the current one  #the previous one or the current one
   
     if ( $$scan_record{'scantron.PaperID'} =~ /\S/) {      if ( $$scan_record{'scantron.PaperID'} =~ /\S/) {
         $r->print(   $r->print("<p>".&mt("<b>An error was detected ($error)</b>".
             '<p class="LC_warning">'      " for PaperID <tt>[_1]</tt>",
            .&mt('An error was detected ([_1]) for PaperID [_2]',      $$scan_record{'scantron.PaperID'})."</p> \n");
                 "<b>$error</b>",  
                 '<tt>'.$$scan_record{'scantron.PaperID'}.'</tt>')  
            ."</p> \n");  
     } else {      } else {
         $r->print(   $r->print("<p>".&mt("<b>An error was detected ($error)</b>".
             '<p class="LC_warning">'      " in scanline [_1] <pre>[_2]</pre>",
            .&mt('An error was detected ([_1]) in scanline [_2] [_3]',      $i,$line)."</p> \n");
                 "<b>$error</b>", $i, "<pre>$line</pre>")      }
            ."</p> \n");      my $message="<p>".&mt("The ID on the form is  <tt>[_1]</tt><br />".
     }    "The name on the paper is [_2],[_3]",
     my $message =    $$scan_record{'scantron.ID'},
         '<p>'    $$scan_record{'scantron.LastName'},
        .&mt('The ID on the form is [_1]',    $$scan_record{'scantron.FirstName'})."</p>";
             "<tt>$$scan_record{'scantron.ID'}</tt>")  
        .'<br />'  
        .&mt('The name on the paper is [_1], [_2]',  
             $$scan_record{'scantron.LastName'},  
             $$scan_record{'scantron.FirstName'})  
        .'</p>';  
   
     $r->print('<input type="hidden" name="scantron_corrections" value="'.$error.'" />'."\n");      $r->print('<input type="hidden" name="scantron_corrections" value="'.$error.'" />'."\n");
     $r->print('<input type="hidden" name="scantron_line" value="'.$i.'" />'."\n");      $r->print('<input type="hidden" name="scantron_line" value="'.$i.'" />'."\n");
Line 7069  sub scantron_get_correction { Line 6934  sub scantron_get_correction {
   
     if ($error =~ /ID$/) {      if ($error =~ /ID$/) {
  if ($error eq 'incorrectID') {   if ($error eq 'incorrectID') {
     $r->print('<p class="LC_warning">'.&mt("The encoded ID is not in the classlist").      $r->print("<p>".&mt("The encoded ID is not in the classlist").
       "</p>\n");        "</p>\n");
  } elsif ($error eq 'duplicateID') {   } elsif ($error eq 'duplicateID') {
     $r->print('<p class="LC_warning">'.&mt("The encoded ID has also been used by a previous paper [_1]",$arg)."</p>\n");      $r->print("<p>".&mt("The encoded ID has also been used by a previous paper [_1]",$arg)."</p>\n");
  }   }
  $r->print($message);   $r->print($message);
  $r->print("<p>".&mt("How should I handle this?")." <br /> \n");   $r->print("<p>".&mt("How should I handle this?")." <br /> \n");
Line 7088  sub scantron_get_correction { Line 6953  sub scantron_get_correction {
  $r->print('</li>');   $r->print('</li>');
     } elsif ($error =~ /CODE$/) {      } elsif ($error =~ /CODE$/) {
  if ($error eq 'incorrectCODE') {   if ($error eq 'incorrectCODE') {
     $r->print('<p class="LC_warning">'.&mt("The encoded CODE is not in the list of possible CODEs.")."</p>\n");      $r->print("<p>".&mt("The encoded CODE is not in the list of possible CODEs.")."</p>\n");
  } elsif ($error eq 'duplicateCODE') {   } elsif ($error eq 'duplicateCODE') {
     $r->print('<p class="LC_warning">'.&mt("The encoded CODE has also been used by a previous paper [_1], and CODEs are supposed to be unique.",join(', ',@{$arg}))."</p>\n");      $r->print("<p>".&mt("The encoded CODE has also been used by a previous paper [_1], and CODEs are supposed to be unique.",join(', ',@{$arg}))."</p>\n");
  }   }
         $r->print("<p>".&mt('The CODE on the form is [_1]',   $r->print("<p>".&mt("The CODE on the form is  <tt>'[_1]'</tt>",
                             "<tt>'$$scan_record{'scantron.CODE'}'</tt>")      $$scan_record{'scantron.CODE'})."<br />\n");
                  ."</p>\n");  
  $r->print($message);   $r->print($message);
  $r->print("<p>".&mt("How should I handle this?")."</p>\n");   $r->print("<p>".&mt("How should I handle this?")." <br /> \n");
  $r->print("\n<br /> ");   $r->print("\n<br /> ");
  my $i=0;   my $i=0;
  if ($error eq 'incorrectCODE'    if ($error eq 'incorrectCODE' 
Line 7123  sub scantron_get_correction { Line 6987  sub scantron_get_correction {
     $r->print("      $r->print("
     <label>      <label>
         <input type='radio' name='scantron_CODE_resolution' value='use_unfound'$checked />          <input type='radio' name='scantron_CODE_resolution' value='use_unfound'$checked />
        ".&mt("Use the CODE [_1] that was on the paper, ignoring the error.",         ".&mt("Use the CODE [_1] that is was on the paper, ignoring the error.",
      "<b><tt>".$$scan_record{'scantron.CODE'}."</tt></b>")."       "<b><tt>".$$scan_record{'scantron.CODE'}."</tt></b>")."
     </label>");      </label>");
     $r->print("\n<br />");      $r->print("\n<br />");
  }   }
   
  $r->print(<<ENDSCRIPT);   $r->print(&Apache::lonhtmlcommon::scripttag(<<ENDSCRIPT));
 <script type="text/javascript">  
 function change_radio(field) {  function change_radio(field) {
     var slct=document.scantronupload.scantron_CODE_resolution;      var slct=document.scantronupload.scantron_CODE_resolution;
     var i;      var i;
Line 7138  function change_radio(field) { Line 7001  function change_radio(field) {
         if (slct[i].value==field) { slct[i].checked=true; }          if (slct[i].value==field) { slct[i].checked=true; }
     }      }
 }  }
 </script>  
 ENDSCRIPT  ENDSCRIPT
  my $href="/adm/pickcode?".   my $href="/adm/pickcode?".
    "form=".&escape("scantronupload").     "form=".&escape("scantronupload").
Line 7163  ENDSCRIPT Line 7025  ENDSCRIPT
      "</label><input type='text' size='8' name='scantron_CODE_newvalue' onfocus=\"javascript:change_radio('use_typed')\" onkeypress=\"javascript:change_radio('use_typed')\" />"));       "</label><input type='text' size='8' name='scantron_CODE_newvalue' onfocus=\"javascript:change_radio('use_typed')\" onkeypress=\"javascript:change_radio('use_typed')\" />"));
  $r->print("\n<br /><br />");   $r->print("\n<br /><br />");
     } elsif ($error eq 'doublebubble') {      } elsif ($error eq 'doublebubble') {
  $r->print('<p class="LC_warning">'.&mt("There have been multiple bubbles scanned for some question(s)")."</p>\n");   $r->print("<p>".&mt("There have been multiple bubbles scanned for some question(s)")."</p>\n");
   
  # The form field scantron_questions is acutally a list of line numbers.   # The form field scantron_questions is acutally a list of line numbers.
  # represented by this form so:   # represented by this form so:
Line 7181  ENDSCRIPT Line 7043  ENDSCRIPT
  }   }
         $r->print(&verify_bubbles_checked(@lines_to_correct));          $r->print(&verify_bubbles_checked(@lines_to_correct));
     } elsif ($error eq 'missingbubble') {      } elsif ($error eq 'missingbubble') {
  $r->print('<p class="LC_warning">'.&mt("There have been [_1]no[_2] bubbles scanned for some question(s)",'<b>','</b>')."</p>\n");   $r->print("<p>".&mt("There have been <b>no</b> bubbles scanned for some question(s)")."</p>\n");
  $r->print($message);   $r->print($message);
  $r->print("<p>".&mt("Please indicate which bubble should be used for grading.")."</p>");   $r->print("<p>".&mt("Please indicate which bubble should be used for grading.")."</p>");
  $r->print(&mt("Some questions have no scanned bubbles.")."\n");   $r->print(&mt("Some questions have no scanned bubbles.")."\n");
Line 7210  sub verify_bubbles_checked { Line 7072  sub verify_bubbles_checked {
     my (@ansnums) = @_;      my (@ansnums) = @_;
     my $ansnumstr = join('","',@ansnums);      my $ansnumstr = join('","',@ansnums);
     my $warning = &mt("A bubble or 'No bubble' selection has not been made for one or more lines.");      my $warning = &mt("A bubble or 'No bubble' selection has not been made for one or more lines.");
     my $output = (<<ENDSCRIPT);      my $output = &Apache::lonhtmlcommon::scripttag((<<ENDSCRIPT));
 <script type="text/javascript">  
 function verify_bubble_radio(form) {  function verify_bubble_radio(form) {
     var ansnumArray = new Array ("$ansnumstr");      var ansnumArray = new Array ("$ansnumstr");
     var need_bubble_count = 0;      var need_bubble_count = 0;
Line 7234  function verify_bubble_radio(form) { Line 7095  function verify_bubble_radio(form) {
     }      }
     form.submit();       form.submit(); 
 }  }
 </script>  
 ENDSCRIPT  ENDSCRIPT
     return $output;      return $output;
 }  }
Line 7984  SCANTRONFORM Line 7844  SCANTRONFORM
                     $studentrecord .= $recording;                      $studentrecord .= $recording;
                 }                  }
                 if ($studentrecord ne $studentdata) {                  if ($studentrecord ne $studentdata) {
                     $r->print('<p><span class="LC_warning">');                      $r->print('<p><span class="LC_error">');
                     if ($scancode eq '') {                      if ($scancode eq '') {
                         $r->print(&mt('Mismatch grading bubblesheet for user: [_1] with ID: [_2].',                          $r->print(&mt('Mismatch grading bubble sheet for user: [_1] with ID: [_2].',
                                   $uname.':'.$udom,$scan_record->{'scantron.ID'}));                                    $uname.':'.$udom,$scan_record->{'scantron.ID'}));
                     } else {                      } else {
                         $r->print(&mt('Mismatch grading bubblesheet for user: [_1] with ID: [_2] and CODE: [_3].',                          $r->print(&mt('Mismatch grading bubble sheet for user: [_1] with ID: [_2] and CODE: [_3].',
                                   $uname.':'.$udom,$scan_record->{'scantron.ID'},$scancode));                                    $uname.':'.$udom,$scan_record->{'scantron.ID'},$scancode));
                     }                      }
                     $r->print('</span><br />'.&Apache::loncommon::start_data_table()."\n".                      $r->print('</span><br />'.&Apache::loncommon::start_data_table()."\n".
Line 7997  SCANTRONFORM Line 7857  SCANTRONFORM
                               '<th>'.&mt('Source').'</th><th>'.&mt('Bubbled responses').'</th>'.                                '<th>'.&mt('Source').'</th><th>'.&mt('Bubbled responses').'</th>'.
                               &Apache::loncommon::end_data_table_header_row()."\n".                                &Apache::loncommon::end_data_table_header_row()."\n".
                               &Apache::loncommon::start_data_table_row().                                &Apache::loncommon::start_data_table_row().
                               '<td>'.&mt('Bubblesheet').'</td>'.                                '<td>'.&mt('Bubble Sheet').'</td>'.
                               '<td><span class="LC_nobreak">'.$studentdata.'</span></td>'.                                '<td><span class="LC_nobreak">'.$studentdata.'</span></td>'.
                               &Apache::loncommon::end_data_table_row().                                &Apache::loncommon::end_data_table_row().
                               &Apache::loncommon::start_data_table_row().                                &Apache::loncommon::start_data_table_row().
                               '<td>'.&mt('Stored submissions').'</td>'.                                '<td>Stored submissions</td>'.
                               '<td><span class="LC_nobreak">'.$studentrecord.'</span></td>'."\n".                                '<td><span class="LC_nobreak">'.$studentrecord.'</span></td>'."\n".
                               &Apache::loncommon::end_data_table_row().                                &Apache::loncommon::end_data_table_row().
                               &Apache::loncommon::end_data_table().'</p>');                                &Apache::loncommon::end_data_table().'</p>');
Line 8093  sub scantron_upload_scantron_data { Line 7953  sub scantron_upload_scantron_data {
     my $default_form_data=&defaultFormData(&get_symb($r,1));      my $default_form_data=&defaultFormData(&get_symb($r,1));
     my $nofile_alert = &mt('Please use the browse button to select a file from your local directory.');      my $nofile_alert = &mt('Please use the browse button to select a file from your local directory.');
     my $nocourseid_alert = &mt("Please use the 'Select Course' link to open a separate window where you can search for a course to which a file can be uploaded.");      my $nocourseid_alert = &mt("Please use the 'Select Course' link to open a separate window where you can search for a course to which a file can be uploaded.");
     $r->print('      $r->print(&Apache::lonhtmlcommon::scripttag('
 <script type="text/javascript" language="javascript">  
     function checkUpload(formname) {      function checkUpload(formname) {
  if (formname.upfile.value == "") {   if (formname.upfile.value == "") {
     alert("'.$nofile_alert.'");      alert("'.$nofile_alert.'");
Line 8121  sub scantron_upload_scantron_data { Line 7980  sub scantron_upload_scantron_data {
         return;          return;
     }      }
   
 </script>  '));
       $r->print('
 <h3>'.&mt('Send bubblesheet data to a course').'</h3>  <h3>'.&mt('Send scanned bubblesheet data to a course').'</h3>
   
 <form enctype="multipart/form-data" action="/adm/grades" name="rules" method="post">  <form enctype="multipart/form-data" action="/adm/grades" name="rules" method="post">
 '.$default_form_data.  '.$default_form_data.
Line 8468  sub checkscantron_results { Line 8327  sub checkscantron_results {
             }              }
         }          }
     }      }
     $r->print('<p>'.      $r->print('<p>'.&mt('Comparison of bubblesheet data (including corrections) with corresponding submission records (most recent submission) for <b>[quant,_1,student]</b>  ([_2] scantron lines/student).',$numstudents,$env{'form.scantron_maxbubble'}).'</p>');
               &mt('Comparison of bubblesheet data (including corrections) with corresponding submission records (most recent submission) for [_1][quant,_2,student][_3] ([quant,_4,bubblesheet line] per student).',  
                   '<b>',  
                   $numstudents,  
                   '</b>',  
                   $env{'form.scantron_maxbubble'}).  
               '</p>'  
     );  
     $r->print('<p>'.&mt('Exact matches for <b>[quant,_1,student]</b>.',$passed).'<br />'.&mt('Discrepancies detected for <b>[quant,_1,student]</b>.',$failed).'</p>');      $r->print('<p>'.&mt('Exact matches for <b>[quant,_1,student]</b>.',$passed).'<br />'.&mt('Discrepancies detected for <b>[quant,_1,student]</b>.',$failed).'</p>');
     if ($passed) {      if ($passed) {
         $r->print(&mt('Students with exact correspondence between bubblesheet data and submissions are as follows:').'<br /><br />');          $r->print(&mt('Students with exact correspondence between bubblesheet data and submissions are as follows:').'<br /><br />');
Line 8713  sub grading_menu { Line 8565  sub grading_menu {
                     url => $url4,                      url => $url4,
                     permission => 'F',                      permission => 'F',
                     icon => 'stat.png',                      icon => 'stat.png',
                     linktitle => 'Grade bubblesheet exams, upload/download bubblesheet data files, and review previously graded bubblesheet exams.'                      linktitle => 'Grade scantron exams, upload/download scantron data files, and review previously graded scantron exams.'
                    }                     }
                     ]                      ]
             });              });
Line 8743  sub grading_menu { Line 8595  sub grading_menu {
   
     $Str .="</form>\n";      $Str .="</form>\n";
     my $receiptalert = &mt("Please enter a receipt number given by a student in the receipt box.");      my $receiptalert = &mt("Please enter a receipt number given by a student in the receipt box.");
     $request->print(<<GRADINGMENUJS);      $request->print(&Apache::lonhtmlcommon::scripttag(<<GRADINGMENUJS));
 <script type="text/javascript" language="javascript">  
     function checkChoice(formname,val,cmdx) {      function checkChoice(formname,val,cmdx) {
  if (val <= 2) {   if (val <= 2) {
     var cmd = radioSelection(formname.radioChoice);      var cmd = radioSelection(formname.radioChoice);
Line 8777  sub grading_menu { Line 8628  sub grading_menu {
  }   }
  return true;   return true;
     }      }
 </script>  
 GRADINGMENUJS  GRADINGMENUJS
     &commonJSfunctions($request);      &commonJSfunctions($request);
     return $Str;          return $Str;    
Line 8792  sub submit_options { Line 8642  sub submit_options {
     my $probTitle = &Apache::lonnet::gettitle($symb);      my $probTitle = &Apache::lonnet::gettitle($symb);
   
     my $receiptalert = &mt("Please enter a receipt number given by a student in the receipt box.");       my $receiptalert = &mt("Please enter a receipt number given by a student in the receipt box."); 
     $request->print(<<GRADINGMENUJS);      $request->print(&Apache::lonhtmlcommon::scripttag(<<GRADINGMENUJS));
 <script type="text/javascript" language="javascript">  
     function checkChoice(formname,val,cmdx) {      function checkChoice(formname,val,cmdx) {
  if (val <= 2) {   if (val <= 2) {
     var cmd = radioSelection(formname.radioChoice);      var cmd = radioSelection(formname.radioChoice);
Line 8826  sub submit_options { Line 8675  sub submit_options {
  }   }
  return true;   return true;
     }      }
 </script>  
 GRADINGMENUJS  GRADINGMENUJS
     &commonJSfunctions($request);      &commonJSfunctions($request);
     my ($table,undef,$hdgrade) = &showResourceInfo($symb,$probTitle);      my ($table,undef,$hdgrade) = &showResourceInfo($symb,$probTitle);
Line 8969  sub init_perm { Line 8817  sub init_perm {
     }      }
 }  }
   
 sub init_old_essays {  
     my ($symb,$apath,$adom,$aname) = @_;  
     if ($symb ne '') {  
         my %essays = &Apache::lonnet::dump('nohist_essay_'.$apath,$adom,$aname);  
         if (keys(%essays) > 0) {  
             $old_essays{$symb} = \%essays;  
         }  
     }  
     return;  
 }  
   
 sub reset_old_essays {  
     undef(%old_essays);  
 }  
   
 sub gather_clicker_ids {  sub gather_clicker_ids {
     my %clicker_ids;      my %clicker_ids;
   
Line 9057  sub process_clicker { Line 8890  sub process_clicker {
     $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>'.&mt('Specify a file containing the clicker information for this resource.').      $result.='&nbsp;<b>'.&mt('Specify a file containing the clicker information for this resource.').
         '</b></td></tr>'."\n";          '</b></td></tr>'."\n";
     $result.='<tr bgcolor="#ffffe6"><td>'."\n";      $result.='<tr bgcolor=#ffffe6><td>'."\n";
 # Attempt to restore parameters from last session, set defaults if not present  # Attempt to restore parameters from last session, set defaults if not present
     my %Saveable_Parameters=&clicker_grading_parameters();      my %Saveable_Parameters=&clicker_grading_parameters();
     &Apache::loncommon::restore_course_settings('grades_clicker',      &Apache::loncommon::restore_course_settings('grades_clicker',
Line 9084  sub process_clicker { Line 8917  sub process_clicker {
     my $pcorrect=&mt("Percentage points for correct solution");      my $pcorrect=&mt("Percentage points for correct solution");
     my $pincorrect=&mt("Percentage points for incorrect solution");      my $pincorrect=&mt("Percentage points for incorrect solution");
     my $selectform=&Apache::loncommon::select_form($env{'form.upfiletype'},'upfiletype',      my $selectform=&Apache::loncommon::select_form($env{'form.upfiletype'},'upfiletype',
                                                    {'iclicker' => 'i>clicker',     ('iclicker' => 'i>clicker',
                                                     'interwrite' => 'interwrite PRS'});                                                      'interwrite' => 'interwrite PRS'));
     $symb = &Apache::lonenc::check_encrypt($symb);      $symb = &Apache::lonenc::check_encrypt($symb);
     $result.=<<ENDUPFORM;      $result.= &Apache::lonhtmlcommon::scripttag(<<ENDUPFORM);
 <script type="text/javascript">  
 function sanitycheck() {  function sanitycheck() {
 // Accept only integer percentages  // Accept only integer percentages
    document.forms.gradesupload.pcorrect.value=Math.round(document.forms.gradesupload.pcorrect.value);     document.forms.gradesupload.pcorrect.value=Math.round(document.forms.gradesupload.pcorrect.value);
Line 9126  function sanitycheck() { Line 8958  function sanitycheck() {
 // Remember the old state  // Remember the old state
    document.forms.gradesupload.waschecked.value=newgradingchoice;     document.forms.gradesupload.waschecked.value=newgradingchoice;
 }  }
 </script>  ENDUPFORM
       $result.= <<ENDUPFORM;
 <form method="post" enctype="multipart/form-data" action="/adm/grades" name="gradesupload">  <form method="post" enctype="multipart/form-data" action="/adm/grades" name="gradesupload">
 <input type="hidden" name="symb" value="$symb" />  <input type="hidden" name="symb" value="$symb" />
 <input type="hidden" name="command" value="processclickerfile" />  <input type="hidden" name="command" value="processclickerfile" />
Line 9145  function sanitycheck() { Line 8978  function sanitycheck() {
 <br /><label>$pcorrect: <input type="text" name="pcorrect" size="4" value="$env{'form.pcorrect'}" onchange="sanitycheck()" /></label>  <br /><label>$pcorrect: <input type="text" name="pcorrect" size="4" value="$env{'form.pcorrect'}" onchange="sanitycheck()" /></label>
 <br /><label>$pincorrect: <input type="text" name="pincorrect" size="4" value="$env{'form.pincorrect'}" onchange="sanitycheck()" /></label>  <br /><label>$pincorrect: <input type="text" name="pincorrect" size="4" value="$env{'form.pincorrect'}" onchange="sanitycheck()" /></label>
 <br /><input type="button" onclick="javascript:checkUpload(this.form);" value="$upload" />  <br /><input type="button" onclick="javascript:checkUpload(this.form);" value="$upload" />
 </form>  </form>'
 ENDUPFORM  ENDUPFORM
     $result.='</td></tr></table>'."\n".      $result.='</td></tr></table>'."\n".
              '</td></tr></table><br /><br />'."\n";               '</td></tr></table><br /><br />'."\n";
Line 9175  sub process_clicker_file { Line 9008  sub process_clicker_file {
     if ($env{'form.gradingmechanism'} eq 'given') {      if ($env{'form.gradingmechanism'} eq 'given') {
         $env{'form.givenanswer'}=~s/^\s*//gs;          $env{'form.givenanswer'}=~s/^\s*//gs;
         $env{'form.givenanswer'}=~s/\s*$//gs;          $env{'form.givenanswer'}=~s/\s*$//gs;
         $env{'form.givenanswer'}=~s/[^a-zA-Z0-9\.\*\-\+]+/\,/g;          $env{'form.givenanswer'}=~s/[^a-zA-Z0-9\.\*\-]+/\,/g;
         $env{'form.givenanswer'}=uc($env{'form.givenanswer'});          $env{'form.givenanswer'}=uc($env{'form.givenanswer'});
         my @answers=split(/\,/,$env{'form.givenanswer'});          my @answers=split(/\,/,$env{'form.givenanswer'});
         $foundgiven=$#answers+1;          $foundgiven=$#answers+1;
Line 9235  sub process_clicker_file { Line 9068  sub process_clicker_file {
     $result.=(<<ENDHEADER);      $result.=(<<ENDHEADER);
 <br /><table width="100%" border="0"><tr><td bgcolor="#777777">  <br /><table width="100%" border="0"><tr><td bgcolor="#777777">
 <table width="100%" border="0"><tr bgcolor="#e6ffff"><td>  <table width="100%" border="0"><tr bgcolor="#e6ffff"><td>
 <b>$heading</b></td></tr><tr bgcolor="#ffffe6"><td>  <b>$heading</b></td></tr><tr bgcolor=#ffffe6><td>
 <form method="post" action="/adm/grades" name="clickeranalysis">  <form method="post" action="/adm/grades" name="clickeranalysis">
 <input type="hidden" name="symb" value="$symb" />  <input type="hidden" name="symb" value="$symb" />
 <input type="hidden" name="command" value="assignclickergrades" />  <input type="hidden" name="command" value="assignclickergrades" />
Line 9304  ENDHEADER Line 9137  ENDHEADER
                    "\n".&mt("Username").": <input type='text' name='uname".$id."' />&nbsp;".                     "\n".&mt("Username").": <input type='text' name='uname".$id."' />&nbsp;".
                    "\n".&mt("Domain").": ".                     "\n".&mt("Domain").": ".
                    &Apache::loncommon::select_dom_form($env{'course.'.$env{'request.course.id'}.'.domain'},'udom'.$id).'&nbsp;'.                     &Apache::loncommon::select_dom_form($env{'course.'.$env{'request.course.id'}.'.domain'},'udom'.$id).'&nbsp;'.
                    &Apache::loncommon::selectstudent_link('clickeranalysis','uname'.$id,'udom'.$id,0,$id);                     &Apache::loncommon::selectstudent_link('clickeranalysis','uname'.$id,'udom'.$id);
           $unknown_count++;            $unknown_count++;
        }         }
     }      }
Line 9349  sub iclicker_eval { Line 9182  sub iclicker_eval {
     $id=~s/^[\#0]+//;      $id=~s/^[\#0]+//;
     for (my $i=0;$i<$number;$i++) {      for (my $i=0;$i<$number;$i++) {
  my $idx=3+$i*6;   my $idx=3+$i*6;
                 $entries[$idx]=~s/[^a-zA-Z0-9\.\*\-\+]+//g;  
  push(@idresponses,$entries[$idx]);   push(@idresponses,$entries[$idx]);
     }      }
     $$responses{$id}=join(',',@idresponses);      $$responses{$id}=join(',',@idresponses);
Line 9404  sub assign_clicker_grades { Line 9236  sub assign_clicker_grades {
 # Start screen output  # Start screen output
     my ($result) = &showResourceInfo($symb,$env{'form.probTitle'});      my ($result) = &showResourceInfo($symb,$env{'form.probTitle'});
   
     $result .= '<br />'.      my $heading=&mt('Assigning grades based on clicker file');
                &Apache::loncommon::start_data_table().      $result.=(<<ENDHEADER);
                &Apache::loncommon::start_data_table_header_row().  <br /><table width="100%" border="0"><tr><td bgcolor="#777777">
                '<th>'.&mt('Assigning grades based on clicker file').'</th>'.  <table width="100%" border="0"><tr bgcolor="#e6ffff"><td>
                &Apache::loncommon::end_data_table_header_row().  <b>$heading</b></td></tr><tr bgcolor=#ffffe6><td>
                &Apache::loncommon::start_data_table_row().'<td>';  ENDHEADER
   
 # Get correct result  # Get correct result
 # FIXME: Possibly need delimiter other than ":"  # FIXME: Possibly need delimiter other than ":"
     my @correct=();      my @correct=();
Line 9426  sub assign_clicker_grades { Line 9257  sub assign_clicker_grades {
                     $result.='<br /><span class="LC_warning">'.                      $result.='<br /><span class="LC_warning">'.
                              &mt('More than one correct result given for question "[_1]": [_2] versus [_3].',                               &mt('More than one correct result given for question "[_1]": [_2] versus [_3].',
                                  $env{'form.question:'.$i},$correct[$i],$input[$i]).'</span>';                                   $env{'form.question:'.$i},$correct[$i],$input[$i]).'</span>';
                  } elsif (($input[$i]) || ($input[$i] eq '0')) {                   } elsif ($input[$i]) {
                     $correct[$i]=$input[$i];                      $correct[$i]=$input[$i];
                  }                   }
              }               }
           }            }
        }         }
        for (my $i=0;$i<$number;$i++) {         for (my $i=0;$i<$number;$i++) {
           if ((!$correct[$i]) && ($correct[$i] ne '0')) {            if (!$correct[$i]) {
              $result.='<br /><span class="LC_error">'.               $result.='<br /><span class="LC_error">'.
                       &mt('No correct result given for question "[_1]"!',                        &mt('No correct result given for question "[_1]"!',
                           $env{'form.question:'.$i}).'</span>';                            $env{'form.question:'.$i}).'</span>';
           }            }
        }         }
        $result.='<br />'.&mt("Correct answer: [_1]",join(', ',map { ((($_) || ($_ eq '0'))?$_:'-') } @correct));         $result.='<br />'.&mt("Correct answer: [_1]",join(', ',map { ($_?$_:'-') } @correct));
     }      }
 # Start grading  # Start grading
     my $pcorrect=$env{'form.pcorrect'};      my $pcorrect=$env{'form.pcorrect'};
     my $pincorrect=$env{'form.pincorrect'};      my $pincorrect=$env{'form.pincorrect'};
     my $storecount=0;      my $storecount=0;
     my %users=();  
     foreach my $key (keys(%env)) {      foreach my $key (keys(%env)) {
        my $user='';         my $user='';
        if ($key=~/^form\.student\:(.*)$/) {         if ($key=~/^form\.student\:(.*)$/) {
Line 9459  sub assign_clicker_grades { Line 9289  sub assign_clicker_grades {
              $user=$env{'form.multi'.$id};               $user=$env{'form.multi'.$id};
           }            }
        }         }
        if ($user) {         if ($user) { 
           if ($users{$user}) {  
              $result.='<br /><span class="LC_warning">'.  
                       &mt("More than one entry found for <tt>[_1]</tt>!",$user).  
                       '</span><br />';  
           }  
           $users{$user}=1;  
           my @answer=split(/\,/,$env{$key});            my @answer=split(/\,/,$env{$key});
           my $sum=0;            my $sum=0;
           my $realnumber=$number;            my $realnumber=$number;
Line 9478  sub assign_clicker_grades { Line 9302  sub assign_clicker_grades {
                 } elsif ($correct[$i] eq '*') {                  } elsif ($correct[$i] eq '*') {
                    $sum+=$pcorrect;                     $sum+=$pcorrect;
                 } else {                  } else {
 # We actually grade if correct or not                     if ($answer[$i] eq $correct[$i]) {
                    my $increment=$pincorrect;                        $sum+=$pcorrect;
 # Special case: numerical answer "0"                     } else {
                    if ($correct[$i] eq '0') {                        $sum+=$pincorrect;
                       if ($answer[$i]=~/^[0\.]+$/) {  
                          $increment=$pcorrect;  
                       }  
 # General numerical answer, both evaluate to something non-zero  
                    } elsif ((1.0*$correct[$i]!=0) && (1.0*$answer[$i]!=0)) {  
                       if (1.0*$correct[$i]==1.0*$answer[$i]) {  
                          $increment=$pcorrect;  
                       }  
 # Must be just alphanumeric  
                    } elsif ($answer[$i] eq $correct[$i]) {  
                       $increment=$pcorrect;  
                    }                     }
                    $sum+=$increment;  
                 }                  }
              }               }
           }            }
Line 9517  sub assign_clicker_grades { Line 9329  sub assign_clicker_grades {
     }      }
 # We are done  # We are done
     $result.='<br />'.&mt('Successfully stored grades for [quant,_1,student].',$storecount).      $result.='<br />'.&mt('Successfully stored grades for [quant,_1,student].',$storecount).
              '</td>'.               '</td></tr></table>'."\n".
              &Apache::loncommon::end_data_table_row().               '</td></tr></table><br /><br />'."\n";
              &Apache::loncommon::end_data_table()."<br /><br />\n";  
     return $result.&show_grading_menu_form($symb);      return $result.&show_grading_menu_form($symb);
 }  }
   
Line 9533  sub navmap_errormsg { Line 9344  sub navmap_errormsg {
 sub handler {  sub handler {
     my $request=$_[0];      my $request=$_[0];
     &reset_caches();      &reset_caches();
     if ($request->header_only) {      if ($env{'browser.mathml'}) {
         &Apache::loncommon::content_type($request,'text/html');   &Apache::loncommon::content_type($request,'text/xml');
         $request->send_http_header;      } else {
         return OK;   &Apache::loncommon::content_type($request,'text/html');
     }      }
       $request->send_http_header;
       return '' if $request->header_only;
     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'});      &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'});
   
     my $symb=&get_symb($request,1);      my $symb=&get_symb($request,1);
     my @commands=&Apache::loncommon::get_env_multiple('form.command');      my @commands=&Apache::loncommon::get_env_multiple('form.command');
     my $command=$commands[0];      my $command=$commands[0];
Line 9550  sub handler { Line 9362  sub handler {
   
     $ssi_error = 0;      $ssi_error = 0;
     my $brcrum = [{href=>"/adm/grades",text=>"Grading"}];      my $brcrum = [{href=>"/adm/grades",text=>"Grading"}];
     my $start_page = &Apache::loncommon::start_page('Grading',undef,      $request->print(&Apache::loncommon::start_page('Grading',undef,
                                           {'bread_crumbs' => $brcrum});                                            {'bread_crumbs' => $brcrum}));
     if ($symb eq '' && $command eq '') {      if ($symb eq '' && $command eq '') {
  if ($env{'user.adv'}) {   if ($env{'user.adv'}) {
             &Apache::loncommon::content_type($request,'text/html');  
             $request->send_http_header;  
             $request->print($start_page);  
     if (($env{'form.codeone'}) && ($env{'form.codetwo'}) &&      if (($env{'form.codeone'}) && ($env{'form.codetwo'}) &&
  ($env{'form.codethree'})) {   ($env{'form.codethree'})) {
  my $token=$env{'form.codeone'}.'*'.$env{'form.codetwo'}.'*'.   my $token=$env{'form.codeone'}.'*'.$env{'form.codetwo'}.'*'.
Line 9580  sub handler { Line 9389  sub handler {
     } else {      } else {
  $request->print(&Apache::lonxml::tokeninputfield());   $request->print(&Apache::lonxml::tokeninputfield());
     }      }
         } elsif ($env{'request.course.id'}) {   }
             &init_perm();   
             if (!%perm) {  
                 $request->internal_redirect('/adm/quickgrades');  
             } else {  
                 &Apache::loncommon::content_type($request,'text/html');  
                 $request->send_http_header;  
                 $request->print($start_page);  
             }  
         }  
     } else {      } else {
         &init_perm();   &init_perm();
         if (!$env{'request.course.id'}) {  
             unless ((&Apache::lonnet::allowed('usc',$env{'request.role.domain'})) &&  
                     ($command =~ /^scantronupload/)) {  
                 # Not in a course.  
                 $env{'user.error.msg'}="/adm/grades::vgr:0:0:Cannot display grades page outside course context";  
                 return HTTP_NOT_ACCEPTABLE;  
             }  
         } elsif (!%perm) {  
             $request->internal_redirect('/adm/quickgrades');  
         }  
         &Apache::loncommon::content_type($request,'text/html');  
         $request->send_http_header;  
         $request->print($start_page);  
  if ($command eq 'submission' && $perm{'vgr'}) {   if ($command eq 'submission' && $perm{'vgr'}) {
     ($env{'form.student'} eq '' ? &listStudents($request) : &submission($request,0,0));      ($env{'form.student'} eq '' ? &listStudents($request) : &submission($request,0,0));
  } elsif ($command eq 'pickStudentPage' && $perm{'vgr'}) {   } elsif ($command eq 'pickStudentPage' && $perm{'vgr'}) {
Line 9682  sub handler { Line 9469  sub handler {
     }      }
     $request->print(&Apache::loncommon::end_page());      $request->print(&Apache::loncommon::end_page());
     &reset_caches();      &reset_caches();
     return OK;      return '';
 }  }
   
 1;  1;
Line 9809  ssi_with_retries() Line 9596  ssi_with_retries()
   
 =item  scantron_process_students() :   =item  scantron_process_students() : 
   
    Routine that does the actual grading of the bubblesheet information.     Routine that does the actual grading of the bubble sheet information.
   
    The parsed scanline hash is added to %env      The parsed scanline hash is added to %env 
   
Line 9829  ssi_with_retries() Line 9616  ssi_with_retries()
   
 =item  scantron_upload_scantron_data() :  =item  scantron_upload_scantron_data() :
   
     Creates the screen for adding a new bubblesheet data file to a course.      Creates the screen for adding a new bubble sheet data file to a course.
   
 =item  scantron_upload_scantron_data_save() :   =item  scantron_upload_scantron_data_save() : 
   
Line 9843  ssi_with_retries() Line 9630  ssi_with_retries()
 =item  scantron_download_scantron_data() :   =item  scantron_download_scantron_data() : 
   
    Shows a list of the three internal files (original, corrected,     Shows a list of the three internal files (original, corrected,
    skipped) for a specific bubblesheet data file that exists in the     skipped) for a specific bubble sheet data file that exists in the
    course.     course.
   
 =item  scantron_validate_ID() :   =item  scantron_validate_ID() : 

Removed from v.1.596.2.13  
changed lines
  Added in v.1.597


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>