Diff for /loncom/homework/grades.pm between versions 1.596.2.12.2.41.2.4 and 1.596.2.12.2.60

version 1.596.2.12.2.41.2.4, 2019/02/05 16:13:05 version 1.596.2.12.2.60, 2022/02/09 23:50:00
Line 43  use Apache::lonmsg(); Line 43  use Apache::lonmsg();
 use Apache::Constants qw(:common :http);  use Apache::Constants qw(:common :http);
 use Apache::lonlocal;  use Apache::lonlocal;
 use Apache::lonenc;  use Apache::lonenc;
   use Apache::lonstathelpers;
 use Apache::bridgetask();  use Apache::bridgetask();
   use Apache::lontexconvert();
   use HTML::Parser();
   use File::MMagic;
 use String::Similarity;  use String::Similarity;
 use LONCAPA;  use LONCAPA;
   
Line 98  sub ssi_print_error { Line 102  sub ssi_print_error {
   
 #  #
 # --- Retrieve the parts from the metadata file.---  # --- Retrieve the parts from the metadata file.---
   # Returns an array of everything that the resources stores away
   #
   
 sub getpartlist {  sub getpartlist {
     my ($symb,$errorref) = @_;      my ($symb,$errorref) = @_;
   
Line 122  sub getpartlist { Line 129  sub getpartlist {
     return @stores;      return @stores;
 }  }
   
 # --- Get the symbolic name of a problem and the url  
 sub get_symb {  
     my ($request,$silent) = @_;  
     my $symb=$env{'form.symb'};  
     unless ($symb) {  
         (my $url=$env{'form.url'}) =~ s-^http://($ENV{'SERVER_NAME'}|$ENV{'HTTP_HOST'})--;  
         $symb = &Apache::lonnet::symbread($url);  
         if ($symb eq '') {   
     if (!$silent) {  
                 $request->print(&mt("Unable to handle ambiguous references: [_1].",$url));  
         return ();  
     }  
         }  
     }  
     &Apache::lonenc::check_decrypt(\$symb);  
     return ($symb);  
 }  
   
 #--- Format fullname, username:domain if different for display  #--- Format fullname, username:domain if different for display
 #--- Use anywhere where the student names are listed  #--- Use anywhere where the student names are listed
 sub nameUserString {  sub nameUserString {
Line 154  sub nameUserString { Line 143  sub nameUserString {
   
 #--- Get the partlist and the response type for a given problem. ---  #--- Get the partlist and the response type for a given problem. ---
 #--- Indicate if a response type is coded handgraded or not. ---  #--- Indicate if a response type is coded handgraded or not. ---
   #--- Count responseIDs, essayresponse items, and dropbox items ---
   #--- Sets response_error pointer to "1" if navmaps object broken ---
 sub response_type {  sub response_type {
     my ($symb,$response_error) = @_;      my ($symb,$response_error) = @_;
   
Line 170  sub response_type { Line 161  sub response_type {
         return;          return;
     }      }
     my $partlist = $res->parts();      my $partlist = $res->parts();
       my ($numresp,$numessay,$numdropbox) = (0,0,0);
     my %vPart =       my %vPart = 
  map { $_ => 1 } (&Apache::loncommon::get_env_multiple('form.vPart'));   map { $_ => 1 } (&Apache::loncommon::get_env_multiple('form.vPart'));
     my (%response_types,%handgrade);      my (%response_types,%handgrade);
Line 179  sub response_type { Line 171  sub response_type {
  my @types = $res->responseType($part);   my @types = $res->responseType($part);
  my @ids = $res->responseIds($part);   my @ids = $res->responseIds($part);
  for (my $i=0; $i < scalar(@ids); $i++) {   for (my $i=0; $i < scalar(@ids); $i++) {
               $numresp ++;
     $response_types{$part}{$ids[$i]} = $types[$i];      $response_types{$part}{$ids[$i]} = $types[$i];
               if ($types[$i] eq 'essay') {
                   $numessay ++;
                   if (&Apache::lonnet::EXT("resource.$part".'_'.$ids[$i].".uploadedfiletypes",$symb)) {
                       $numdropbox ++;
                   }
               }
     $handgrade{$part.'_'.$ids[$i]} =       $handgrade{$part.'_'.$ids[$i]} = 
  &Apache::lonnet::EXT('resource.'.$part.'_'.$ids[$i].   &Apache::lonnet::EXT('resource.'.$part.'_'.$ids[$i].
      '.handgrade',$symb);       '.handgrade',$symb);
  }   }
     }      }
     return ($partlist,\%handgrade,\%response_types);      return ($partlist,\%handgrade,\%response_types,$numresp,$numessay,$numdropbox);
 }  }
   
 sub flatten_responseType {  sub flatten_responseType {
Line 212  sub get_display_part { Line 211  sub get_display_part {
     return $display;      return $display;
 }  }
   
 #--- Show resource title  #--- Show parts and response type
 #--- and parts and response type  
 sub showResourceInfo {  sub showResourceInfo {
     my ($symb,$probTitle,$checkboxes,$res_error) = @_;      my ($symb,$partlist,$responseType,$formname,$checkboxes,$uploads) = @_;
     my $result = '<h3>'.&mt('Current Resource').': '.$probTitle.'</h3>'."\n";      unless ((ref($partlist) eq 'ARRAY') && (ref($responseType) eq 'HASH')) {
     my ($partlist,$handgrade,$responseType) = &response_type($symb,$res_error);          return '<br clear="all">';
     if (ref($res_error)) {      }
         if ($$res_error) {      my $coltitle = &mt('Problem Part Shown');
             return;      if ($checkboxes) {
           $coltitle = &mt('Problem Part');
       } else {
           my $checkedparts = 0;
           foreach my $partid (&Apache::loncommon::get_env_multiple('form.vPart')) {
               if (grep(/^\Q$partid\E$/,@{$partlist})) {
                   $checkedparts ++;
               }
           }
           if ($checkedparts == scalar(@{$partlist})) {
               return '<br clear="all">';
         }          }
           if ($uploads) {
               $coltitle = &mt('Problem Part Selected');
           }
       }
       my $result = '<div class="LC_left_float" style="display:inline-block;">';
       if ($checkboxes) {
           my $legend = &mt('Parts to display');
           if ($uploads) {
               $legend = &mt('Part(s) with dropbox');
           }
           $result .= '<fieldset style="display:inline-block;"><legend>'.$legend.'</legend>'.
                      '<span class="LC_nobreak">'.
                      '<label><input type="radio" name="chooseparts" value="0" onclick="toggleParts('."'$formname'".');" checked="checked" />'.
                      &mt('All parts').'</label>'.('&nbsp;'x2).
                      '<label><input type="radio" name="chooseparts" value="1" onclick="toggleParts('."'$formname'".');" />'.
                      &mt('Selected parts').'</label></span>'.
                      '<div id="LC_partselector" style="display:none">';
     }      }
     $result.=&Apache::loncommon::start_data_table()      $result .= &Apache::loncommon::start_data_table()
             .&Apache::loncommon::start_data_table_header_row();                .&Apache::loncommon::start_data_table_header_row();
     if ($checkboxes) {      if ($checkboxes) {
         $result.='<th>&nbsp;</th>';          $result .= '<th>'.&mt('Display?').'</th>';
     }      }
     $result.='<th>'.&mt('Problem Part').'</th>'      $result .= '<th>'.$coltitle.'</th>'
             .'<th>'.&mt('Res. ID').'</th>'                .'<th>'.&mt('Res. ID').'</th>'
             .'<th>'.&mt('Type').'</th>'                .'<th>'.&mt('Type').'</th>'
             .&Apache::loncommon::end_data_table_header_row();                .&Apache::loncommon::end_data_table_header_row();
     my %resptype = ();  
     my $hdgrade='no';  
     my %partsseen;      my %partsseen;
     foreach my $partID (sort(keys(%$responseType))) {      foreach my $partID (sort(keys(%$responseType))) {
         foreach my $resID (sort(keys(%{ $responseType->{$partID} }))) {          foreach my $resID (sort(keys(%{ $responseType->{$partID} }))) {
             my $handgrade=$$handgrade{$partID.'_'.$resID};  
             my $responsetype = $responseType->{$partID}->{$resID};              my $responsetype = $responseType->{$partID}->{$resID};
             $hdgrade = $handgrade if ($handgrade eq 'yes');              if ($uploads) {
             $result.=&Apache::loncommon::start_data_table_row();                  next unless ($responsetype eq 'essay');
             if ($checkboxes) {                  next unless (&Apache::lonnet::EXT("resource.$partID".'_'."$resID.uploadedfiletypes",$symb));
                 if (exists($partsseen{$partID})) {              }
                     $result.="<td>&nbsp;</td>";              my $display_part=&get_display_part($partID,$symb);
               if (exists($partsseen{$partID})) {
                   $result.=&Apache::loncommon::continue_data_table_row();
               } else {
                   $partsseen{$partID}=scalar(keys(%{$responseType->{$partID}}));
                   $result.=&Apache::loncommon::start_data_table_row().
                            '<td rowspan="'.$partsseen{$partID}.'" style="vertical-align:middle">';
                   if ($checkboxes) {
                       $result.='<input type="checkbox" name="vPart" checked="checked" value="'.$partID.'" /></td>'.
                                '<td rowspan="'.$partsseen{$partID}.'" style="vertical-align:middle">'.$display_part.'</td>';
                 } else {                  } else {
                     $result.="<td><input type='checkbox' name='vPart' value='$partID' checked='checked' /></td>";                      $result.=$display_part.'</td>';
                 }                  }
                 $partsseen{$partID}=1;  
             }              }
             my $display_part=&get_display_part($partID,$symb);              $result.='<td>'.'<span class="LC_internal_info">'.$resID.'</span></td>'
             $result.='<td>'.$display_part.'</td>'  
                     .'<td>'.'<span class="LC_internal_info">'.$resID.'</span></td>'  
                     .'<td>'.&mt($responsetype).'</td>'                      .'<td>'.&mt($responsetype).'</td>'
 #                   .'<td><b>'.&mt('Handgrade: [_1]',$handgrade).'</b></td>'  
                     .&Apache::loncommon::end_data_table_row();                      .&Apache::loncommon::end_data_table_row();
         }          }
     }      }
     $result.=&Apache::loncommon::end_data_table();      $result.=&Apache::loncommon::end_data_table();
     return $result,$responseType,$hdgrade,$partlist,$handgrade;      if ($checkboxes) {
           $result .= '</div></fieldset>';
       }
       $result .= '</div><div style="padding:0;clear:both;margin:0;border:0"></div>';
       if (!keys(%partsseen)) {
           $result = '';
           if ($uploads) {
               return '<div style="padding:0;clear:both;margin:0;border:0"></div>'.
                      '<p class="LC_info">'.
                       &mt('No dropbox items or essayresponse items with uploadedfiletypes set.').
                      '</p>';
           } else {
               return '<br clear="all" />';
           }
       }  
       return $result;
   }
   
   sub part_selector_js {
       my $js = <<"END";
   function toggleParts(formname) {
       if (document.getElementById('LC_partselector')) {
           var index = '';
           if (document.forms.length) {
               for (var i=0; i<document.forms.length; i++) {
                   if (document.forms[i].name == formname) {
                       index = i;
                       break;
                   }
               }
           }
           if ((index != '') && (document.forms[index].elements['chooseparts'].length > 1)) {
               for (var i=0; i<document.forms[index].elements['chooseparts'].length; i++) {
                   if (document.forms[index].elements['chooseparts'][i].checked) {
                      var val = document.forms[index].elements['chooseparts'][i].value;
                       if (document.forms[index].elements['chooseparts'][i].value == 1) {
                           document.getElementById('LC_partselector').style.display = 'block';
                       } else {
                           document.getElementById('LC_partselector').style.display = 'none';
                       }
                   }
               }
           }
       }
   }
   END
       return &Apache::lonhtmlcommon::scripttag($js);
 }  }
   
 sub reset_caches {  sub reset_caches {
Line 440  sub cleanRecord { Line 513  sub cleanRecord {
     $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 @answer = %answer;
           %answer = map {&HTML::Entities::encode($_, '"<>&')}  @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,$type,$trial,$rndseed);
Line 472  sub cleanRecord { Line 547  sub cleanRecord {
     $env{'form.kwstyle'}  = $keyhash{$loginuser.'_kwstyle'} ne '' ? $keyhash{$loginuser.'_kwstyle'} : '';      $env{'form.kwstyle'}  = $keyhash{$loginuser.'_kwstyle'} ne '' ? $keyhash{$loginuser.'_kwstyle'} : '';
     $env{'form.'.$symb} = 1; # so that we don't have to read it from disk for multiple sub of the same prob.      $env{'form.'.$symb} = 1; # so that we don't have to read it from disk for multiple sub of the same prob.
  }   }
           $answer = &Apache::lontexconvert::msgtexconverted($answer);
  return '<br /><br /><blockquote><tt>'.&keywords_highlight($answer).'</tt></blockquote>';   return '<br /><br /><blockquote><tt>'.&keywords_highlight($answer).'</tt></blockquote>';
     } elsif ( $response eq 'organic') {      } elsif ( $response eq 'organic') {
         my $result=&mt('Smile representation: [_1]',          my $result=&mt('Smile representation: [_1]',
Line 514  sub cleanRecord { Line 590  sub cleanRecord {
  $answer =    $answer = 
     &Apache::loncommon::format_previous_attempt_value('submission',      &Apache::loncommon::format_previous_attempt_value('submission',
       $answer);        $answer);
         return $answer;   return $answer;
     }      }
     return &HTML::Entities::encode($answer, '"<>&');      return &HTML::Entities::encode($answer, '"<>&');
 }  }
Line 522  sub cleanRecord { Line 598  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 551  sub commonJSfunctions { Line 626  sub commonJSfunctions {
     return selectOne.value;      return selectOne.value;
  }   }
     }      }
 </script>  
 COMMONJSFUNCTIONS  COMMONJSFUNCTIONS
 }  }
   
 #--- Dumps the class list with usernames,list of sections,  #--- Dumps the class list with usernames,list of sections,
 #--- section, ids and fullnames for each user.  #--- section, ids and fullnames for each user.
 sub getclasslist {  sub getclasslist {
     my ($getsec,$filterlist,$getgroup) = @_;      my ($getsec,$filterbyaccstatus,$getgroup,$symb,$submitonly,$filterbysubmstatus) = @_;
     my @getsec;      my @getsec;
     my @getgroup;      my @getgroup;
     my $stu_status = join(':',&Apache::loncommon::get_env_multiple('form.Status'));      my $stu_status = join(':',&Apache::loncommon::get_env_multiple('form.Status'));
Line 586  sub getclasslist { Line 660  sub getclasslist {
     #      #
     my %sections;      my %sections;
     my %fullnames;      my %fullnames;
       my ($cdom,$cnum,$partlist);
       if (($filterbysubmstatus) && ($submitonly ne 'all') && ($symb ne '')) {
           $cdom = $env{"course.$env{'request.course.id'}.domain"};
           $cnum = $env{"course.$env{'request.course.id'}.num"};
           my $res_error;
           ($partlist) = &response_type($symb,\$res_error);
       }
     foreach my $student (keys(%$classlist)) {      foreach my $student (keys(%$classlist)) {
         my $end      =           my $end      = 
             $classlist->{$student}->[&Apache::loncoursedata::CL_END()];              $classlist->{$student}->[&Apache::loncoursedata::CL_END()];
Line 602  sub getclasslist { Line 683  sub getclasslist {
         my $group   =           my $group   = 
             $classlist->{$student}->[&Apache::loncoursedata::CL_GROUP()];              $classlist->{$student}->[&Apache::loncoursedata::CL_GROUP()];
  # filter students according to status selected   # filter students according to status selected
  if ($filterlist && (!($stu_status =~ /Any/))) {   if ($filterbyaccstatus && (!($stu_status =~ /Any/))) {
     if (!($stu_status =~ $status)) {      if (!($stu_status =~ $status)) {
  delete($classlist->{$student});   delete($classlist->{$student});
  next;   next;
Line 619  sub getclasslist { Line 700  sub getclasslist {
                }                  } 
         }          }
            if (($grp eq 'none') && !$group) {             if (($grp eq 'none') && !$group) {
                $exclude = 0;             $exclude = 0;
         }          }
     }      }
     if ($exclude) {      if ($exclude) {
         delete($classlist->{$student});          delete($classlist->{$student});
    next;
     }      }
  }   }
           if (($filterbysubmstatus) && ($submitonly ne 'all') && ($symb ne '')) {
               my $udom =
                   $classlist->{$student}->[&Apache::loncoursedata::CL_SDOM()];
               my $uname =
                   $classlist->{$student}->[&Apache::loncoursedata::CL_SNAME()];
               if (($symb ne '') && ($udom ne '') && ($uname ne '')) {
                   if ($submitonly eq 'queued') {
                       my %queue_status =
                           &Apache::bridgetask::get_student_status($symb,$cdom,$cnum,
                                                                   $udom,$uname);
                       if (!defined($queue_status{'gradingqueue'})) {
                           delete($classlist->{$student});
                           next;
                       }
                   } else {
                       my (%status) =&student_gradeStatus($symb,$udom,$uname,$partlist);
                       my $submitted = 0;
                       my $graded = 0;
                       my $incorrect = 0;
                       foreach (keys(%status)) {
                           $submitted = 1 if ($status{$_} ne 'nothing');
                           $graded = 1 if ($status{$_} =~ /^ungraded/);
                           $incorrect = 1 if ($status{$_} =~ /^incorrect/);
   
                           my ($foo,$partid,$foo1) = split(/\./,$_);
                           if ($status{'resource.'.$partid.'.submitted_by'} ne '') {
                               $submitted = 0;
                           }
                       }
                       if (!$submitted && ($submitonly eq 'yes' ||
                                           $submitonly eq 'incorrect' ||
                                           $submitonly eq 'graded')) {
                           delete($classlist->{$student});
                           next;
                       } elsif (!$graded && ($submitonly eq 'graded')) {
                           delete($classlist->{$student});
                           next;
                       } elsif (!$incorrect && $submitonly eq 'incorrect') {
                           delete($classlist->{$student});
                           next;
                       }
                   }
               }
           }
  $section = ($section ne '' ? $section : 'none');   $section = ($section ne '' ? $section : 'none');
  if (&canview($section)) {   if (&canview($section)) {
     if (!@getsec || grep(/^\Q$section\E$/,@getsec)) {      if (!@getsec || grep(/^\Q$section\E$/,@getsec)) {
Line 640  sub getclasslist { Line 766  sub getclasslist {
     delete($classlist->{$student});      delete($classlist->{$student});
  }   }
     }      }
     my %seen = ();  
     my @sections = sort(keys(%sections));      my @sections = sort(keys(%sections));
     return ($classlist,\@sections,\%fullnames);      return ($classlist,\@sections,\%fullnames);
 }  }
Line 656  sub canmodify { Line 781  sub canmodify {
  #can modify the requested section   #can modify the requested section
  return 1;   return 1;
     } else {      } else {
  # can't modify the request section   # can't modify the requested section
  return 0;   return 0;
     }      }
  }   }
Line 669  sub canview { Line 794  sub canview {
     my ($sec)=@_;      my ($sec)=@_;
     if ($perm{'vgr'}) {      if ($perm{'vgr'}) {
  if (!defined($perm{'vgr_section'})) {   if (!defined($perm{'vgr_section'})) {
     # can modify whole class      # can view whole class
     return 1;      return 1;
  } else {   } else {
     if ($sec eq $perm{'vgr_section'}) {      if ($sec eq $perm{'vgr_section'}) {
  #can modify the requested section   #can view the requested section
  return 1;   return 1;
     } else {      } else {
  # can't modify the request section   # can't view the requested section
  return 0;   return 0;
     }      }
  }   }
     }      }
     #can't modify      #can't view
     return 0;      return 0;
 }  }
   
Line 706  sub student_gradeStatus { Line 831  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="probTitle" value="'.$env{'form.probTitle'}.'" />'."\n".  
  '<input type="hidden" name="Status"  value="'.$stu_status.'" />'."\n".   '<input type="hidden" name="Status"  value="'.$stu_status.'" />'."\n".
  '<input type="hidden" name="command" value="submission" />'."\n".   '<input type="hidden" name="command" value="submission" />'."\n".
  '<input type="hidden" name="student" value="" />'."\n".   '<input type="hidden" name="student" value="" />'."\n".
Line 810  sub most_similar { Line 933  sub most_similar {
   
 #------------------------------------ Receipt Verification Routines  #------------------------------------ Receipt Verification Routines
 #  #
   
   sub initialverifyreceipt {
      my ($request,$symb) = @_;
      &commonJSfunctions($request);
      return '<form name="gradingMenu" action=""><input type="submit" value="'.&mt('Verify Receipt Number.').'" />'.
           &Apache::lonnet::recprefix($env{'request.course.id'}).
           '-<input type="text" name="receipt" size="4" />'.
           '<input type="hidden" name="symb" value="'.&Apache::lonenc::check_encrypt($symb).'" />'."\n".
           '<input type="hidden" name="command" value="verify" />'.
           "</form>\n";
   }
   
 #--- Check whether a receipt number is valid.---  #--- Check whether a receipt number is valid.---
 sub verifyreceipt {  sub verifyreceipt {
     my $request  = shift;      my ($request,$symb) = @_;
   
     my $courseid = $env{'request.course.id'};      my $courseid = $env{'request.course.id'};
     my $receipt  = &Apache::lonnet::recprefix($courseid).'-'.      my $receipt  = &Apache::lonnet::recprefix($courseid).'-'.
  $env{'form.receipt'};   $env{'form.receipt'};
     $receipt     =~ s/[^\-\d]//g;      $receipt     =~ s/[^\-\d]//g;
     my ($symb)   = &get_symb($request);  
   
     my $title.=      my $title =
  '<h3><span class="LC_info">'.   '<h3><span class="LC_info">'.
  &mt('Verifying Receipt No. [_1]',$receipt).   &mt('Verifying Receipt Number [_1]',$receipt).
  '</span></h3>'."\n".   '</span></h3>'."\n";
  '<h4>'.&mt('[_1]Resource: [_2]','<b>','</b>'.$env{'form.probTitle'}).  
  '</h4>'."\n";  
   
     my ($string,$contents,$matches) = ('','',0);      my ($string,$contents,$matches) = ('','',0);
     my (undef,undef,$fullname) = &getclasslist('all','0');      my (undef,undef,$fullname) = &getclasslist('all','0');
Line 895  sub verifyreceipt { Line 1027  sub verifyreceipt {
     $contents.      $contents.
     &Apache::loncommon::end_data_table()."\n";      &Apache::loncommon::end_data_table()."\n";
     }      }
     return $string.&show_grading_menu_form($symb);      return $string;
 }  }
   
 #--- This is called by a number of programs.  #--- This is called by a number of programs.
Line 903  sub verifyreceipt { Line 1035  sub verifyreceipt {
 #--- Also called directly when one clicks on the subm button   #--- Also called directly when one clicks on the subm button 
 #    on the problem page.  #    on the problem page.
 sub listStudents {  sub listStudents {
     my ($request) = shift;      my ($request,$symb,$submitonly,$divforres) = @_;
   
     my ($symb) = &get_symb($request);  
     my $cdom      = $env{"course.$env{'request.course.id'}.domain"};      my $cdom      = $env{"course.$env{'request.course.id'}.domain"};
     my $cnum      = $env{"course.$env{'request.course.id'}.num"};      my $cnum      = $env{"course.$env{'request.course.id'}.num"};
     my $getsec    = $env{'form.section'} eq '' ? 'all' : $env{'form.section'};      my $getsec    = $env{'form.section'} eq '' ? 'all' : $env{'form.section'};
     my $getgroup  = $env{'form.group'} eq '' ? 'all' : $env{'form.group'};      my $getgroup  = $env{'form.group'} eq '' ? 'all' : $env{'form.group'};
     my $submitonly= $env{'form.submitonly'} eq '' ? 'all' : $env{'form.submitonly'};      unless ($submitonly) {
     my $viewgrade = $env{'form.showgrading'} eq 'yes' ? 'View/Grade/Regrade' : 'View';          $submitonly = $env{'form.submitonly'} eq '' ? 'all' : $env{'form.submitonly'};
     $env{'form.probTitle'} = $env{'form.probTitle'} eq '' ?       }
  &Apache::lonnet::gettitle($symb) : $env{'form.probTitle'};  
       my $result='';
     my $result='<h3><span class="LC_info">&nbsp;'      my $res_error;
  .&mt("$viewgrade Submissions for a Student or a Group of Students")      my ($partlist,$handgrade,$responseType,$numresp,$numessay) = &response_type($symb,\$res_error);
  .'</span></h3>';  
   
     my ($table,undef,$hdgrade,$partlist,$handgrade) = &showResourceInfo($symb,$env{'form.probTitle'},($env{'form.showgrading'} eq 'yes'));      my $table;
       if (ref($partlist) eq 'ARRAY') {
           if (scalar(@$partlist) > 1 ) {
               $table = &showResourceInfo($symb,$partlist,$responseType,'gradesub',1);
           } elsif ($divforres) {
               $table = '<div style="padding:0;clear:both;margin:0;border:0"></div>';
           } else {
               $table = '<br clear="all" />';
           }
       }
   
     my %js_lt = &Apache::lonlocal::texthash (      my %js_lt = &Apache::lonlocal::texthash (
  '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.',
      );       );
     &js_escape(\%js_lt);      &js_escape(\%js_lt);
     $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 956  sub listStudents { Line 1094  sub listStudents {
  formname.command.value = 'submission';   formname.command.value = 'submission';
  formname.submit();   formname.submit();
     }      }
 </script>  
 LISTJAVASCRIPT  LISTJAVASCRIPT
   
     &commonJSfunctions($request);      &commonJSfunctions($request);
     $request->print($result);      $request->print($result);
   
     my $checkhdgrade = ($env{'form.handgrade'} eq 'yes' && scalar(@$partlist) > 1 ) ? 'checked="checked"' : '';  
     my $checklastsub = $checkhdgrade eq '' ? 'checked="checked"' : '';  
     my $gradeTable='<form action="/adm/grades" method="post" name="gradesub">'.      my $gradeTable='<form action="/adm/grades" method="post" name="gradesub">'.
  "\n".$table;   "\n".$table;
   
     $gradeTable .= &Apache::lonhtmlcommon::start_pick_box();      $gradeTable .= &Apache::lonhtmlcommon::start_pick_box();
     $gradeTable .= &Apache::lonhtmlcommon::row_title(&mt('View Problem Text'))      $gradeTable .= &Apache::lonhtmlcommon::row_title(&mt('View Problem Text'))
                   .'<label><input type="radio" name="vProb" value="no" checked="checked" /> '.&mt('no').' </label>'."\n"                    .'<label><input type="radio" name="vProb" value="no" checked="checked" /> '.&mt('no').' </label>'."\n"
Line 979  LISTJAVASCRIPT Line 1114  LISTJAVASCRIPT
                   .'<label><input type="radio" name="vAns" value="all" checked="checked" /> '.&mt('all students').' </label><br />'."\n"                    .'<label><input type="radio" name="vAns" value="all" checked="checked" /> '.&mt('all students').' </label><br />'."\n"
                   .&Apache::lonhtmlcommon::row_closure();                    .&Apache::lonhtmlcommon::row_closure();
   
     my $submission_options;  
     if ($env{'form.handgrade'} eq 'yes' && scalar(@$partlist) > 1) {  
  $submission_options.=  
     '<label><input type="radio" name="lastSub" value="hdgrade" '.$checkhdgrade.' /> '.&mt('essay part only').' </label>'."\n";  
     }  
     my $stu_status = join(':',&Apache::loncommon::get_env_multiple('form.Status'));      my $stu_status = join(':',&Apache::loncommon::get_env_multiple('form.Status'));
     my $saveStatus = $stu_status eq '' ? 'Active' : $stu_status;      my $saveStatus = $stu_status eq '' ? 'Active' : $stu_status;
     $env{'form.Status'} = $saveStatus;      $env{'form.Status'} = $saveStatus;
     $submission_options.=      my %optiontext = &Apache::lonlocal::texthash (
                             lastonly => 'last submission',
                             last     => 'last submission with details',
                             datesub  => 'all submissions',
                             all      => 'all submissions with details',
                         );
       my $submission_options =
         '<span class="LC_nobreak">'.          '<span class="LC_nobreak">'.
         '<label><input type="radio" name="lastSub" value="lastonly" '.$checklastsub.' /> '.          '<label><input type="radio" name="lastSub" value="lastonly" /> '.
         &mt('last submission only').' </label></span>'."\n".          $optiontext{'lastonly'}.' </label></span>'."\n".
         '<span class="LC_nobreak">'.          '<span class="LC_nobreak">'.
         '<label><input type="radio" name="lastSub" value="last" /> '.          '<label><input type="radio" name="lastSub" value="last" /> '.
         &mt('last submission &amp; parts info').' </label></span>'."\n".          $optiontext{'last'}.' </label></span>'."\n".
         '<span class="LC_nobreak">'.          '<span class="LC_nobreak">'.
         '<label><input type="radio" name="lastSub" value="datesub" /> '.          '<label><input type="radio" name="lastSub" value="datesub" checked="checked" /> '.
         &mt('by dates and submissions').'</label></span>'."\n".          $optiontext{'datesub'}.'</label></span>'."\n".
         '<span class="LC_nobreak">'.          '<span class="LC_nobreak">'.
         '<label><input type="radio" name="lastSub" value="all" /> '.          '<label><input type="radio" name="lastSub" value="all" /> '.
         &mt('all details').'</label></span>';          $optiontext{'all'}.'</label></span>';
       my ($compmsg,$nocompmsg);
       $nocompmsg = ' checked="checked"';
       if ($numessay) {
           $compmsg = $nocompmsg;
           $nocompmsg = '';
       }
     $gradeTable .= &Apache::lonhtmlcommon::row_title(&mt('Submissions'))      $gradeTable .= &Apache::lonhtmlcommon::row_title(&mt('Submissions'))
                   .$submission_options                    .$submission_options;
   # Check if any gradable
       my $showmore;
       if ($perm{'mgr'}) {
           my @sections;
           if ($env{'request.course.sec'} ne '') {
               @sections = ($env{'request.course.sec'});
           } elsif ($env{'form.section'} eq '') {
               @sections = ('all');
           } else {
               @sections = &Apache::loncommon::get_env_multiple('form.section');
           }
           if (grep(/^all$/,@sections)) {
               $showmore = 1;
           } else {
               foreach my $sec (@sections) {
                   if (&canmodify($sec)) {
                       $showmore = 1;
                       last;
                   }
               }
           }
       }
   
       if ($showmore) {
           $gradeTable .=
                      &Apache::lonhtmlcommon::row_closure()
                     .&Apache::lonhtmlcommon::row_title(&mt('Send Messages'))
                     .'<span class="LC_nobreak">'
                     .'<label><input type="radio" name="compmsg" value="0"'.$nocompmsg.' />'
                     .&mt('No').('&nbsp;'x2).'</label>'
                     .'<label><input type="radio" name="compmsg" value="1"'.$compmsg.' />'
                     .&mt('Yes').('&nbsp;'x2).'</label>'
                   .&Apache::lonhtmlcommon::row_closure();                    .&Apache::lonhtmlcommon::row_closure();
   
     $gradeTable .= &Apache::lonhtmlcommon::row_title(&mt('Grading Increments'))          $gradeTable .= 
                      &Apache::lonhtmlcommon::row_title(&mt('Grading Increments'))
                   .'<select name="increment">'                    .'<select name="increment">'
                   .'<option value="1">'.&mt('Whole Points').'</option>'                    .'<option value="1">'.&mt('Whole Points').'</option>'
                   .'<option value=".5">'.&mt('Half Points').'</option>'                    .'<option value=".5">'.&mt('Half Points').'</option>'
                   .'<option value=".25">'.&mt('Quarter Points').'</option>'                    .'<option value=".25">'.&mt('Quarter Points').'</option>'
                   .'<option value=".1">'.&mt('Tenths of a Point').'</option>'                    .'<option value=".1">'.&mt('Tenths of a Point').'</option>'
                   .'</select>'                    .'</select>';
                   .&Apache::lonhtmlcommon::row_closure();      }
   
     $gradeTable .=       $gradeTable .= 
         &build_section_inputs().          &build_section_inputs().
  '<input type="hidden" name="submitonly"  value="'.$submitonly.'" />'."\n".   '<input type="hidden" name="submitonly"  value="'.$submitonly.'" />'."\n".
  '<input type="hidden" name="handgrade"   value="'.$env{'form.handgrade'}.'" /><br />'."\n".  
  '<input type="hidden" name="showgrading" value="'.$env{'form.showgrading'}.'" /><br />'."\n".  
  '<input type="hidden" name="saveState"   value="'.$env{'form.saveState'}.'" />'."\n".  
  '<input type="hidden" name="probTitle"   value="'.$env{'form.probTitle'}.'" />'."\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="saveStatusOld" value="'.$saveStatus.'" />'."\n";   '<input type="hidden" name="saveStatusOld" value="'.$saveStatus.'" />'."\n";
       if (exists($env{'form.Status'})) {
     if (exists($env{'form.gradingMenu'}) && exists($env{'form.Status'})) {   $gradeTable .= '<input type="hidden" name="Status" value="'.$env{'form.Status'}.'" />'."\n";
  $gradeTable .= '<input type="hidden" name="Status" value="'.$stu_status.'" />'."\n";  
     } else {      } else {
         $gradeTable .= &Apache::lonhtmlcommon::row_title(&mt('Student Status'))          $gradeTable .= &Apache::lonhtmlcommon::row_closure()
                         .&Apache::lonhtmlcommon::row_title(&mt('Student Status'))
                       .&Apache::lonhtmlcommon::StatusOptions(                        .&Apache::lonhtmlcommon::StatusOptions(
                            $saveStatus,undef,1,'javascript:reLoadList(this.form);')                             $saveStatus,undef,1,'javascript:reLoadList(this.form);');
                       .&Apache::lonhtmlcommon::row_closure();  
     }      }
       if ($numessay) {
     $gradeTable .= &Apache::lonhtmlcommon::row_title(&mt('Check For Plagiarism'))          $gradeTable .= &Apache::lonhtmlcommon::row_closure()
                   .'<input type="checkbox" name="checkPlag" checked="checked" />'                        .&Apache::lonhtmlcommon::row_title(&mt('Check For Plagiarism'))
                   .&Apache::lonhtmlcommon::row_closure(1)                        .'<input type="checkbox" name="checkPlag" checked="checked" />';
       }
       $gradeTable .= &Apache::lonhtmlcommon::row_closure(1)
                   .&Apache::lonhtmlcommon::end_pick_box();                    .&Apache::lonhtmlcommon::end_pick_box();
   
     $gradeTable .= '<p>'      $gradeTable .= '<p>'
                   .&mt('To '.lc($viewgrade)." a submission or a group of submissions, click on the check box(es) next to the student's name(s). Then click on the Next button.")."\n"                    .&mt("To view/grade/regrade a submission or a group of submissions, click on the check box(es) next to the student's name(s). Then click on the Next button.")."\n"
                   .'<input type="hidden" name="command" value="processGroup" />'                    .'<input type="hidden" name="command" value="processGroup" />'
                   .'</p>';                    .'</p>';
   
Line 1055  LISTJAVASCRIPT Line 1226  LISTJAVASCRIPT
     while ($loop < 2) {      while ($loop < 2) {
  $gradeTable.='<th>'.&mt('No.').'</th><th>'.&mt('Select').'</th>'.   $gradeTable.='<th>'.&mt('No.').'</th><th>'.&mt('Select').'</th>'.
     '<th>'.&nameUserString('header').'&nbsp;'.&mt('Section/Group').'</th>';      '<th>'.&nameUserString('header').'&nbsp;'.&mt('Section/Group').'</th>';
  if ($env{'form.showgrading'} eq 'yes'    if (($submitonly ne 'queued') && ($submitonly ne 'all')) {
     && $submitonly ne 'queued'  
     && $submitonly ne 'all') {  
     foreach my $part (sort(@$partlist)) {      foreach my $part (sort(@$partlist)) {
  my $display_part=   my $display_part=
     &get_display_part((split(/_/,$part))[0],$symb);      &get_display_part((split(/_/,$part))[0],$symb);
Line 1093  LISTJAVASCRIPT Line 1262  LISTJAVASCRIPT
     $status{'gradingqueue'} = $queue_status{'gradingqueue'};      $status{'gradingqueue'} = $queue_status{'gradingqueue'};
  }   }
   
  if ($env{'form.showgrading'} eq 'yes'    if (($submitonly ne 'queued') && ($submitonly ne 'all')) {
     && $submitonly ne 'queued'  
     && $submitonly ne 'all') {  
     (%status) =&student_gradeStatus($symb,$udom,$uname,$partlist);      (%status) =&student_gradeStatus($symb,$udom,$uname,$partlist);
     my $submitted = 0;      my $submitted = 0;
     my $graded = 0;      my $graded = 0;
Line 1136  LISTJAVASCRIPT Line 1303  LISTJAVASCRIPT
        &nameUserString(undef,$$fullname{$student},$uname,$udom).         &nameUserString(undef,$$fullname{$student},$uname,$udom).
        '&nbsp;'.$section.($group ne '' ?'/'.$group:'').'</td>'."\n";         '&nbsp;'.$section.($group ne '' ?'/'.$group:'').'</td>'."\n";
   
     if ($env{'form.showgrading'} eq 'yes' && $submitonly ne 'all') {      if ($submitonly ne 'all') {
  foreach (sort(keys(%status))) {   foreach (sort(keys(%status))) {
     next if ($_ =~ /^resource.*?submitted_by$/);      next if ($_ =~ /^resource.*?submitted_by$/);
     $gradeTable.='<td align="center">&nbsp;'.&mt($status{$_}).'&nbsp;</td>'."\n";      $gradeTable.='<td align="center">&nbsp;'.&mt($status{$_}).'&nbsp;</td>'."\n";
Line 1150  LISTJAVASCRIPT Line 1317  LISTJAVASCRIPT
     }      }
     if ($ctr%2 ==1) {      if ($ctr%2 ==1) {
  $gradeTable.='<td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>';   $gradeTable.='<td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>';
     if ($env{'form.showgrading'} eq 'yes'       if (($submitonly ne 'queued') && ($submitonly ne 'all')) {
  && $submitonly ne 'queued'  
  && $submitonly ne 'all') {  
  foreach (@$partlist) {   foreach (@$partlist) {
     $gradeTable.='<td>&nbsp;</td>';      $gradeTable.='<td>&nbsp;</td>';
  }   }
Line 1183  LISTJAVASCRIPT Line 1348  LISTJAVASCRIPT
     } elsif ($ctr == 1) {      } elsif ($ctr == 1) {
  $gradeTable =~ s/type="checkbox"/type="checkbox" checked="checked"/;   $gradeTable =~ s/type="checkbox"/type="checkbox" checked="checked"/;
     }      }
     $gradeTable.=&show_grading_menu_form($symb);  
     $request->print($gradeTable);      $request->print($gradeTable);
     return '';      return '';
 }  }
Line 1191  LISTJAVASCRIPT Line 1355  LISTJAVASCRIPT
 #---- Called from the listStudents routine  #---- Called from the listStudents routine
   
 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 1223  sub check_script { Line 1387  sub check_script {
         }          }
     }      }
   
 </script>'."\n";  '."\n");
     return $chkallscript;      return $chkallscript;
 }  }
   
Line 1237  sub check_buttons { Line 1401  sub check_buttons {
   
 #     Displays the submissions for one student or a group of students  #     Displays the submissions for one student or a group of students
 sub processGroup {  sub processGroup {
     my ($request)  = shift;      my ($request,$symb) = @_;
     my $ctr        = 0;      my $ctr        = 0;
     my @stuchecked = &Apache::loncommon::get_env_multiple('form.stuinfo');      my @stuchecked = &Apache::loncommon::get_env_multiple('form.stuinfo');
     my $total      = scalar(@stuchecked)-1;      my $total      = scalar(@stuchecked)-1;
Line 1247  sub processGroup { Line 1411  sub processGroup {
  $env{'form.student'}        = $uname;   $env{'form.student'}        = $uname;
  $env{'form.userdom'}        = $udom;   $env{'form.userdom'}        = $udom;
  $env{'form.fullname'}       = $fullname;   $env{'form.fullname'}       = $fullname;
  &submission($request,$ctr,$total);   &submission($request,$ctr,$total,$symb);
  $ctr++;   $ctr++;
     }      }
     return '';      return '';
Line 1263  sub sub_page_js { Line 1427  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 = ');
     &js_escape(\$alertmsg);      &js_escape(\$alertmsg);
     $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 1384  sub sub_page_js { Line 1547  sub sub_page_js {
  }   }
     }      }
  }   }
  if (val == "Grade Student") {  
     formname.showgrading.value = "yes";  
     if (formname.Status.value == "") {  
  formname.Status.value = "Active";  
     }  
     formname.studentNo.value = total;  
  }  
  formname.submit();   formname.submit();
     }      }
   
Line 1430  sub sub_page_js { Line 1586  sub sub_page_js {
   
  formname.submit();   formname.submit();
     }      }
 </script>  
 SUBJAVASCRIPT  SUBJAVASCRIPT
 }  }
   
 #--- javascript for essay type problem --  #--- javascript for grading message center
 sub sub_page_kw_js {  sub sub_grademessage_js {
     my $request = shift;      my $request = shift;
     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= (<<INNERJS);
     <script text="text/javascript">  <script type="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 1478  sub sub_page_kw_js { Line 1633  sub sub_page_kw_js {
       self.close()        self.close()
   
     }      }
     </script>  
 INNERJS  
   
     my $inner_js_highlight_central=<<INNERJS;  
  <script type="text/javascript">  
     function updateChoice(flag) {  
       opener.document.SCORE.kwclr.value = opener.radioSelection(document.hlCenter.kwdclr);  
       opener.document.SCORE.kwsize.value = opener.radioSelection(document.hlCenter.kwdsize);  
       opener.document.SCORE.kwstyle.value = opener.radioSelection(document.hlCenter.kwdstyle);  
       opener.document.SCORE.refresh.value = "on";  
       if (opener.document.SCORE.keywords.value!=""){  
          opener.document.SCORE.submit();  
       }  
       self.close()  
     }  
 </script>  </script>
 INNERJS  INNERJS
   
     my $start_page_msg_central =       my $start_page_msg_central =
         &Apache::loncommon::start_page('Message Central',$inner_js_msg_central,          &Apache::loncommon::start_page('Message Central',$inner_js_msg_central,
        {'js_ready'  => 1,         {'js_ready'  => 1,
  'only_body' => 1,   'only_body' => 1,
  'bgcolor'   =>'#FFFFFF',});   'bgcolor'   =>'#FFFFFF',});
     my $end_page_msg_central =       my $end_page_msg_central =
  &Apache::loncommon::end_page({'js_ready' => 1});   &Apache::loncommon::end_page({'js_ready' => 1});
   
   
     my $start_page_highlight_central =   
         &Apache::loncommon::start_page('Highlight Central',  
        $inner_js_highlight_central,  
        {'js_ready'  => 1,  
  'only_body' => 1,  
  'bgcolor'   =>'#FFFFFF',});  
     my $end_page_highlight_central =   
  &Apache::loncommon::end_page({'js_ready' => 1});  
   
     my $docopen=&Apache::lonhtmlcommon::javascript_docopen();      my $docopen=&Apache::lonhtmlcommon::javascript_docopen();
     $docopen=~s/^document\.//;      $docopen=~s/^document\.//;
     my %js_lt = &Apache::lonlocal::texthash(  
                 keyw => 'Keywords list, separated by a space. Add/delete to list if desired.',  
                 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.',  
                 col1 => 'red',  
                 col2 => 'green',  
                 col3 => 'blue',  
                 siz1 => 'normal',  
                 siz2 => '+1',  
                 siz3 => '+2',  
                 sty1 => 'normal',  
                 sty2 => 'italic',  
                 sty3 => 'bold',  
              );  
     my %html_js_lt = &Apache::lonlocal::texthash(      my %html_js_lt = &Apache::lonlocal::texthash(
                 comp => 'Compose Message for: ',                  comp => 'Compose Message for: ',
                 incl => 'Include',                  incl => 'Include',
Line 1539  INNERJS Line 1657  INNERJS
                 new  => 'New',                  new  => 'New',
                 save => 'Save',                  save => 'Save',
                 canc => 'Cancel',                  canc => 'Cancel',
                 kehi => 'Keyword Highlight Options',  
                 txtc => 'Text Color',  
                 font => 'Font Size',  
                 fnst => 'Font Style',  
              );               );
     &js_escape(\%js_lt);  
     &html_escape(\%html_js_lt);      &html_escape(\%html_js_lt);
     &js_escape(\%html_js_lt);      &js_escape(\%html_js_lt);
     $request->print(<<SUBJAVASCRIPT);      $request->print(&Apache::lonhtmlcommon::scripttag(<<SUBJAVASCRIPT));
 <script type="text/javascript" language="javascript">  
   
 //===================== Show list of keywords ====================  
   function keywords(formname) {  
     var nret = prompt("$js_lt{'keyw'}",formname.keywords.value);  
     if (nret==null) return;  
     formname.keywords.value = nret;  
   
     if (formname.keywords.value != "") {  
  formname.refresh.value = "on";  
  formname.submit();  
     }  
     return;  
   }  
   
 //===================== Script to view submitted by ==================  //===================== Script to view submitted by ==================
   function viewSubmitter(submitter) {    function viewSubmitter(submitter) {
Line 1572  INNERJS Line 1671  INNERJS
     return;      return;
   }    }
   
 //===================== Script to add keyword(s) ==================  
   function getSel() {  
     if (document.getSelection) txt = document.getSelection();  
     else if (document.selection) txt = document.selection.createRange().text;  
     else return;  
     var cleantxt = txt.replace(new RegExp('([\\f\\n\\r\\t\\v ])+', 'g')," ");  
     if (cleantxt=="") {  
  alert("$js_lt{'plse'}");  
  return;  
     }  
     var nret = prompt("$js_lt{'adds'}",cleantxt);  
     if (nret==null) return;  
     document.SCORE.keywords.value = document.SCORE.keywords.value+" "+nret;  
     if (document.SCORE.keywords.value != "") {  
  document.SCORE.refresh.value = "on";  
  document.SCORE.submit();  
     }  
     return;  
   }  
   
 //====================== Script for composing message ==============  //====================== Script for composing message ==============
    // preload images     // preload images
    img1 = new Image();     img1 = new Image();
Line 1662  INNERJS Line 1741  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;$html_js_lt{'comp'}\"+fullname+\"<\\/span><\\/h3><br /><br />");      pDoc.write("<h1>&nbsp;$html_js_lt{'comp'}\"+fullname+\"<\\/h1>");
   
     pDoc.write('<table border="0" width="100%"><tr><td bgcolor="#777777">');      pDoc.write('<table style="border:1px solid black;"><tr>');
     pDoc.write('<table border="0" width="100%"><tr bgcolor="#DDFFFF">');      pDoc.write("<td><b>$html_js_lt{'incl'}<\\/b><\\/td><td><b>$html_js_lt{'type'}<\\/b><\\/td><td><b>$html_js_lt{'mesa'}<\\/td><\\/tr>");
     pDoc.write("<td><b>$html_js_lt{'type'}<\\/b><\\/td><td><b>$html_js_lt{'incl'}<\\/b><\\/td><td><b>$html_js_lt{'mesa'}<\\/td><\\/tr>");  
 }  }
     function displaySubject(msg,shwsel) {      function displaySubject(msg,shwsel) {
     pDoc = pWin.document;      pDoc = pWin.document;
     pDoc.write("<tr bgcolor=\\"#ffffdd\\">");      pDoc.write("<tr>");
     pDoc.write("<td>$html_js_lt{'subj'}<\\/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>$html_js_lt{'subj'}<\\/td>");
       pDoc.write("<td><input name=\\"msgsub\\" type=\\"text\\" value=\\""+msg+"\\"size=\\"40\\" maxlength=\\"80\\"><\\/td><\\/tr>");
 }  }
   
   function displaySavedMsg(ctr,msg,shwsel) {    function displaySavedMsg(ctr,msg,shwsel) {
     pDoc = pWin.document;      pDoc = pWin.document;
     pDoc.write("<tr bgcolor=\\"#ffffdd\\">");      pDoc.write("<tr>");
     pDoc.write("<td align=\\"center\\">"+ctr+"<\\/td>");  
     pDoc.write("<td align=\\"center\\"><input name=\\"msgn"+ctr+"\\" type=\\"checkbox\\"" +shwsel+"><\\/td>");      pDoc.write("<td align=\\"center\\"><input name=\\"msgn"+ctr+"\\" type=\\"checkbox\\"" +shwsel+"><\\/td>");
       pDoc.write("<td align=\\"center\\">"+ctr+"<\\/td>");
     pDoc.write("<td><textarea name=\\"msg"+ctr+"\\" cols=\\"60\\" rows=\\"3\\">"+msg+"<\\/textarea><\\/td><\\/tr>");      pDoc.write("<td><textarea name=\\"msg"+ctr+"\\" cols=\\"60\\" rows=\\"3\\">"+msg+"<\\/textarea><\\/td><\\/tr>");
 }  }
   
   function newMsg(newmsg,shwsel) {    function newMsg(newmsg,shwsel) {
     pDoc = pWin.document;      pDoc = pWin.document;
     pDoc.write("<tr bgcolor=\\"#ffffdd\\">");      pDoc.write("<tr>");
     pDoc.write("<td align=\\"center\\">$html_js_lt{'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 align=\\"center\\">$html_js_lt{'new'}<\\/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>");
 }  }
   
   function msgTail() {    function msgTail() {
     pDoc = pWin.document;      pDoc = pWin.document;
     pDoc.write("<\\/table>");  
     pDoc.write("<\\/td><\\/tr><\\/table>&nbsp;");      pDoc.write("<\\/td><\\/tr><\\/table>&nbsp;");
     pDoc.write("<input type=\\"button\\" value=\\"$html_js_lt{'save'}\\" onclick=\\"javascript:checkInput()\\">&nbsp;&nbsp;");      pDoc.write("<input type=\\"button\\" value=\\"$html_js_lt{'save'}\\" onclick=\\"javascript:checkInput()\\">&nbsp;&nbsp;");
     pDoc.write("<input type=\\"button\\" value=\\"$html_js_lt{'canc'}\\" onclick=\\"self.close()\\"><br /><br />");      pDoc.write("<input type=\\"button\\" value=\\"$html_js_lt{'canc'}\\" onclick=\\"self.close()\\"><br /><br />");
Line 1703  INNERJS Line 1780  INNERJS
     pDoc.close();      pDoc.close();
 }  }
   
   SUBJAVASCRIPT
   }
   
   #--- javascript for essay type problem --
   sub sub_page_kw_js {
       my $request = shift;
   
       unless ($env{'form.compmsg'}) {
           &commonJSfunctions($request);
       }
   
       my $inner_js_highlight_central= (<<INNERJS);
   <script type="text/javascript">
       function updateChoice(flag) {
         opener.document.SCORE.kwclr.value = opener.radioSelection(document.hlCenter.kwdclr);
         opener.document.SCORE.kwsize.value = opener.radioSelection(document.hlCenter.kwdsize);
         opener.document.SCORE.kwstyle.value = opener.radioSelection(document.hlCenter.kwdstyle);
         opener.document.SCORE.refresh.value = "on";
         if (opener.document.SCORE.keywords.value!=""){
            opener.document.SCORE.submit();
         }
         self.close()
       }
   </script>
   INNERJS
   
       my $start_page_highlight_central =
           &Apache::loncommon::start_page('Highlight Central',
                                          $inner_js_highlight_central,
                                          {'js_ready'  => 1,
                                           'only_body' => 1,
                                           'bgcolor'   =>'#FFFFFF',});
       my $end_page_highlight_central =
           &Apache::loncommon::end_page({'js_ready' => 1});
   
       my $docopen=&Apache::lonhtmlcommon::javascript_docopen();
       $docopen=~s/^document\.//;
   
       my %js_lt = &Apache::lonlocal::texthash(
                   keyw => 'Keywords list, separated by a space. Add/delete to list if desired.',
                   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.',
                   col1 => 'red',
                   col2 => 'green',
                   col3 => 'blue',
                   siz1 => 'normal',
                   siz2 => '+1',
                   siz3 => '+2',
                   sty1 => 'normal',
                   sty2 => 'italic',
                   sty3 => 'bold',
                );
       my %html_js_lt = &Apache::lonlocal::texthash(
                   save => 'Save',
                   canc => 'Cancel',
                   kehi => 'Keyword Highlight Options',
                   txtc => 'Text Color',
                   font => 'Font Size',
                   fnst => 'Font Style',
                );
       &js_escape(\%js_lt);
       &html_escape(\%html_js_lt);
       &js_escape(\%html_js_lt);
       $request->print(&Apache::lonhtmlcommon::scripttag(<<SUBJAVASCRIPT));
   
   //===================== Show list of keywords ====================
     function keywords(formname) {
       var nret = prompt("$js_lt{'keyw'}",formname.keywords.value);
       if (nret==null) return;
       formname.keywords.value = nret;
   
       if (formname.keywords.value != "") {
           formname.refresh.value = "on";
           formname.submit();
       }
       return;
     }
   
   //===================== Script to add keyword(s) ==================
     function getSel() {
       if (document.getSelection) txt = document.getSelection();
       else if (document.selection) txt = document.selection.createRange().text;
       else return;
       if (typeof(txt) != 'string') {
           txt = String(txt);
       }
       var cleantxt = txt.replace(new RegExp('([\\f\\n\\r\\t\\v ])+', 'g')," ");
       if (cleantxt=="") {
           alert("$js_lt{'plse'}");
           return;
       }
       var nret = prompt("$js_lt{'adds'}",cleantxt);
       if (nret==null) return;
       document.SCORE.keywords.value = document.SCORE.keywords.value+" "+nret;
       if (document.SCORE.keywords.value != "") {
           document.SCORE.refresh.value = "on";
           document.SCORE.submit();
       }
       return;
     }
   
 //====================== Script for keyword highlight options ==============  //====================== Script for keyword highlight options ==============
   function kwhighlight() {    function kwhighlight() {
     var kwclr    = document.SCORE.kwclr.value;      var kwclr    = document.SCORE.kwclr.value;
Line 1784  INNERJS Line 1962  INNERJS
     hDoc.close();      hDoc.close();
   }    }
   
 </script>  
 SUBJAVASCRIPT  SUBJAVASCRIPT
 }  }
   
Line 1873  sub gradeBox { Line 2050  sub gradeBox {
   
     $result .=       $result .= 
     '<td>'.$data_WGT.$display_part.'</td><td>'.$radio.'</td><td>'.&mt('or').'</td><td>'.$line.'</td>';      '<td>'.$data_WGT.$display_part.'</td><td>'.$radio.'</td><td>'.&mt('or').'</td><td>'.$line.'</td>';
     $result.=&Apache::loncommon::end_data_table_row().'<td colspan="6">';      $result.=&Apache::loncommon::end_data_table_row();
       $result.=&Apache::loncommon::start_data_table_row().'<td colspan="6">';
     $result.='<input type="hidden" name="stores'.$counter.'_'.$partid.'" value="" />'."\n".      $result.='<input type="hidden" name="stores'.$counter.'_'.$partid.'" value="" />'."\n".
  '<input type="hidden" name="oldpts'.$counter.'_'.$partid.'" value="'.$score.'" />'."\n".   '<input type="hidden" name="oldpts'.$counter.'_'.$partid.'" value="'.$score.'" />'."\n".
  '<input type="hidden" name="solved'.$counter.'_'.$partid.'" value="'.   '<input type="hidden" name="solved'.$counter.'_'.$partid.'" value="'.
Line 1892  sub gradeBox { Line 2070  sub gradeBox {
 }  }
   
 sub handback_box {  sub handback_box {
     my ($symb,$uname,$udom,$counter,$partid,$record,$res_error) = @_;      my ($symb,$uname,$udom,$counter,$partid,$record,$res_error_pointer) = @_;
     my ($partlist,$handgrade,$responseType) = &response_type($symb,$res_error);      my ($partlist,$handgrade,$responseType,$numresp,$numessay) = &response_type($symb,$res_error_pointer);
       return unless ($numessay);
     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) {
Line 1995  sub show_problem { Line 2174  sub show_problem {
 sub files_exist {  sub files_exist {
     my ($r, $symb) = @_;      my ($r, $symb) = @_;
     my @students = &Apache::loncommon::get_env_multiple('form.stuinfo');      my @students = &Apache::loncommon::get_env_multiple('form.stuinfo');
   
     foreach my $student (@students) {      foreach my $student (@students) {
         my ($uname,$udom,$fullname) = split(/:/,$student);          my ($uname,$udom,$fullname) = split(/:/,$student);
         my %record = &Apache::lonnet::restore($symb,$env{'request.course.id'},          my %record = &Apache::lonnet::restore($symb,$env{'request.course.id'},
Line 2014  sub files_exist { Line 2192  sub files_exist {
   
 sub download_all_link {  sub download_all_link {
     my ($r,$symb) = @_;      my ($r,$symb) = @_;
       unless (&files_exist($r, $symb)) {
           $r->print(&mt('There are currently no submitted documents.'));
           return;
       }
     my $all_students =       my $all_students = 
  join("\n", &Apache::loncommon::get_env_multiple('form.stuinfo'));   join("\n", &Apache::loncommon::get_env_multiple('form.stuinfo'));
   
Line 2026  sub download_all_link { Line 2208  sub download_all_link {
                              'cgi.'.$identifier.'.parts' => $parts,});                               'cgi.'.$identifier.'.parts' => $parts,});
     $r->print('<a href="/cgi-bin/multidownload.pl?'.$identifier.'">'.      $r->print('<a href="/cgi-bin/multidownload.pl?'.$identifier.'">'.
       &mt('Download All Submitted Documents').'</a>');        &mt('Download All Submitted Documents').'</a>');
     return      return;
   }
   
   sub submit_download_link {
       my ($request,$symb) = @_;
       if (!$symb) { return ''; }
       my $res_error;
       my ($partlist,$handgrade,$responseType,$numresp,$numessay,$numdropbox) =
           &response_type($symb,\$res_error);
       if ($res_error) {
           $request->print(&mt('An error occurred retrieving response types'));
           return;
       }
       unless ($numessay) {
           $request->print(&mt('No essayresponse items found'));
           return;
       }
       my @chosenparts = &Apache::loncommon::get_env_multiple('form.vPart');
       if (@chosenparts) {
           $request->print(&showResourceInfo($symb,$partlist,$responseType,
                                             undef,undef,1));
       }
       if ($numessay) {
           my $submitonly= $env{'form.submitonly'} eq '' ? 'all' : $env{'form.submitonly'};
           my $getsec    = $env{'form.section'} eq '' ? 'all' : $env{'form.section'};
           my $getgroup  = $env{'form.group'} eq '' ? 'all' : $env{'form.group'};
           (undef,undef,my $fullname) = &getclasslist($getsec,1,$getgroup,$symb,$submitonly,1);
           if (ref($fullname) eq 'HASH') {
               my @students = map { $_.':'.$fullname->{$_} } (keys(%{$fullname}));
               if (@students) {
                   @{$env{'form.stuinfo'}} = @students;
                   if ($numdropbox) {
                       &download_all_link($request,$symb);
                   } else {
                       $request->print(&mt('No essayrespose items with dropbox found'));
                   }
   # FIXME Need a mechanism to download essays, i.e., if $numessay > $numdropbox
   # Needs to omit user's identity if resource instance is for an anonymous survey.
               } else {
                   $request->print(&mt('No students match the criteria you selected'));
               }
           } else {
               $request->print(&mt('Could not retrieve student information'));
           }
       } else {
           $request->print(&mt('No essayresponse items found'));
       }
       return;
 }  }
   
 sub build_section_inputs {  sub build_section_inputs {
Line 2044  sub build_section_inputs { Line 2273  sub build_section_inputs {
   
 # --------------------------- show submissions of a student, option to grade   # --------------------------- show submissions of a student, option to grade 
 sub submission {  sub submission {
     my ($request,$counter,$total) = @_;      my ($request,$counter,$total,$symb,$divforres,$calledby) = @_;
     my ($uname,$udom)     = ($env{'form.student'},$env{'form.userdom'});      my ($uname,$udom)     = ($env{'form.student'},$env{'form.userdom'});
     $udom = ($udom eq '' ? $env{'user.domain'} : $udom); #has form.userdom changed for a student?      $udom = ($udom eq '' ? $env{'user.domain'} : $udom); #has form.userdom changed for a student?
     my $usec = &Apache::lonnet::getsection($udom,$uname,$env{'request.course.id'});      my $usec = &Apache::lonnet::getsection($udom,$uname,$env{'request.course.id'});
     $env{'form.fullname'} = &Apache::loncommon::plainname($uname,$udom,'lastname') if $env{'form.fullname'} eq '';      $env{'form.fullname'} = &Apache::loncommon::plainname($uname,$udom,'lastname') if $env{'form.fullname'} eq '';
     my ($symb) = &get_symb($request);   
     if ($symb eq '') { $request->print("Unable to handle ambiguous references:."); return ''; }      if ($symb eq '') { $request->print("Unable to handle ambiguous references:."); return ''; }
       my $probtitle=&Apache::lonnet::gettitle($symb);
       my ($essayurl,%coursedesc_by_cid);
   
     if (!&canview($usec)) {      if (!&canview($usec)) {
         $request->print(          $request->print(
Line 2059  sub submission { Line 2290  sub submission {
             ' '.&mt('([_1] in section [_2] in course id [_3])',              ' '.&mt('([_1] in section [_2] in course id [_3])',
                         $uname.':'.$udom,$usec,$env{'request.course.id'}).                          $uname.':'.$udom,$usec,$env{'request.course.id'}).
             '</span>');              '</span>');
  $request->print(&show_grading_menu_form($symb));  
  return;   return;
     }      }
   
       my $res_error;
       my ($partlist,$handgrade,$responseType,$numresp,$numessay) =
           &response_type($symb,\$res_error);
       if ($res_error) {
           $request->print(&navmap_errormsg());
           return;
       }
   
     if (!$env{'form.lastSub'}) { $env{'form.lastSub'} = 'datesub'; }      if (!$env{'form.lastSub'}) { $env{'form.lastSub'} = 'datesub'; }
     if (!$env{'form.vProb'}) { $env{'form.vProb'} = 'yes'; }      if (!$env{'form.vProb'}) { $env{'form.vProb'} = 'yes'; }
     if (!$env{'form.vAns'}) { $env{'form.vAns'} = 'yes'; }      if (!$env{'form.vAns'}) { $env{'form.vAns'} = 'yes'; }
       if (($numessay) && ($calledby eq 'submission') && (!exists($env{'form.compmsg'}))) {
           $env{'form.compmsg'} = 1;
       }
     my $last = ($env{'form.lastSub'} eq 'last' ? 'last' : '');      my $last = ($env{'form.lastSub'} eq 'last' ? 'last' : '');
     my $checkIcon = '<img alt="'.&mt('Check Mark').      my $checkIcon = '<img alt="'.&mt('Check Mark').
  '" src="'.$request->dir_config('lonIconsURL').   '" src="'.$request->dir_config('lonIconsURL').
Line 2073  sub submission { Line 2314  sub submission {
   
     # header info      # header info
     if ($counter == 0) {      if ($counter == 0) {
           my @chosenparts = &Apache::loncommon::get_env_multiple('form.vPart');
           if (@chosenparts) {
               $request->print(&showResourceInfo($symb,$partlist,$responseType,'gradesub'));
           } elsif ($divforres) {
               $request->print('<div style="padding:0;clear:both;margin:0;border:0"></div>');
           } else {
               $request->print('<br clear="all" />');
           }
  &sub_page_js($request);   &sub_page_js($request);
  &sub_page_kw_js($request) if ($env{'form.handgrade'} eq 'yes');          &sub_grademessage_js($request) if ($env{'form.compmsg'});
  $env{'form.probTitle'} = $env{'form.probTitle'} eq '' ?    &sub_page_kw_js($request) if ($numessay);
     &Apache::lonnet::gettitle($symb) : $env{'form.probTitle'};  
  if ($env{'form.handgrade'} eq 'yes' && &files_exist($request, $symb)) {  
     &download_all_link($request, $symb);  
  }  
  $request->print('<h3>&nbsp;<span class="LC_info">'.&mt('Submission Record').'</span></h3>'."\n".  
  '<h4>&nbsp;'.&mt('[_1]Resource: [_2]','<b>','</b>'.$env{'form.probTitle'}).'</h4>'."\n");  
   
  # option to display problem, only once else it cause problems    # option to display problem, only once else it cause problems 
         # with the form later since the problem has a form.          # with the form later since the problem has a form.
Line 2098  sub submission { Line 2341  sub submission {
     $request->print(&show_problem($request,$symb,$uname,$udom,0,1,$mode));      $request->print(&show_problem($request,$symb,$uname,$udom,0,1,$mode));
  }   }
   
  # kwclr is the only variable that is guaranteed not to be blank   
         # if this subroutine has been called once.  
  my %keyhash = ();   my %keyhash = ();
  if ($env{'form.kwclr'} eq '' && $env{'form.handgrade'} eq 'yes') {   if (($env{'form.kwclr'} eq '' && $numessay) || ($env{'form.compmsg'})) {
     %keyhash = &Apache::lonnet::dump('nohist_handgrade',      %keyhash = &Apache::lonnet::dump('nohist_handgrade',
      $env{'course.'.$env{'request.course.id'}.'.domain'},       $env{'course.'.$env{'request.course.id'}.'.domain'},
      $env{'course.'.$env{'request.course.id'}.'.num'});       $env{'course.'.$env{'request.course.id'}.'.num'});
    }
    # kwclr is the only variable that is guaranteed not to be blank
    # if this subroutine has been called once.
    if ($env{'form.kwclr'} eq '' && $numessay) {
     my $loginuser = $env{'user.name'}.':'.$env{'user.domain'};      my $loginuser = $env{'user.name'}.':'.$env{'user.domain'};
     $env{'form.keywords'} = $keyhash{$symb.'_keywords'} ne '' ? $keyhash{$symb.'_keywords'} : '';      $env{'form.keywords'} = $keyhash{$symb.'_keywords'} ne '' ? $keyhash{$symb.'_keywords'} : '';
     $env{'form.kwclr'}    = $keyhash{$loginuser.'_kwclr'} ne '' ? $keyhash{$loginuser.'_kwclr'} : 'red';      $env{'form.kwclr'}    = $keyhash{$loginuser.'_kwclr'} ne '' ? $keyhash{$loginuser.'_kwclr'} : 'red';
     $env{'form.kwsize'}   = $keyhash{$loginuser.'_kwsize'} ne '' ? $keyhash{$loginuser.'_kwsize'} : '0';      $env{'form.kwsize'}   = $keyhash{$loginuser.'_kwsize'} ne '' ? $keyhash{$loginuser.'_kwsize'} : '0';
     $env{'form.kwstyle'}  = $keyhash{$loginuser.'_kwstyle'} ne '' ? $keyhash{$loginuser.'_kwstyle'} : '';      $env{'form.kwstyle'}  = $keyhash{$loginuser.'_kwstyle'} ne '' ? $keyhash{$loginuser.'_kwstyle'} : '';
     $env{'form.msgsub'}   = $keyhash{$symb.'_subject'} ne '' ?    }
  $keyhash{$symb.'_subject'} : $env{'form.probTitle'};   if ($env{'form.compmsg'}) {
       $env{'form.msgsub'}   = $keyhash{$symb.'_subject'} ne '' ?
    $keyhash{$symb.'_subject'} : $probtitle;
     $env{'form.savemsgN'} = $keyhash{$symb.'_savemsgN'} ne '' ? $keyhash{$symb.'_savemsgN'} : '0';      $env{'form.savemsgN'} = $keyhash{$symb.'_savemsgN'} ne '' ? $keyhash{$symb.'_savemsgN'} : '0';
  }   }
   
  my $overRideScore = $env{'form.overRideScore'} eq '' ? 'no' : $env{'form.overRideScore'};   my $overRideScore = $env{'form.overRideScore'} eq '' ? 'no' : $env{'form.overRideScore'};
  my $stu_status = join(':',&Apache::loncommon::get_env_multiple('form.Status'));   my $stu_status = join(':',&Apache::loncommon::get_env_multiple('form.Status'));
  $request->print('<form action="/adm/grades" method="post" name="SCORE" enctype="multipart/form-data">'."\n".   $request->print('<form action="/adm/grades" method="post" name="SCORE" enctype="multipart/form-data">'."\n".
  '<input type="hidden" name="command"    value="handgrade" />'."\n".   '<input type="hidden" name="command"    value="handgrade" />'."\n".
  '<input type="hidden" name="saveState"  value="'.$env{'form.saveState'}.'" />'."\n".  
  '<input type="hidden" name="Status"     value="'.$stu_status.'" />'."\n".   '<input type="hidden" name="Status"     value="'.$stu_status.'" />'."\n".
  '<input type="hidden" name="overRideScore" value="'.$overRideScore.'" />'."\n".   '<input type="hidden" name="overRideScore" value="'.$overRideScore.'" />'."\n".
  '<input type="hidden" name="probTitle"  value="'.$env{'form.probTitle'}.'" />'."\n".  
  '<input type="hidden" name="refresh"    value="off" />'."\n".   '<input type="hidden" name="refresh"    value="off" />'."\n".
  '<input type="hidden" name="studentNo"  value="" />'."\n".   '<input type="hidden" name="studentNo"  value="" />'."\n".
  '<input type="hidden" name="gradeOpt"   value="" />'."\n".   '<input type="hidden" name="gradeOpt"   value="" />'."\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="showgrading" value="'.$env{'form.showgrading'}.'" />'."\n".  
  '<input type="hidden" name="vProb"      value="'.$env{'form.vProb'}.'" />'."\n".   '<input type="hidden" name="vProb"      value="'.$env{'form.vProb'}.'" />'."\n".
  '<input type="hidden" name="vAns"       value="'.$env{'form.vAns'}.'" />'."\n".   '<input type="hidden" name="vAns"       value="'.$env{'form.vAns'}.'" />'."\n".
  '<input type="hidden" name="lastSub"    value="'.$env{'form.lastSub'}.'" />'."\n".   '<input type="hidden" name="lastSub"    value="'.$env{'form.lastSub'}.'" />'."\n".
    '<input type="hidden" name="compmsg"    value="'.$env{'form.compmsg'}.'" />'."\n".
  &build_section_inputs().   &build_section_inputs().
  '<input type="hidden" name="submitonly" value="'.$env{'form.submitonly'}.'" />'."\n".   '<input type="hidden" name="submitonly" value="'.$env{'form.submitonly'}.'" />'."\n".
  '<input type="hidden" name="handgrade"  value="'.$env{'form.handgrade'}.'" />'."\n".  
  '<input type="hidden" name="NCT"'.   '<input type="hidden" name="NCT"'.
  ' value="'.($env{'form.NTSTU'} ne '' ? $env{'form.NTSTU'} : $total+1).'" />'."\n");   ' value="'.($env{'form.NTSTU'} ne '' ? $env{'form.NTSTU'} : $total+1).'" />'."\n");
  if ($env{'form.handgrade'} eq 'yes') {   if ($env{'form.compmsg'}) {
       $request->print('<input type="hidden" name="msgsub"   value="'.$env{'form.msgsub'}.'" />'."\n".
       '<input type="hidden" name="shownSub" value="0" />'."\n".
       '<input type="hidden" name="savemsgN" value="'.$env{'form.savemsgN'}.'" />'."\n");
    }
    if ($numessay) {
     $request->print('<input type="hidden" name="keywords" value="'.$env{'form.keywords'}.'" />'."\n".      $request->print('<input type="hidden" name="keywords" value="'.$env{'form.keywords'}.'" />'."\n".
     '<input type="hidden" name="kwclr"    value="'.$env{'form.kwclr'}.'" />'."\n".      '<input type="hidden" name="kwclr"    value="'.$env{'form.kwclr'}.'" />'."\n".
     '<input type="hidden" name="kwsize"   value="'.$env{'form.kwsize'}.'" />'."\n".      '<input type="hidden" name="kwsize"   value="'.$env{'form.kwsize'}.'" />'."\n".
     '<input type="hidden" name="kwstyle"  value="'.$env{'form.kwstyle'}.'" />'."\n".      '<input type="hidden" name="kwstyle"  value="'.$env{'form.kwstyle'}.'" />'."\n");
     '<input type="hidden" name="msgsub"   value="'.$env{'form.msgsub'}.'" />'."\n".  
     '<input type="hidden" name="shownSub" value="0" />'."\n".  
     '<input type="hidden" name="savemsgN" value="'.$env{'form.savemsgN'}.'" />'."\n");  
     foreach my $partid (&Apache::loncommon::get_env_multiple('form.vPart')) {  
  $request->print('<input type="hidden" name="vPart" value="'.$partid.'" />'."\n");  
     }  
  }   }
   
  my ($cts,$prnmsg) = (1,'');   my ($cts,$prnmsg) = (1,'');
  while ($cts <= $env{'form.savemsgN'}) {   while ($cts <= $env{'form.savemsgN'}) {
     $prnmsg.='<input type="hidden" name="savemsg'.$cts.'" value="'.      $prnmsg.='<input type="hidden" name="savemsg'.$cts.'" value="'.
Line 2161  sub submission { Line 2404  sub submission {
  }   }
  $request->print($prnmsg);   $request->print($prnmsg);
   
  if ($env{'form.handgrade'} eq 'yes' && $env{'form.showgrading'} eq 'yes') {   if ($numessay) {
   
             my %lt = &Apache::lonlocal::texthash(              my %lt = &Apache::lonlocal::texthash(
                           keyh => 'Keyword Highlighting for Essays',                            keyh => 'Keyword Highlighting for Essays',
Line 2173  sub submission { Line 2416  sub submission {
 #  #
 # Print out the keyword options line  # Print out the keyword options line
 #  #
             $request->print(      $request->print(
                 '<div class="LC_columnSection">'                  '<div class="LC_columnSection">'
                .'<fieldset><legend>'.$lt{'keyh'}.'</legend>'                 .'<fieldset><legend>'.$lt{'keyh'}.'</legend>'
                .&Apache::lonhtmlcommon::funclist_from_array(                 .&Apache::lonhtmlcommon::funclist_from_array(
Line 2188  sub submission { Line 2431  sub submission {
 #  #
 # Load the other essays for similarity check  # Load the other essays for similarity check
 #  #
             my (undef,undef,$essayurl) = &Apache::lonnet::decode_symb($symb);              (undef,undef,$essayurl) = &Apache::lonnet::decode_symb($symb);
     my ($adom,$aname,$apath)=($essayurl=~/^($LONCAPA::domain_re)\/($LONCAPA::username_re)\/(.*)$/);              if ($essayurl eq 'lib/templates/simpleproblem.problem') {
     $apath=&escape($apath);                  my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
     $apath=~s/\W/\_/gs;                  my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
             &init_old_essays($symb,$apath,$adom,$aname);                  if ($cdom ne '' && $cnum ne '') {
                       my ($map,$id,$res) = &Apache::lonnet::decode_symb($symb);
                       if ($map =~ m{^\Quploaded/$cdom/$cnum/\E(default(?:|_\d+)\.(?:sequence|page))$}) {
                           my $apath = $1.'_'.$id;
                           $apath=~s/\W/\_/gs;
                           &init_old_essays($symb,$apath,$cdom,$cnum);
                       }
                   }
               } else {
           my ($adom,$aname,$apath)=($essayurl=~/^($LONCAPA::domain_re)\/($LONCAPA::username_re)\/(.*)$/);
           $apath=&escape($apath);
           $apath=~s/\W/\_/gs;
                   &init_old_essays($symb,$apath,$adom,$aname);
               }
         }          }
     }      }
   
Line 2236  sub submission { Line 2492  sub submission {
     }      }
   
     my %record = &Apache::lonnet::restore($symb,$env{'request.course.id'},$udom,$uname);      my %record = &Apache::lonnet::restore($symb,$env{'request.course.id'},$udom,$uname);
     my $res_error;  
     my ($partlist,$handgrade,$responseType) = &response_type($symb,\$res_error);  
     if ($res_error) {  
         $request->print(&navmap_errormsg());  
         return;  
     }  
   
     # Display student info      # Display student info
     $request->print(($counter == 0 ? '' : '<br />'));      $request->print(($counter == 0 ? '' : '<br />'));
Line 2250  sub submission { Line 2500  sub submission {
               .'<h3 class="LC_hcell">'.&mt('Submissions').'</h3>';                .'<h3 class="LC_hcell">'.&mt('Submissions').'</h3>';
     $result.='<input type="hidden" name="name'.$counter.      $result.='<input type="hidden" name="name'.$counter.
              '" value="'.$env{'form.fullname'}.'" />'."\n";               '" value="'.$env{'form.fullname'}.'" />'."\n";
     if ($env{'form.handgrade'} eq 'no') {      if ($numresp > $numessay) {
         $result.='<p class="LC_info">'          $result.='<p class="LC_info">'
                 .&mt('Part(s) graded correct by the computer is marked with a [_1] symbol.',$checkIcon)                  .&mt('Part(s) graded correct by the computer is marked with a [_1] symbol.',$checkIcon)
                 ."</p>\n";                  ."</p>\n";
     }      }
   
     # If any part of the problem is an essay-response (handgraded), then check for collaborators      # If any part of the problem is an essayresponse, then check for collaborators
     my $fullname;      my $fullname;
     my $col_fullnames = [];      my $col_fullnames = [];
     if ($env{'form.handgrade'} eq 'yes') {      if ($numessay) {
  (my $sub_result,$fullname,$col_fullnames)=   (my $sub_result,$fullname,$col_fullnames)=
     &check_collaborators($symb,$uname,$udom,\%record,$handgrade,      &check_collaborators($symb,$uname,$udom,\%record,$handgrade,
  $counter);   $counter);
Line 2268  sub submission { Line 2518  sub submission {
     $request->print($result."\n");      $request->print($result."\n");
   
     # print student answer/submission      # print student answer/submission
     # Options are (1) Handgraded submission only      # Options are (1) Last submission only
     #             (2) Last submission, includes submission that is not handgraded       #             (2) Last submission (with detailed information for that submission)
     #                  (for multi-response type part)      #             (3) All transactions (by date)
     #             (3) Last submission plus the parts info      #             (4) The whole record (with detailed information for all transactions)
     #             (4) The whole record for this student  
       my ($string,$timestamp)= &get_last_submission(\%record);
  my ($string,$timestamp)= &get_last_submission(\%record);  
       my $lastsubonly;
  my $lastsubonly;  
       if ($$timestamp eq '') {
         if ($$timestamp eq '') {          $lastsubonly.='<div class="LC_grade_submissions_body">'.$$string[0].'</div>'; 
             $lastsubonly.='<div class="LC_grade_submissions_body">'.$$string[0].'</div>';       } else {
         } else {          $lastsubonly =
             $lastsubonly =              '<div class="LC_grade_submissions_body">'
                 '<div class="LC_grade_submissions_body">'             .'<b>'.&mt('Date Submitted:').'</b> '.$$timestamp."\n";
                .'<b>'.&mt('Date Submitted:').'</b> '.$$timestamp."\n";  
    my %seenparts;
     my %seenparts;   my @part_response_id = &flatten_responseType($responseType);
     my @part_response_id = &flatten_responseType($responseType);   foreach my $part (@part_response_id) {
     foreach my $part (@part_response_id) {      my ($partid,$respid) = @{ $part };
  next if ($env{'form.lastSub'} eq 'hdgrade'       my $display_part=&get_display_part($partid,$symb);
  && $$handgrade{$$part[0].'_'.$$part[1]} ne 'yes');      if ($env{"form.$uname:$udom:$partid:submitted_by"}) {
    if (exists($seenparts{$partid})) { next; }
  my ($partid,$respid) = @{ $part };   $seenparts{$partid}=1;
  my $display_part=&get_display_part($partid,$symb);                  $request->print(
  if ($env{"form.$uname:$udom:$partid:submitted_by"}) {                      '<b>'.&mt('Part: [_1]',$display_part).'</b>'.
     if (exists($seenparts{$partid})) { next; }                      ' <b>'.&mt('Collaborative submission by: [_1]',
     $seenparts{$partid}=1;                                 '<a href="javascript:viewSubmitter(\''.
                     $request->print(                                 $env{"form.$uname:$udom:$partid:submitted_by"}.
                         '<b>'.&mt('Part: [_1]',$display_part).'</b>'.                                 '\');" target="_self">'.
                         ' <b>'.&mt('Collaborative submission by: [_1]',                                 $$fullname{$env{"form.$uname:$udom:$partid:submitted_by"}}.'</a>').
                                    '<a href="javascript:viewSubmitter(\''.                      '<br />');
                                    $env{"form.$uname:$udom:$partid:submitted_by"}.   next;
                                    '\');" target="_self">'.      }
                                    $$fullname{$env{"form.$uname:$udom:$partid:submitted_by"}}.'</a>').      my $responsetype = $responseType->{$partid}->{$respid};
                         '<br />');      if (!exists($record{"resource.$partid.$respid.submission"})) {
     next;                  $lastsubonly.="\n".'<div class="LC_grade_submission_part">'.
  }                      '<b>'.&mt('Part: [_1]',$display_part).'</b>'.
  my $responsetype = $responseType->{$partid}->{$respid};                      ' <span class="LC_internal_info">'.
  if (!exists($record{"resource.$partid.$respid.submission"})) {                      '('.&mt('Response ID: [_1]',$respid).')'.
                     $lastsubonly.="\n".'<div class="LC_grade_submission_part">'.                      '</span>&nbsp; &nbsp;'.
                         '<b>'.&mt('Part: [_1]',$display_part).'</b>'.              '<span class="LC_warning">'.&mt('Nothing submitted - no attempts.').'</span><br /><br /></div>';
                         ' <span class="LC_internal_info">'.   next;
                         '('.&mt('Response ID: [_1]',$respid).')'.      }
                         '</span>&nbsp; &nbsp;'.      foreach my $submission (@$string) {
  '<span class="LC_warning">'.&mt('Nothing submitted - no attempts.').'</span><br /><br /></div>';   my ($partid,$respid) = ($submission =~ /^resource\.([^\.]*)\.([^\.]*)\.submission/);
     next;   if (join('_',@{$part}) ne ($partid.'_'.$respid)) { next; }
  }   my ($ressub,$hide,$draft,$subval) = split(/:/,$submission,4);
  foreach my $submission (@$string) {   # Similarity check
     my ($partid,$respid) = ($submission =~ /^resource\.([^\.]*)\.([^\.]*)\.submission/);                  my $similar='';
     if (join('_',@{$part}) ne ($partid.'_'.$respid)) { next; }                  my ($type,$trial,$rndseed);
     my ($ressub,$hide,$draft,$subval) = split(/:/,$submission,4);                  if ($hide eq 'rand') {
     # Similarity check                      $type = 'randomizetry';
     my $similar='';                      $trial = $record{"resource.$partid.tries"};
                     my ($type,$trial,$rndseed);                      $rndseed = $record{"resource.$partid.rndseed"};
                     if ($hide eq 'rand') {                  }
                         $type = 'randomizetry';   if ($env{'form.checkPlag'}) {
                         $trial = $record{"resource.$partid.tries"};      my ($oname,$odom,$ocrsid,$oessay,$osim)=
                         $rndseed = $record{"resource.$partid.rndseed"};          &most_similar($uname,$udom,$symb,$subval);
                     }      if ($osim) {
     if ($env{'form.checkPlag'}) {          $osim=int($osim*100.0);
  my ($oname,$odom,$ocrsid,$oessay,$osim)=                          if ($hide eq 'anon') {
     &most_similar($uname,$udom,$symb,$subval);                              $similar='<hr /><span class="LC_warning">'.&mt("Essay was found to be similar to another essay submitted for this assignment.").'<br />'.
  if ($osim) {                                       &mt('As the current submission is for an anonymous survey, no other details are available.').'</span><hr />';
     $osim=int($osim*100.0);                          } else {
     my %old_course_desc =       $similar='<hr />';
  &Apache::lonnet::coursedescription($ocrsid,                              if ($essayurl eq 'lib/templates/simpleproblem.problem') {
    {'one_time' => 1});                                  $similar .= '<h3><span class="LC_warning">'.
                                               &mt('Essay is [_1]% similar to an essay by [_2]',
                             if ($hide eq 'anon') {                                                  $osim,
                                 $similar='<hr /><span class="LC_warning">'.&mt("Essay was found to be similar to another essay submitted for this assignment.").'<br />'.                                                  &Apache::loncommon::plainname($oname,$odom).' ('.$oname.':'.$odom.')').
                                          &mt('As the current submission is for an anonymous survey, no other details are available.').'</span><hr />';                                              '</span></h3>';
                             } else {                              } elsif ($ocrsid ne '') {
         $similar="<hr /><h3><span class=\"LC_warning\">".                                  my %old_course_desc;
                                   if (ref($coursedesc_by_cid{$ocrsid}) eq 'HASH') {
                                       %old_course_desc = %{$coursedesc_by_cid{$ocrsid}};
                                   } else {
                                       my $args;
                                       if ($ocrsid ne $env{'request.course.id'}) {
                                           $args = {'one_time' => 1};
                                       }
                                       %old_course_desc =
                                           &Apache::lonnet::coursedescription($ocrsid,$args);
                                       $coursedesc_by_cid{$ocrsid} = \%old_course_desc;
                                   }
                                   $similar .=
                                       '<h3><span class="LC_warning">'.
     &mt('Essay is [_1]% similar to an essay by [_2] in course [_3] (course id [_4]:[_5])',      &mt('Essay is [_1]% similar to an essay by [_2] in course [_3] (course id [_4]:[_5])',
         $osim,          $osim,
         &Apache::loncommon::plainname($oname,$odom).' ('.$oname.':'.$odom.')',          &Apache::loncommon::plainname($oname,$odom).' ('.$oname.':'.$odom.')',
         $old_course_desc{'description'},          $old_course_desc{'description'},
         $old_course_desc{'num'},          $old_course_desc{'num'},
         $old_course_desc{'domain'}).          $old_course_desc{'domain'}).
     '</span></h3><blockquote><i>'.      '</span></h3>';
     &keywords_highlight($oessay).  
     '</i></blockquote><hr />';  
                             }  
  }  
     }  
     my $order=&get_order($partid,$respid,$symb,$uname,$udom,  
                                          undef,$type,$trial,$rndseed);  
                     if ($env{'form.lastSub'} eq 'lastonly' || $env{'form.lastSub'} eq 'datesub' || $env{'form.lastSub'} =~ /^(last|all)$/ || ($env{'form.lastSub'} eq 'hdgrade' &&  
                          $$handgrade{$$part[0].'_'.$$part[1]} eq 'yes')) {  
  my $display_part=&get_display_part($partid,$symb);  
                         $lastsubonly.='<div class="LC_grade_submission_part">'.  
                             '<b>'.&mt('Part: [_1]',$display_part).'</b>'.  
                             ' <span class="LC_internal_info">'.  
                             '('.&mt('Response ID: [_1]',$respid).')'.  
                             '</span>&nbsp; &nbsp;';  
  my $files=&get_submitted_files($udom,$uname,$partid,$respid,\%record);  
  if (@$files) {  
                             if ($hide eq 'anon') {  
                                 $lastsubonly.='<br />'.&mt('[quant,_1,file] uploaded to this anonymous survey',scalar(@{$files}));  
                             } else {                              } else {
                                 $lastsubonly.='<br /><br />'.'<b>'.&mt('Submitted Files:').'</b>'                                  $similar .=
                                             .'<br /><span class="LC_warning">';                                      '<h3><span class="LC_warning">'.
                                 if(@$files == 1) {                                      &mt('Essay is [_1]% similar to an essay by [_2] in an unknown course',
                                     $lastsubonly .= &mt('Like all files provided by users, this file may contain viruses!');                                          $osim,
                                 } else {                                          &Apache::loncommon::plainname($oname,$odom).' ('.$oname.':'.$odom.')').
                                     $lastsubonly .= &mt('Like all files provided by users, these files may contain viruses!');                                      '</span></h3>';
                                 }  
                                 $lastsubonly .= '</span>';  
   
                                 foreach my $file (@$files) {  
                                     &Apache::lonnet::allowuploaded('/adm/grades',$file);  
                                     $lastsubonly.='<br /><a href="'.$file.'?rawmode=1" target="lonGRDs"><img src="'.&Apache::loncommon::icon($file).'" border="0" alt="" /> '.$file.'</a>';  
                                 }  
                             }                              }
     $lastsubonly.='<br />';                              $similar .= '<blockquote><i>'.
  }                                          &keywords_highlight($oessay).
                                           '</i></blockquote><hr />';
           }
                       }
                   }
    my $order=&get_order($partid,$respid,$symb,$uname,$udom,
                                        undef,$type,$trial,$rndseed);
                   if (($env{'form.lastSub'} eq 'lastonly') ||
                       ($env{'form.lastSub'} eq 'datesub')  ||
                       ($env{'form.lastSub'} =~ /^(last|all)$/)) {
       my $display_part=&get_display_part($partid,$symb);
                       $lastsubonly.='<div class="LC_grade_submission_part">'.
                           '<b>'.&mt('Part: [_1]',$display_part).'</b>'.
                           ' <span class="LC_internal_info">'.
                           '('.&mt('Response ID: [_1]',$respid).')'.
                           '</span>&nbsp; &nbsp;';
       my $files=&get_submitted_files($udom,$uname,$partid,$respid,\%record);
       if (@$files) {
                         if ($hide eq 'anon') {                          if ($hide eq 'anon') {
                             $lastsubonly.='<br /><b>'.&mt('Anonymous Survey').'</b>';                               $lastsubonly.='<br />'.&mt('[quant,_1,file] uploaded to this anonymous survey',scalar(@{$files}));
                         } else {                          } else {
     $lastsubonly.='<br /><b>'.&mt('Submitted Answer:').' </b>';                              $lastsubonly.='<br /><br />'.'<b>'.&mt('Submitted Files:').'</b>'
                             if ($draft) {                                           .'<br /><span class="LC_warning">';
                                 $lastsubonly.= ' <span class="LC_warning">'.&mt('Draft Copy').'</span>';                              if(@$files == 1) {
                                   $lastsubonly .= &mt('Like all files provided by users, this file may contain viruses!');
                               } else {
                                   $lastsubonly .= &mt('Like all files provided by users, these files may contain viruses!');
                             }                              }
                             $subval =                              $lastsubonly .= '</span>';
         &cleanRecord($subval,$responsetype,$symb,$partid,                              foreach my $file (@$files) {
      $respid,\%record,$order,undef,$uname,$udom,$type,$trial,$rndseed);                                  &Apache::lonnet::allowuploaded('/adm/grades',$file);
                             if ($responsetype eq 'essay') {                                  $lastsubonly.='<br /><a href="'.$file.'?rawmode=1" target="lonGRDs"><img src="'.&Apache::loncommon::icon($file).'" border="0" alt="" /> '.$file.'</a>';
                                 $subval =~ s{\n}{<br />}g;  
                             }                              }
                             $lastsubonly.=$subval."\n";  
                         }                          }
  if ($similar) {$lastsubonly.="<br /><br />$similar\n";}   $lastsubonly.='<br />';
  $lastsubonly.='</div>';  
     }      }
                       if ($hide eq 'anon') {
                           $lastsubonly.='<br /><b>'.&mt('Anonymous Survey').'</b>'; 
                       } else {
                           $lastsubonly.='<br /><b>'.&mt('Submitted Answer:').' </b>';
                           if ($draft) {
                               $lastsubonly.= ' <span class="LC_warning">'.&mt('Draft Copy').'</span>';
                           }
                           $subval =
       &cleanRecord($subval,$responsetype,$symb,$partid,
    $respid,\%record,$order,undef,$uname,$udom,$type,$trial,$rndseed);
                           if ($responsetype eq 'essay') {
                               $subval =~ s{\n}{<br />}g;
                           }
                           $lastsubonly.=$subval."\n";
                       }
                       if ($similar) {$lastsubonly.="<br /><br />$similar\n";}
       $lastsubonly.='</div>';
  }   }
     }      }
     $lastsubonly.='</div>'."\n"; # End: LC_grade_submissions_body  
  }   }
  $request->print($lastsubonly);   $lastsubonly.='</div>'."\n"; # End: LC_grade_submissions_body
    if ($env{'form.lastSub'} eq 'datesub') {      }
  my (undef,$responseType,undef,$parts) = &showResourceInfo($symb);      $request->print($lastsubonly);
       if ($env{'form.lastSub'} eq 'datesub') {
           my ($parts,$handgrade,$responseType) = &response_type($symb,\$res_error);
  $request->print(&displaySubByDates($symb,\%record,$parts,$responseType,$checkIcon,$uname,$udom));   $request->print(&displaySubByDates($symb,\%record,$parts,$responseType,$checkIcon,$uname,$udom));
     }      }
     if ($env{'form.lastSub'} =~ /^(last|all)$/) {      if ($env{'form.lastSub'} =~ /^(last|all)$/) {
Line 2420  sub submission { Line 2692  sub submission {
  'Apache::grades::keywords_highlight',   'Apache::grades::keywords_highlight',
                                                                  $usec,$identifier));                                                                   $usec,$identifier));
     }      }
   
     $request->print('<input type="hidden" name="unamedom'.$counter.'" value="'.$uname.':'      $request->print('<input type="hidden" name="unamedom'.$counter.'" value="'.$uname.':'
  .$udom.'" />'."\n");   .$udom.'" />'."\n");
     # return if view submission with no grading option      # return if view submission with no grading option
     if ($env{'form.showgrading'} eq '' || (!&canmodify($usec))) {      if (!&canmodify($usec)) {
  my $toGrade.='<input type="button" value="Grade Student" '.          $request->print('<p><span class="LC_warning">'.&mt('No grading privileges').'</span></p></div>');
     'onclick="javascript:checksubmit(this.form,\'Grade Student\',\''          return;
     .$counter.'\');" target="_self" /> &nbsp;'."\n" if (&canmodify($usec));  
  $toGrade.='</div>'."\n";  
  if (($env{'form.command'} eq 'submission') ||   
     ($env{'form.command'} eq 'processGroup' && $counter == $total)) {  
     $toGrade.='</form>'.&show_grading_menu_form($symb);   
  }  
  $request->print($toGrade);  
  return;  
     } else {      } else {
  $request->print('</div>'."\n");   $request->print('</div>'."\n");
     }      }
   
     # essay grading message center      # grading message center
     if ($env{'form.handgrade'} eq 'yes') {  
  my $result='<div class="LC_grade_message_center">';      if ($env{'form.compmsg'}) {
               my $result='<div class="LC_Box">'.
  $result.='<div class="LC_grade_message_center_header">'.                     '<h3 class="LC_hcell">'.&mt('Send Message').'</h3>'.
     &mt('Send Message').'</div><div class="LC_grade_message_center_body">';                     '<div class="LC_grade_message_center_body">';
  my ($lastname,$givenn) = split(/,/,$env{'form.fullname'});          my ($lastname,$givenn) = split(/,/,$env{'form.fullname'});
  my $msgfor = $givenn.' '.$lastname;          my $msgfor = $givenn.' '.$lastname;
  if (scalar(@$col_fullnames) > 0) {          if (scalar(@$col_fullnames) > 0) {
     my $lastone = pop(@$col_fullnames);              my $lastone = pop(@$col_fullnames);
     $msgfor .= ', '.(join ', ',@$col_fullnames).' and '.$lastone.'.';              $msgfor .= ', '.(join ', ',@$col_fullnames).' and '.$lastone.'.';
  }          }
  $msgfor =~ s/\'/\\'/g; #' stupid emacs - no! javascript          $msgfor =~ s/\'/\\'/g; #' stupid emacs - no! javascript
  $result.='<input type="hidden" name="includemsg'.$counter.'" value="" />'."\n".          $result.='<input type="hidden" name="includemsg'.$counter.'" value="" />'."\n".
     '<input type="hidden" name="newmsg'.$counter.'" value="" />'."\n";                   '<input type="hidden" name="newmsg'.$counter.'" value="" />'."\n".
  $result.='&nbsp;<a href="javascript:msgCenter(document.SCORE,'.$counter.           '&nbsp;<a href="javascript:msgCenter(document.SCORE,'.$counter.
     ',\''.$msgfor.'\');" target="_self">'.                   ',\''.$msgfor.'\');" target="_self">'.
     &mt('Compose message to student'.(scalar(@$col_fullnames) >= 1 ? 's' : '')).'</a><label> ('.                   &mt('Compose message to student'.(scalar(@$col_fullnames) >= 1 ? 's' : '')).'</a><label> ('.
     &mt('incl. grades').' <input type="checkbox" name="withgrades'.$counter.'" /></label>)'.                   &mt('incl. grades').' <input type="checkbox" name="withgrades'.$counter.'" /></label>)'.
     ' <img src="'.$request->dir_config('lonIconsURL').                   ' <img src="'.$request->dir_config('lonIconsURL').
     '/mailbkgrd.gif" width="14" height="10" name="mailicon'.$counter.'" />'."\n".                   '/mailbkgrd.gif" width="14" height="10" alt="" name="mailicon'.$counter.'" />'."\n".
     '<br />&nbsp;('.                   '<br />&nbsp;('.
     &mt('Message will be sent when you click on Save &amp; Next below.').")\n";                   &mt('Message will be sent when you click on Save &amp; Next below.').")\n".
  $result.='</div></div>';           '</div></div>';
  $request->print($result);          $request->print($result);
     }      }
   
     my %seen = ();      my %seen = ();
Line 2480  sub submission { Line 2743  sub submission {
  my $part_resp = join('_',@{ $part_response_id });   my $part_resp = join('_',@{ $part_response_id });
  next if ($seen{$partid} > 0);   next if ($seen{$partid} > 0);
  $seen{$partid}++;   $seen{$partid}++;
  next if ($$handgrade{$part_resp} ne 'yes'   
  && $env{'form.lastSub'} eq 'hdgrade');  
  push(@partlist,$partid);   push(@partlist,$partid);
  push(@gradePartRespid,$partid.'.'.$respid);   push(@gradePartRespid,$partid.'.'.$respid);
  $request->print(&gradeBox($request,$symb,$uname,$udom,$counter,$partid,\%record));   $request->print(&gradeBox($request,$symb,$uname,$udom,$counter,$partid,\%record));
Line 2532  sub submission { Line 2793  sub submission {
         $endform.="<input type='hidden' value='".&get_increment().          $endform.="<input type='hidden' value='".&get_increment().
             "' name='increment' />";              "' name='increment' />";
  $endform.='</td></tr></table></form>';   $endform.='</td></tr></table></form>';
  $endform.=&show_grading_menu_form($symb);  
  $request->print($endform);   $request->print($endform);
     }      }
     return '';      return '';
Line 2655  sub get_last_submission { Line 2915  sub get_last_submission {
                 }                  }
             }              }
     my ($partid,$foo) = split(/submission$/,$key);      my ($partid,$foo) = split(/submission$/,$key);
     my $draft  = $lasthash{$partid.'awarddetail'} eq 'DRAFT' ? 1: 0;      my $draft  = $lasthash{$partid.'awarddetail'} eq 'DRAFT' ? 1 : 0;
             push(@string, join(':', $key, $hide, $draft, (              push(@string, join(':', $key, $hide, $draft, (
                 ref($lasthash{$key}) eq 'ARRAY' ?                  ref($lasthash{$key}) eq 'ARRAY' ?
                     join(',', @{$lasthash{$key}}) : $lasthash{$key}) ));                      join(',', @{$lasthash{$key}}) : $lasthash{$key}) ));
Line 2864  ENDJS Line 3124  ENDJS
   
 #--- Called from submission routine  #--- Called from submission routine
 sub processHandGrade {  sub processHandGrade {
     my ($request) = shift;      my ($request,$symb) = @_;
     my ($symb)   = &get_symb($request);  
     my (undef,undef,$url) = &Apache::lonnet::decode_symb($symb);      my (undef,undef,$url) = &Apache::lonnet::decode_symb($symb);
     my $button = $env{'form.gradeOpt'};      my $button = $env{'form.gradeOpt'};
     my $ngrade = $env{'form.NCT'};      my $ngrade = $env{'form.NCT'};
     my $ntstu  = $env{'form.NTSTU'};      my $ntstu  = $env{'form.NTSTU'};
     my $cdom   = $env{'course.'.$env{'request.course.id'}.'.domain'};      my $cdom   = $env{'course.'.$env{'request.course.id'}.'.domain'};
     my $cnum   = $env{'course.'.$env{'request.course.id'}.'.num'};      my $cnum   = $env{'course.'.$env{'request.course.id'}.'.num'};
       my ($res_error,%queueable);
       my ($partlist,$handgrade,$responseType,$numresp,$numessay) = &response_type($symb,\$res_error);
       if ($res_error) {
           $request->print(&navmap_errormsg());
           return;
       } else {
           foreach my $part (@{$partlist}) {
               if (ref($responseType->{$part}) eq 'HASH') {
                   foreach my $id (keys(%{$responseType->{$part}})) {
                       if (($responseType->{$part}->{$id} eq 'essay') ||
                           (lc($handgrade->{$part.'_'.$id}) eq 'yes')) {
                           $queueable{$part} = 1;
                           last;
                       }
                   }
               }
           }
       }
   
     if ($button eq 'Save & Next') {      if ($button eq 'Save & Next') {
  my $ctr = 0;   my $ctr = 0;
  while ($ctr < $ngrade) {   while ($ctr < $ngrade) {
     my ($uname,$udom) = split(/:/,$env{'form.unamedom'.$ctr});      my ($uname,$udom) = split(/:/,$env{'form.unamedom'.$ctr});
     my ($errorflag,$pts,$wgt,$numhidden) =       my ($errorflag,$pts,$wgt,$numhidden) = 
                 &saveHandGrade($request,$symb,$uname,$udom,$ctr);                  &saveHandGrade($request,$symb,$uname,$udom,$ctr,undef,undef,\%queueable);
     if ($errorflag eq 'no_score') {      if ($errorflag eq 'no_score') {
  $ctr++;   $ctr++;
  next;   next;
Line 2915  sub processHandGrade { Line 3192  sub processHandGrade {
  if ($env{'form.withgrades'.$ctr}) {   if ($env{'form.withgrades'.$ctr}) {
     $message.="\n\nPoint".($pts > 1 ? 's':'').' awarded = '.$pts.' out of '.$wgt;      $message.="\n\nPoint".($pts > 1 ? 's':'').' awarded = '.$pts.' out of '.$wgt;
     $messagetail = " for <a href=\"".      $messagetail = " for <a href=\"".
                    $feedurl."?symb=$showsymb\">$env{'form.probTitle'}</a>";                     $feedurl."?symb=$showsymb\">$restitle</a>";
  }   }
  $msgstatus =    $msgstatus = 
                     &Apache::lonmsg::user_normal_msg($uname,$udom,$subject,                      &Apache::lonmsg::user_normal_msg($uname,$udom,$subject,
Line 2933  sub processHandGrade { Line 3210  sub processHandGrade {
     foreach my $collaborator (@collaborators) {      foreach my $collaborator (@collaborators) {
  my ($errorflag,$pts,$wgt) =    my ($errorflag,$pts,$wgt) = 
     &saveHandGrade($request,$symb,$collaborator,$udom,$ctr,      &saveHandGrade($request,$symb,$collaborator,$udom,$ctr,
    $env{'form.unamedom'.$ctr},$part);     $env{'form.unamedom'.$ctr},$part,\%queueable);
  if ($errorflag eq 'not_allowed') {   if ($errorflag eq 'not_allowed') {
     $request->print("<span class=\"LC_error\">".&mt('Not allowed to modify grades for [_1]',"$collaborator:$udom")."</span>");      $request->print("<span class=\"LC_error\">".&mt('Not allowed to modify grades for [_1]',"$collaborator:$udom")."</span>");
     next;      next;
Line 2943  sub processHandGrade { Line 3220  sub processHandGrade {
       $udom);        $udom);
     if ($env{'form.withgrades'.$ctr}) {      if ($env{'form.withgrades'.$ctr}) {
  $messagetail = " for <a href=\"".   $messagetail = " for <a href=\"".
                                     $baseurl."?symb=$showsymb\">$env{'form.probTitle'}</a>";                                      $baseurl."?symb=$showsymb\">$restitle</a>";
     }      }
     $msgstatus =       $msgstatus = 
  &Apache::lonmsg::user_normal_msg($collaborator,$udom,$subject,$message.$messagetail,undef,$baseurl,undef,undef,undef,$showsymb,$restitle);   &Apache::lonmsg::user_normal_msg($collaborator,$udom,$subject,$message.$messagetail,undef,$baseurl,undef,undef,undef,$showsymb,$restitle);
Line 2955  sub processHandGrade { Line 3232  sub processHandGrade {
  }   }
     }      }
   
     if ($env{'form.handgrade'} eq 'yes') {      my %keyhash = ();
       if ($numessay) {
  # Keywords sorted in alphabatical order   # Keywords sorted in alphabatical order
  my $loginuser = $env{'user.name'}.':'.$env{'user.domain'};   my $loginuser = $env{'user.name'}.':'.$env{'user.domain'};
  my %keyhash = ();  
  $env{'form.keywords'}           =~ s/,\s{0,}|\s+/ /g;   $env{'form.keywords'}           =~ s/,\s{0,}|\s+/ /g;
  $env{'form.keywords'}           =~ s/^\s+|\s+$//;   $env{'form.keywords'}           =~ s/^\s+|\s+$//g;
  my (@keywords) = sort(split(/\s+/,$env{'form.keywords'}));   my (@keywords) = sort(split(/\s+/,$env{'form.keywords'}));
  $env{'form.keywords'} = join(' ',@keywords);   $env{'form.keywords'} = join(' ',@keywords);
  $keyhash{$symb.'_keywords'}     = $env{'form.keywords'};   $keyhash{$symb.'_keywords'}     = $env{'form.keywords'};
Line 2968  sub processHandGrade { Line 3245  sub processHandGrade {
  $keyhash{$loginuser.'_kwclr'}   = $env{'form.kwclr'};   $keyhash{$loginuser.'_kwclr'}   = $env{'form.kwclr'};
  $keyhash{$loginuser.'_kwsize'}  = $env{'form.kwsize'};   $keyhash{$loginuser.'_kwsize'}  = $env{'form.kwsize'};
  $keyhash{$loginuser.'_kwstyle'} = $env{'form.kwstyle'};   $keyhash{$loginuser.'_kwstyle'} = $env{'form.kwstyle'};
       }
   
       if ($env{'form.compmsg'}) {
  # message center - Order of message gets changed. Blank line is eliminated.   # message center - Order of message gets changed. Blank line is eliminated.
  # New messages are saved in env for the next student.   # New messages are saved in env for the next student.
  # All messages are saved in nohist_handgrade.db   # All messages are saved in nohist_handgrade.db
Line 2991  sub processHandGrade { Line 3270  sub processHandGrade {
  }   }
  $env{'form.savemsgN'} = --$idx;   $env{'form.savemsgN'} = --$idx;
  $keyhash{$symb.'_savemsgN'} = $env{'form.savemsgN'};   $keyhash{$symb.'_savemsgN'} = $env{'form.savemsgN'};
       }
       if (($numessay) || ($env{'form.compmsg'})) {
  my $putresult = &Apache::lonnet::put   my $putresult = &Apache::lonnet::put
     ('nohist_handgrade',\%keyhash,$cdom,$cnum);      ('nohist_handgrade',\%keyhash,$cdom,$cnum);
     }      }
   
     # Called by Save & Refresh from Highlight Attribute Window      # Called by Save & Refresh from Highlight Attribute Window
     my (undef,undef,$fullname) = &getclasslist($env{'form.section'},'1');      my (undef,undef,$fullname) = &getclasslist($env{'form.section'},'1');
     if ($env{'form.refresh'} eq 'on') {      if ($env{'form.refresh'} eq 'on') {
Line 3008  sub processHandGrade { Line 3290  sub processHandGrade {
     my $processUser = $env{'form.unamedom'.$ctr};      my $processUser = $env{'form.unamedom'.$ctr};
     ($env{'form.student'},$env{'form.userdom'}) = split(/:/,$processUser);      ($env{'form.student'},$env{'form.userdom'}) = split(/:/,$processUser);
     $env{'form.fullname'} = $$fullname{$processUser};      $env{'form.fullname'} = $$fullname{$processUser};
     &submission($request,$ctr,$total-1);      &submission($request,$ctr,$total-1,$symb);
     $ctr++;      $ctr++;
  }   }
  return '';   return '';
     }      }
   
 # Go directly to grade student - from submission or link from chart page  
     if ($button eq 'Grade Student') {  
  (undef,undef,$env{'form.handgrade'},undef,undef) = &showResourceInfo($symb);  
  my $processUser = $env{'form.unamedom'.$env{'form.studentNo'}};  
  ($env{'form.student'},$env{'form.userdom'}) = split(/:/,$processUser);  
  $env{'form.fullname'} = $$fullname{$processUser};  
  &submission($request,0,0);  
  return '';  
     }  
   
     # Get the next/previous one or group of students      # Get the next/previous one or group of students
     my $firststu = $env{'form.unamedom0'};      my $firststu = $env{'form.unamedom0'};
     my $laststu = $env{'form.unamedom'.($ngrade-1)};      my $laststu = $env{'form.unamedom'.($ngrade-1)};
Line 3054  sub processHandGrade { Line 3326  sub processHandGrade {
     }      }
     $ctr = 0;      $ctr = 0;
     @parsedlist = reverse @parsedlist if ($button eq 'Previous');      @parsedlist = reverse @parsedlist if ($button eq 'Previous');
     my $res_error;  
     my ($partlist) = &response_type($symb,\$res_error);  
     if ($res_error) {  
         $request->print(&navmap_errormsg());  
         return;  
     }  
     foreach my $student (@parsedlist) {      foreach my $student (@parsedlist) {
  my $submitonly=$env{'form.submitonly'};   my $submitonly=$env{'form.submitonly'};
  my ($uname,$udom) = split(/:/,$student);   my ($uname,$udom) = split(/:/,$student);
Line 3105  sub processHandGrade { Line 3371  sub processHandGrade {
  $env{'form.student'}  = $uname;   $env{'form.student'}  = $uname;
  $env{'form.userdom'}  = $udom;   $env{'form.userdom'}  = $udom;
  $env{'form.fullname'} = $$fullname{$_};   $env{'form.fullname'} = $$fullname{$_};
  &submission($request,$ctr,$total);   &submission($request,$ctr,$total,$symb);
  $ctr++;   $ctr++;
     }      }
     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.='<p>'.&mt('[_1]Message:[_2] No more students for this section or class.','<b>','</b>').'</p>'."\n";
  $the_end.='<p>'.&mt('[_1]Message:[_2] No more students for this section or class.','<b>','</b>').'</p>'."\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);  
  $request->print($the_end);   $request->print($the_end);
     }      }
     return '';      return '';
Line 3120  sub processHandGrade { Line 3383  sub processHandGrade {
   
 #---- Save the score and award for each student, if changed  #---- Save the score and award for each student, if changed
 sub saveHandGrade {  sub saveHandGrade {
     my ($request,$symb,$stuname,$domain,$newflg,$submitter,$part) = @_;      my ($request,$symb,$stuname,$domain,$newflg,$submitter,$part,$queueable) = @_;
     my @version_parts;      my @version_parts;
     my $usec = &Apache::lonnet::getsection($domain,$stuname,      my $usec = &Apache::lonnet::getsection($domain,$stuname,
    $env{'request.course.id'});     $env{'request.course.id'});
Line 3232  sub saveHandGrade { Line 3495  sub saveHandGrade {
  &Apache::lonnet::cstore(\%newrecord,$symb,   &Apache::lonnet::cstore(\%newrecord,$symb,
  $env{'request.course.id'},$domain,$stuname);   $env{'request.course.id'},$domain,$stuname);
  &check_and_remove_from_queue(\@parts,\%record,\%newrecord,$symb,   &check_and_remove_from_queue(\@parts,\%record,\%newrecord,$symb,
      $cdom,$cnum,$domain,$stuname);       $cdom,$cnum,$domain,$stuname,$queueable);
     }      }
     if ($aggregateflag) {      if ($aggregateflag) {
         &Apache::lonnet::cinc('nohist_resourcetracker',\%aggregate,          &Apache::lonnet::cinc('nohist_resourcetracker',\%aggregate,
Line 3272  sub makehidden { Line 3535  sub makehidden {
 }  }
   
 sub check_and_remove_from_queue {  sub check_and_remove_from_queue {
     my ($parts,$record,$newrecord,$symb,$cdom,$cnum,$domain,$stuname) = @_;      my ($parts,$record,$newrecord,$symb,$cdom,$cnum,$domain,$stuname,$queueable) = @_;
     my @ungraded_parts;      my @ungraded_parts;
     foreach my $part (@{$parts}) {      foreach my $part (@{$parts}) {
  if (    $record->{   'resource.'.$part.'.awarded'} eq ''   if (    $record->{   'resource.'.$part.'.awarded'} eq ''
Line 3280  sub check_and_remove_from_queue { Line 3543  sub check_and_remove_from_queue {
      && $newrecord->{'resource.'.$part.'.awarded'} eq ''       && $newrecord->{'resource.'.$part.'.awarded'} eq ''
      && $newrecord->{'resource.'.$part.'.solved' } ne 'excused'       && $newrecord->{'resource.'.$part.'.solved' } ne 'excused'
  ) {   ) {
     push(@ungraded_parts, $part);              if ($queueable->{$part}) {
           push(@ungraded_parts, $part);
               }
  }   }
     }      }
     if ( !@ungraded_parts ) {      if ( !@ungraded_parts ) {
Line 3352  sub handback_files { Line 3617  sub handback_files {
         my ($subject,$message);          my ($subject,$message);
         if (scalar(@handedback) == 1) {          if (scalar(@handedback) == 1) {
             $subject = &mt_user($user_lh,'File Handed Back by Instructor');              $subject = &mt_user($user_lh,'File Handed Back by Instructor');
               $message = &mt_user($user_lh,'A file has been returned that was originally submitted in response to: ');
         } else {          } else {
             $subject = &mt_user($user_lh,'Files Handed Back by Instructor');              $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 = &mt_user($user_lh,'Files have been returned that were originally submitted in response to: ');
Line 3566  sub viewgrades_js { Line 3832  sub viewgrades_js {
   
     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 = ');
     &js_escape(\$alertmsg);      &js_escape(\$alertmsg);
     $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 3728  sub viewgrades_js { Line 3993  sub viewgrades_js {
  }   }
     }      }
   
 </script>  
 VIEWJAVASCRIPT  VIEWJAVASCRIPT
 }  }
   
 #--- show scores for a section or whole class w/ option to change/update a score  #--- show scores for a section or whole class w/ option to change/update a score
 sub viewgrades {  sub viewgrades {
     my ($request) = shift;      my ($request,$symb) = @_;
     &viewgrades_js($request);      &viewgrades_js($request);
   
     my ($symb) = &get_symb($request);  
     #need to make sure we have the correct data for later EXT calls,       #need to make sure we have the correct data for later EXT calls, 
     #thus invalidate the cache      #thus invalidate the cache
     &Apache::lonnet::devalidatecourseresdata(      &Apache::lonnet::devalidatecourseresdata(
Line 3746  sub viewgrades { Line 4009  sub viewgrades {
     &Apache::lonnet::clear_EXT_cache_status();      &Apache::lonnet::clear_EXT_cache_status();
   
     my $result='<h3><span class="LC_info">'.&mt('Manual Grading').'</span></h3>';      my $result='<h3><span class="LC_info">'.&mt('Manual Grading').'</span></h3>';
     $result.='<h4><b>'.&mt('Current Resource').':</b> '.$env{'form.probTitle'}.'</h4>'."\n";  
   
     #view individual student submission form - called using Javascript viewOneStudent      #view individual student submission form - called using Javascript viewOneStudent
     $result.=&jscriptNform($symb);      $result.=&jscriptNform($symb);
Line 3757  sub viewgrades { Line 4019  sub viewgrades {
  '<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="command" value="editgrades" />'."\n".   '<input type="hidden" name="command" value="editgrades" />'."\n".
  &build_section_inputs().   &build_section_inputs().
  '<input type="hidden" name="saveState" value="'.$env{'form.saveState'}.'" />'."\n".  
  '<input type="hidden" name="Status" value="'.$env{'stu_status'}.'" />'."\n".   '<input type="hidden" name="Status" value="'.$env{'stu_status'}.'" />'."\n".
  '<input type="hidden" name="probTitle" value="'.$env{'form.probTitle'}.'" />'."\n";  
   
     #retrieve selected groups      #retrieve selected groups
     my (@groups,$group_display);      my (@groups,$group_display);
Line 3773  sub viewgrades { Line 4033  sub viewgrades {
     }      }
   
     my ($common_header,$specific_header,@sections,$section_display);      my ($common_header,$specific_header,@sections,$section_display);
     @sections = &Apache::loncommon::get_env_multiple('form.section');      if ($env{'request.course.sec'} ne '') {
           @sections = ($env{'request.course.sec'});
       } else {
           @sections = &Apache::loncommon::get_env_multiple('form.section');
       }
   
   # Check if Save button should be usable
       my $disabled = ' disabled="disabled"';
       if ($perm{'mgr'}) {
           if (grep(/^all$/,@sections)) {
               undef($disabled);
           } else {
               foreach my $sec (@sections) {
                   if (&canmodify($sec)) {
                       undef($disabled);
                       last;
                   }
               }
           }
       }
     if (grep(/^all$/,@sections)) {      if (grep(/^all$/,@sections)) {
         @sections = ('all');          @sections = ('all');
         if ($group_display) {          if ($group_display) {
Line 3838  sub viewgrades { Line 4117  sub viewgrades {
  my $part_resp = join('_',@{ $part_response_id });   my $part_resp = join('_',@{ $part_response_id });
  next if $seen{$partid};   next if $seen{$partid};
  $seen{$partid}++;   $seen{$partid}++;
  my $handgrade=$$handgrade{$part_resp};  
  my $wgt = &Apache::lonnet::EXT('resource.'.$partid.'.weight',$symb);   my $wgt = &Apache::lonnet::EXT('resource.'.$partid.'.weight',$symb);
  $weight{$partid} = $wgt eq '' ? '1' : $wgt;   $weight{$partid} = $wgt eq '' ? '1' : $wgt;
   
Line 3907  sub viewgrades { Line 4185  sub viewgrades {
  if  (!$display) { $display = &Apache::lonnet::metadata($url,$part.'.name'); }   if  (!$display) { $display = &Apache::lonnet::metadata($url,$part.'.name'); }
  my ($partid) = &split_part_type($part);   my ($partid) = &split_part_type($part);
         push(@partids,$partid);          push(@partids,$partid);
   #
   # FIXME: Looks like $display looks at English text
   #
  my $display_part=&get_display_part($partid,$symb);   my $display_part=&get_display_part($partid,$symb);
  if ($display =~ /^Partial Credit Factor/) {   if ($display =~ /^Partial Credit Factor/) {
     $result.='<th>'.      $result.='<th>'.
Line 3946  sub viewgrades { Line 4227  sub viewgrades {
     }      }
     $result.=&Apache::loncommon::end_data_table();      $result.=&Apache::loncommon::end_data_table();
     $result.='<input type="hidden" name="total" value="'.$ctr.'" />'."\n";      $result.='<input type="hidden" name="total" value="'.$ctr.'" />'."\n";
     $result.='<input type="button" value="'.&mt('Save').'" '.      $result.='<input type="button" value="'.&mt('Save').'"'.$disabled.' '.
  'onclick="javascript:submit();" target="_self" /></form>'."\n";   'onclick="javascript:submit();" target="_self" /></form>'."\n";
     if ($ctr == 0) {      if ($ctr == 0) {
         my $stu_status = join(' or ',&Apache::loncommon::get_env_multiple('form.Status'));          my $stu_status = join(' or ',&Apache::loncommon::get_env_multiple('form.Status'));
Line 4025  sub viewgrades { Line 4306  sub viewgrades {
  }   }
  $result .= '</span><br />';   $result .= '</span><br />';
     }      }
     $result.=&show_grading_menu_form($symb);  
     return $result;      return $result;
 }  }
   
Line 4137  sub viewstudentgrade { Line 4417  sub viewstudentgrade {
 #--- change scores for all the students in a section/class  #--- change scores for all the students in a section/class
 #    record does not get update if unchanged  #    record does not get update if unchanged
 sub editgrades {  sub editgrades {
     my ($request) = @_;      my ($request,$symb) = @_;
   
     my ($symb)=&get_symb($request);  
     my $section_display = join (", ",&Apache::loncommon::get_env_multiple('form.section'));      my $section_display = join (", ",&Apache::loncommon::get_env_multiple('form.section'));
     my $title='<h2>'.&mt('Current Grade Status').'</h2>';      my $title='<h2>'.&mt('Current Grade Status').'</h2>';
     $title.='<h4><b>'.&mt('Current Resource').':</b> '.$env{'form.probTitle'}.'</h4>'."\n";  
     $title.='<h4><b>'.&mt('Section:').'</b> '.$section_display.'</h4>'."\n";      $title.='<h4><b>'.&mt('Section:').'</b> '.$section_display.'</h4>'."\n";
   
     my $result= &Apache::loncommon::start_data_table().      my $result= &Apache::loncommon::start_data_table().
Line 4209  sub editgrades { Line 4487  sub editgrades {
  &Apache::loncommon::end_data_table_header_row();   &Apache::loncommon::end_data_table_header_row();
     my @noupdate;      my @noupdate;
     my ($updateCtr,$noupdateCtr) = (1,1);      my ($updateCtr,$noupdateCtr) = (1,1);
       my ($got_types,%queueable);
     for ($i=0; $i<$env{'form.total'}; $i++) {      for ($i=0; $i<$env{'form.total'}; $i++) {
  my $user = $env{'form.ctr'.$i};   my $user = $env{'form.ctr'.$i};
  my ($uname,$udom)=split(/:/,$user);   my ($uname,$udom)=split(/:/,$user);
  my %newrecord;   my %newrecord;
  my $updateflag = 0;   my $updateflag = 0;
  my $usec=$classlist->{"$uname:$udom"}[5];          my $usec=$classlist->{"$uname:$udom"}[5];
         my $canmodify = &canmodify($usec);          my $canmodify = &canmodify($usec);
         my $line = '<td'.($canmodify?'':' colspan="2"').'>'.          my $line = '<td'.($canmodify?'':' colspan="2"').'>'.
                    &nameUserString(undef,$$fullname{$user},$uname,$udom).'</td>';                     &nameUserString(undef,$$fullname{$user},$uname,$udom).'</td>';
Line 4308  sub editgrades { Line 4587  sub editgrades {
      $udom,$uname);       $udom,$uname);
  my $all_graded = 1;   my $all_graded = 1;
  my $none_graded = 1;   my $none_graded = 1;
                   unless ($got_types) {
                       my $error;
                       my ($plist,$handgrd,$resptype) = &response_type($symb,\$error);
                       unless ($error) {
                           foreach my $part (@parts) {
                               if (ref($resptype->{$part}) eq 'HASH') {
                                   foreach my $id (keys(%{$resptype->{$part}})) {
                                       if (($resptype->{$part}->{$id} eq 'essay') ||
                                           (lc($handgrd->{$part.'_'.$id}) eq 'yes')) {
                                           $queueable{$part} = 1;
                                           last;
                                       }
                                   }
                               }
                           }
                       }
                       $got_types = 1;
                   }
  foreach my $part (@parts) {   foreach my $part (@parts) {
     if ( $record{'resource.'.$part.'.awarded'} eq '' ) {                      if ($queueable{$part}) {
  $all_graded = 0;          if ( $record{'resource.'.$part.'.awarded'} eq '' ) {
     } else {      $all_graded = 0;
  $none_graded = 0;          } else {
     }      $none_graded = 0;
           }
                       }
  }   }
   
  if ($all_graded || $none_graded) {   if ($all_graded || $none_graded) {
Line 4351  sub editgrades { Line 4650  sub editgrades {
  &Apache::loncommon::end_data_table_row();   &Apache::loncommon::end_data_table_row();
  }   }
     }      }
     $result .= &Apache::loncommon::end_data_table().      $result .= &Apache::loncommon::end_data_table();
  &show_grading_menu_form($symb);  
     my $msg = '<p><b>'.      my $msg = '<p><b>'.
  &mt('Number of records updated = [_1] for [quant,_2,student].',   &mt('Number of records updated = [_1] for [quant,_2,student].',
     $rec_update,$count).'</b><br />'.      $rec_update,$count).'</b><br />'.
Line 4469  sub csvuploadmap_header { Line 4767  sub csvuploadmap_header {
  $javascript=&csvupload_javascript_forward_associate();   $javascript=&csvupload_javascript_forward_associate();
     }      }
   
     my ($result) = &showResourceInfo($symb,$env{'form.probTitle'});  
     my $checked=(($env{'form.noFirstLine'})?' checked="checked"':'');      my $checked=(($env{'form.noFirstLine'})?' checked="checked"':'');
     my $ignore=&mt('Ignore First Line');      my $ignore=&mt('Ignore First Line');
     $symb = &Apache::lonenc::check_encrypt($symb);      $symb = &Apache::lonenc::check_encrypt($symb);
       $request->print('<form method="post" enctype="multipart/form-data" action="/adm/grades" name="gradesupload">'.
                       &mt('Total number of records found in file: [_1]',$distotal).'<hr />'.
                       &mt('Associate entries from the uploaded file with as many fields as you can.'));
       my $reverse=&mt("Reverse Association");
     $request->print(<<ENDPICK);      $request->print(<<ENDPICK);
 <form method="post" enctype="multipart/form-data" action="/adm/grades" name="gradesupload">  <br />
 <h3><span class="LC_info">Uploading Class Grades</span></h3>  <input type="button" value="$reverse" onclick="javascript:this.form.associate.value='Reverse Association';submit(this.form);" />
 $result  
 <hr />  
 <h3>Identify fields</h3>  
 Total number of records found in file: $distotal <hr />  
 Enter as many fields as you can. The system will inform you and bring you back  
 to this page if the data selected is insufficient to run your class.<hr />  
 <input type="button" value="Reverse Association" onclick="javascript:this.form.associate.value='Reverse Association';submit(this.form);" />  
 <label><input type="checkbox" name="noFirstLine" $checked />$ignore</label>  <label><input type="checkbox" name="noFirstLine" $checked />$ignore</label>
 <input type="hidden" name="associate"  value="" />  <input type="hidden" name="associate"  value="" />
 <input type="hidden" name="phase"      value="three" />  <input type="hidden" name="phase"      value="three" />
Line 4492  to this page if the data selected is ins Line 4786  to this page if the data selected is ins
 <input type="hidden" name="upfile_associate"   <input type="hidden" name="upfile_associate" 
                                        value="$env{'form.upfile_associate'}" />                                         value="$env{'form.upfile_associate'}" />
 <input type="hidden" name="symb"       value="$symb" />  <input type="hidden" name="symb"       value="$symb" />
 <input type="hidden" name="saveState"  value="$env{'form.saveState'}" />  
 <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 4546  ENDPICK Line 4836  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.');
     &js_escape(\$alertmsg);      &js_escape(\$alertmsg);
     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 4555  sub checkforfile_js { Line 4844  sub checkforfile_js {
  }   }
  formname.submit();   formname.submit();
     }      }
     </script>  
 CSVFORMJS  CSVFORMJS
     return $result;      return $result;
 }  }
   
 sub upcsvScores_form {  sub upcsvScores_form {
     my ($request) = shift;      my ($request,$symb) = @_;
     my ($symb)=&get_symb($request);  
     if (!$symb) {return '';}      if (!$symb) {return '';}
     my $result=&checkforfile_js();      my $result=&checkforfile_js();
     $env{'form.probTitle'} = &Apache::lonnet::gettitle($symb);      $result.=&Apache::loncommon::start_data_table().
     my ($table) = &showResourceInfo($symb,$env{'form.probTitle'});               &Apache::loncommon::start_data_table_header_row().
     $result.=$table;               '<th>'.&mt('Specify a file containing the class scores for current resource.').'</th>'.
     $result.='<br /><table width="100%" border="0"><tr><td bgcolor="#777777">'."\n";               &Apache::loncommon::end_data_table_header_row().
     $result.='<table width="100%" border="0"><tr bgcolor="#e6ffff"><td>'."\n";               &Apache::loncommon::start_data_table_row().'<td>';
     $result.='&nbsp;<b>'.&mt('Specify a file containing the class scores for current resource.').  
  '</b></td></tr>'."\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 4581  sub upcsvScores_form { Line 4865  sub upcsvScores_form {
 <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="csvuploadmap" />  <input type="hidden" name="command" value="csvuploadmap" />
 <input type="hidden" name="probTitle" value="$env{'form.probTitle'}" />  
 <input type="hidden" name="saveState"  value="$env{'form.saveState'}" />  
 $upfile_select  $upfile_select
 <br /><input type="button" onclick="javascript:checkUpload(this.form);" value="$upload" />  <br /><input type="button" onclick="javascript:checkUpload(this.form);" value="$upload" />
 <label><input type="checkbox" name="noFirstLine" />$ignore</label>  <label><input type="checkbox" name="noFirstLine" />$ignore</label>
 </form>  </form>
 ENDUPFORM  ENDUPFORM
     $result.=&Apache::loncommon::help_open_topic("Course_Convert_To_CSV",      $result.=&Apache::loncommon::help_open_topic("Course_Convert_To_CSV",
                            &mt("How do I create a CSV file from a spreadsheet"))                             &mt("How do I create a CSV file from a spreadsheet")).
     .'</td></tr></table>'."\n";              '</td>'.
     $result.='</td></tr></table><br /><br />'."\n";              &Apache::loncommon::end_data_table_row().
     $result.=&show_grading_menu_form($symb);              &Apache::loncommon::end_data_table();
     return $result;      return $result;
 }  }
   
   
 sub csvuploadmap {  sub csvuploadmap {
     my ($request)= @_;      my ($request,$symb) = @_;
     my ($symb)=&get_symb($request);  
     if (!$symb) {return '';}      if (!$symb) {return '';}
   
     my $datatoken;      my $datatoken;
Line 4607  sub csvuploadmap { Line 4888  sub csvuploadmap {
  $datatoken=&Apache::loncommon::upfile_store($request);   $datatoken=&Apache::loncommon::upfile_store($request);
     } else {      } else {
         $datatoken=&Apache::loncommon::valid_datatoken($env{'form.datatoken'});          $datatoken=&Apache::loncommon::valid_datatoken($env{'form.datatoken'});
         if ($datatoken ne '') {          if ($datatoken ne '') { 
             &Apache::loncommon::load_tmp_file($request,$datatoken);      &Apache::loncommon::load_tmp_file($request,$datatoken);
         }          }
     }      }
     my @records=&Apache::loncommon::upfile_record_sep();      my @records=&Apache::loncommon::upfile_record_sep();
Line 4642  sub csvuploadmap { Line 4923  sub csvuploadmap {
  }   }
     }      }
     &csvuploadmap_footer($request,$i,$keyfields);      &csvuploadmap_footer($request,$i,$keyfields);
     $request->print(&show_grading_menu_form($symb));  
   
     return '';      return '';
 }  }
   
 sub csvuploadoptions {  sub csvuploadoptions {
     my ($request)= @_;      my ($request,$symb)= @_;
     my ($symb)=&get_symb($request);      my $overwrite=&mt('Overwrite any existing score');
     my $checked=(($env{'form.noFirstLine'})?'1':'0');      my $checked=(($env{'form.noFirstLine'})?'1':'0');
     my $ignore=&mt('Ignore First Line');      my $ignore=&mt('Ignore First Line');
     $request->print(<<ENDPICK);      $request->print(<<ENDPICK);
 <form method="post" enctype="multipart/form-data" action="/adm/grades" name="gradesupload">  <form method="post" enctype="multipart/form-data" action="/adm/grades" name="gradesupload">
 <h3><span class="LC_info">Uploading Class Grade Options</span></h3>  
 <input type="hidden" name="command"    value="csvuploadassign" />  <input type="hidden" name="command"    value="csvuploadassign" />
 <!--  
 <p>  
 <label>  
    <input type="checkbox" name="show_full_results" />  
    Show a table of all changes  
 </label>  
 </p>  
 -->  
 <p>  <p>
 <label>  <label>
    <input type="checkbox" name="overwite_scores" checked="checked" />     <input type="checkbox" name="overwite_scores" checked="checked" />
    Overwrite any existing score     $overwrite
 </label>  </label>
 </p>  </p>
 ENDPICK  ENDPICK
     my %fields=&get_fields();      my %fields=&get_fields();
     if (!defined($fields{'domain'})) {      if (!defined($fields{'domain'})) {
  my $domform = &Apache::loncommon::select_dom_form($env{'request.role.domain'},'default_domain');   my $domform = &Apache::loncommon::select_dom_form($env{'request.role.domain'},'default_domain');
  $request->print("\n<p> Users are in domain: ".$domform."</p>\n");          $request->print("\n<p>".&mt('Users are in domain: [_1]',$domform)."</p>\n");
     }      }
     foreach my $key (sort(keys(%env))) {      foreach my $key (sort(keys(%env))) {
  if ($key !~ /^form\.(.*)$/) { next; }   if ($key !~ /^form\.(.*)$/) { next; }
Line 4687  ENDPICK Line 4958  ENDPICK
     # FIXME do a check for any invalid user ids?...      # FIXME do a check for any invalid user ids?...
     $request->print('<input type="submit" value="'.&mt('Assign Grades').'" /><br />      $request->print('<input type="submit" value="'.&mt('Assign Grades').'" /><br />
 <hr /></form>'."\n");  <hr /></form>'."\n");
     $request->print(&show_grading_menu_form($symb));  
     return '';      return '';
 }  }
   
Line 4709  sub get_fields { Line 4979  sub get_fields {
 }  }
   
 sub csvuploadassign {  sub csvuploadassign {
     my ($request)= @_;      my ($request,$symb) = @_;
     my ($symb)=&get_symb($request);  
     if (!$symb) {return '';}      if (!$symb) {return '';}
     my $error_msg = '';      my $error_msg = '';
     my $datatoken = &Apache::loncommon::valid_datatoken($env{'form.datatoken'});      my $datatoken = &Apache::loncommon::valid_datatoken($env{'form.datatoken'});
Line 4720  sub csvuploadassign { Line 4989  sub csvuploadassign {
     my @gradedata = &Apache::loncommon::upfile_record_sep();      my @gradedata = &Apache::loncommon::upfile_record_sep();
     if ($env{'form.noFirstLine'}) { shift(@gradedata); }      if ($env{'form.noFirstLine'}) { shift(@gradedata); }
     my %fields=&get_fields();      my %fields=&get_fields();
     $request->print('<h3>Assigning Grades</h3>');  
     my $courseid=$env{'request.course.id'};      my $courseid=$env{'request.course.id'};
     my ($classlist) = &getclasslist('all',0);      my ($classlist) = &getclasslist('all',0);
     my @notallowed;      my @notallowed;
Line 4796  sub csvuploadassign { Line 5064  sub csvuploadassign {
  $grades{$store_key}=$entries{$fields{$dest}};   $grades{$store_key}=$entries{$fields{$dest}};
     }      }
  }   }
  if (! %grades) {    if (! %grades) {
            push(@skipped,&mt("[_1]: no data to save","$username:$domain"));              push(@skipped,&mt("[_1]: no data to save","$username:$domain")); 
         } else {          } else {
    $grades{"resource.regrader"}="$env{'user.name'}:$env{'user.domain'}";     $grades{"resource.regrader"}="$env{'user.name'}:$env{'user.domain'}";
Line 4804  sub csvuploadassign { Line 5072  sub csvuploadassign {
    $env{'request.course.id'},     $env{'request.course.id'},
    $domain,$username);     $domain,$username);
    if ($result eq 'ok') {     if ($result eq 'ok') {
   # Successfully stored
       $request->print('.');        $request->print('.');
 # Remove from grading queue  # Remove from grading queue
               &Apache::bridgetask::remove_from_queue('gradingqueue',$symb,                &Apache::bridgetask::remove_from_queue('gradingqueue',$symb,
Line 4833  sub csvuploadassign { Line 5102  sub csvuploadassign {
  $request->print(join(', ',@notallowed));   $request->print(join(', ',@notallowed));
     }      }
     $request->print("<br />\n");      $request->print("<br />\n");
     $request->print(&show_grading_menu_form($symb));  
     return $error_msg;      return $error_msg;
 }  }
 #------------- end of section for handling csv file upload ---------  #------------- end of section for handling csv file upload ---------
Line 4844  sub csvuploadassign { Line 5112  sub csvuploadassign {
 #  #
 #--- Select a page/sequence and a student to grade  #--- Select a page/sequence and a student to grade
 sub pickStudentPage {  sub pickStudentPage {
     my ($request) = shift;      my ($request,$symb) = @_;
   
     my $alertmsg = &mt('Please select the student you wish to grade.');      my $alertmsg = &mt('Please select the student you wish to grade.');
     &js_escape(\$alertmsg);      &js_escape(\$alertmsg);
     $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 4862  function checkPickOne(formname) { Line 5129  function checkPickOne(formname) {
     formname.submit();      formname.submit();
 }  }
   
 </script>  
 LISTJAVASCRIPT  LISTJAVASCRIPT
     &commonJSfunctions($request);      &commonJSfunctions($request);
     my ($symb) = &get_symb($request);  
     my $cdom      = $env{"course.$env{'request.course.id'}.domain"};      my $cdom      = $env{"course.$env{'request.course.id'}.domain"};
     my $cnum      = $env{"course.$env{'request.course.id'}.num"};      my $cnum      = $env{"course.$env{'request.course.id'}.num"};
     my $getsec    = $env{'form.section'} eq '' ? 'all' : $env{'form.section'};      my $getsec    = $env{'form.section'} eq '' ? 'all' : $env{'form.section'};
       my $getgroup  = $env{'form.group'} eq '' ? 'all' : $env{'form.group'};
   
     my $result='<h3><span class="LC_info">&nbsp;'.      my $result='<h3><span class="LC_info">&nbsp;'.
  &mt('Manual Grading by Page or Sequence').'</span></h3>';   &mt('Manual Grading by Page or Sequence').'</span></h3>';
Line 4883  LISTJAVASCRIPT Line 5150  LISTJAVASCRIPT
     my ($curpage) =&Apache::lonnet::decode_symb($symb);       my ($curpage) =&Apache::lonnet::decode_symb($symb); 
 #    my ($curpage,$mapId) =&Apache::lonnet::decode_symb($symb);   #    my ($curpage,$mapId) =&Apache::lonnet::decode_symb($symb); 
 #    my $type=($curpage =~ /\.(page|sequence)/);  #    my $type=($curpage =~ /\.(page|sequence)/);
     my $select = '<select name="selectpage">'."\n";  
     my $ctr=0;  
     foreach (@$titles) {  
  my ($minder,$showtitle) = ($_ =~ /(\d+)\.(.*)/);  
  $select.='<option value="'.$ctr.'" '.  
     ($$symbx{$_} =~ /$curpage$/ ? 'selected="selected"' : '').  
     '>'.$showtitle.'</option>'."\n";  
  $ctr++;  
     }  
     $select.= '</select>';  
     $result.='&nbsp;<b>'.&mt('Problems from').':</b> '.$select."<br />\n";  
   
     $ctr=0;      # Collection of hidden fields
       my $ctr=0;
     foreach (@$titles) {      foreach (@$titles) {
  my ($minder,$showtitle) = ($_ =~ /(\d+)\.(.*)/);   my ($minder,$showtitle) = ($_ =~ /(\d+)\.(.*)/);
  $result.='<input type="hidden" name="page'.$ctr.'" value="'.$$symbx{$_}.'" />'."\n";   $result.='<input type="hidden" name="page'.$ctr.'" value="'.$$symbx{$_}.'" />'."\n";
Line 4905  LISTJAVASCRIPT Line 5162  LISTJAVASCRIPT
     $result.='<input type="hidden" name="page" />'."\n".      $result.='<input type="hidden" name="page" />'."\n".
  '<input type="hidden" name="title" />'."\n";   '<input type="hidden" name="title" />'."\n";
   
     my $options =  
  '<label><input type="radio" name="vProb" value="no" checked="checked" /> '.&mt('no').' </label>'."\n".  
  '<label><input type="radio" name="vProb" value="yes" /> '.&mt('yes').' </label>'."<br />\n";  
     $result.='&nbsp;<b>'.&mt('View Problem Text').': </b>'.$options;  
   
     $options =  
  '<label><input type="radio" name="lastSub" value="none" /> '.&mt('none').' </label>'."\n".  
  '<label><input type="radio" name="lastSub" value="datesub" checked="checked" /> '.&mt('by dates and submissions').'</label>'."\n".  
  '<label><input type="radio" name="lastSub" value="all" /> '.&mt('all details').' </label>'."\n";  
     $result.='&nbsp;<b>'.&mt('Submissions').': </b>'.$options;  
       
     $result.=&build_section_inputs();      $result.=&build_section_inputs();
     my $stu_status = join(':',&Apache::loncommon::get_env_multiple('form.Status'));      my $stu_status = join(':',&Apache::loncommon::get_env_multiple('form.Status'));
     $result.='<input type="hidden" name="Status"  value="'.$stu_status.'" />'."\n".      $result.='<input type="hidden" name="Status"  value="'.$stu_status.'" />'."\n".
  '<input type="hidden" name="command" value="displayPage" />'."\n".          '<input type="hidden" name="command" value="displayPage" />'."\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'}.'" />'."<br />\n";  
       # Show grading options
       $result.=&Apache::lonhtmlcommon::start_pick_box();
       my $select = '<select name="selectpage">'."\n";
       $ctr=0;
       foreach (@$titles) {
           my ($minder,$showtitle) = ($_ =~ /(\d+)\.(.*)/);
           $select.='<option value="'.$ctr.'"'.
               ($$symbx{$_} =~ /$curpage$/ ? ' selected="selected"' : '').
               '>'.$showtitle.'</option>'."\n";
           $ctr++;
       }
       $select.= '</select>';
   
     $result.='&nbsp;<b>'.&mt('Use CODE').': </b> <input type="text" name="CODE" value="" /> <br />'."\n";      $result.=
           &Apache::lonhtmlcommon::row_title(&mt('Problems from'))
          .$select
          .&Apache::lonhtmlcommon::row_closure();
   
       $result.=
           &Apache::lonhtmlcommon::row_title(&mt('View Problem Text'))
          .'<label><input type="radio" name="vProb" value="no"'
              .' checked="checked" /> '.&mt('no').' </label>'."\n"
          .'<label><input type="radio" name="vProb" value="yes" />'
              .&mt('yes').'</label>'."\n"
          .&Apache::lonhtmlcommon::row_closure();
   
       $result.=
           &Apache::lonhtmlcommon::row_title(&mt('View Submissions'))
          .'<label><input type="radio" name="lastSub" value="none" /> '
              .&mt('none').' </label>'."\n"
          .'<label><input type="radio" name="lastSub" value="datesub"'
              .' checked="checked" /> '.&mt('all submissions').'</label>'."\n"
          .'<label><input type="radio" name="lastSub" value="all" /> '
              .&mt('all submissions with details').' </label>'
          .&Apache::lonhtmlcommon::row_closure();
   
       $result.=
           &Apache::lonhtmlcommon::row_title(&mt('Use CODE'))
          .'<input type="text" name="CODE" value="" />'
          .&Apache::lonhtmlcommon::row_closure(1)
          .&Apache::lonhtmlcommon::end_pick_box();
   
     $result.='&nbsp;<input type="button" '.      # Show list of students to select for grading
       $result.='<br /><input type="button" '.
              'onclick="javascript:checkPickOne(this.form);" value="'.&mt('Next').' &rarr;" /><br />'."\n";               'onclick="javascript:checkPickOne(this.form);" value="'.&mt('Next').' &rarr;" /><br />'."\n";
   
     $request->print($result);      $request->print($result);
Line 4939  LISTJAVASCRIPT Line 5225  LISTJAVASCRIPT
  '<th>'.&nameUserString('header').'</th>'.   '<th>'.&nameUserString('header').'</th>'.
  &Apache::loncommon::end_data_table_header_row();   &Apache::loncommon::end_data_table_header_row();
     
     my (undef,undef,$fullname) = &getclasslist($getsec,'1');      my (undef,undef,$fullname) = &getclasslist($getsec,'1',$getgroup);
     my $ptr = 1;      my $ptr = 1;
     foreach my $student (sort       foreach my $student (sort 
  {   {
Line 4967  LISTJAVASCRIPT Line 5253  LISTJAVASCRIPT
     $studentTable.='<input type="button" '.      $studentTable.='<input type="button" '.
                    'onclick="javascript:checkPickOne(this.form);" value="'.&mt('Next').' &rarr;" /></form>'."\n";                     'onclick="javascript:checkPickOne(this.form);" value="'.&mt('Next').' &rarr;" /></form>'."\n";
   
     $studentTable.=&show_grading_menu_form($symb);  
     $request->print($studentTable);      $request->print($studentTable);
   
     return '';      return '';
Line 5004  sub getSymbMap { Line 5289  sub getSymbMap {
 #  #
 #--- Displays a page/sequence w/wo problems, w/wo submissions  #--- Displays a page/sequence w/wo problems, w/wo submissions
 sub displayPage {  sub displayPage {
     my ($request) = shift;      my ($request,$symb) = @_;
   
     my ($symb) = &get_symb($request);  
     my $cdom      = $env{"course.$env{'request.course.id'}.domain"};      my $cdom      = $env{"course.$env{'request.course.id'}.domain"};
     my $cnum      = $env{"course.$env{'request.course.id'}.num"};      my $cnum      = $env{"course.$env{'request.course.id'}.num"};
     my $getsec    = $env{'form.section'} eq '' ? 'all' : $env{'form.section'};      my $getsec    = $env{'form.section'} eq '' ? 'all' : $env{'form.section'};
Line 5023  sub displayPage { Line 5306  sub displayPage {
     &Apache::lonnet::clear_EXT_cache_status();      &Apache::lonnet::clear_EXT_cache_status();
   
     if (!&canview($usec)) {      if (!&canview($usec)) {
  $request->print('<span class="LC_warning">'.   $request->print(
                         &mt('Unable to view requested student. ([_1])',              '<span class="LC_warning">'.
                             $env{'form.student'}).              &mt('Unable to view requested student. ([_1])',
                         '</span>');                  $env{'form.student'}).
         $request->print(&show_grading_menu_form($symb));              '</span>');
         return;          return;
     }      }
     my $result='<h3><span class="LC_info">&nbsp;'.$env{'form.title'}.'</span></h3>';      my $result='<h3><span class="LC_info">&nbsp;'.$env{'form.title'}.'</span></h3>';
Line 5045  sub displayPage { Line 5328  sub displayPage {
     my $navmap = Apache::lonnavmaps::navmap->new();      my $navmap = Apache::lonnavmaps::navmap->new();
     unless (ref($navmap)) {      unless (ref($navmap)) {
         $request->print(&navmap_errormsg());          $request->print(&navmap_errormsg());
         $request->print(&show_grading_menu_form($symb));  
         return;          return;
     }      }
     my ($mapUrl, $id, $resUrl)=&Apache::lonnet::decode_symb($env{'form.page'});      my ($mapUrl, $id, $resUrl)=&Apache::lonnet::decode_symb($env{'form.page'});
     my $map = $navmap->getResourceByUrl($resUrl); # add to navmaps      my $map = $navmap->getResourceByUrl($resUrl); # add to navmaps
     if (!$map) {      if (!$map) {
  $request->print('<span class="LC_warning">'.&mt('Unable to view requested sequence. ([_1])',$resUrl).'</span>');   $request->print('<span class="LC_warning">'.&mt('Unable to view requested sequence. ([_1])',$resUrl).'</span>');
  $request->print(&show_grading_menu_form($symb));  
  return;    return; 
     }      }
     my $iterator = $navmap->getIterator($map->map_start(),      my $iterator = $navmap->getIterator($map->map_start(),
Line 5065  sub displayPage { Line 5346  sub displayPage {
  '<input type="hidden" name="page"    value="'.$pageTitle.'" />'."\n".   '<input type="hidden" name="page"    value="'.$pageTitle.'" />'."\n".
  '<input type="hidden" name="title"   value="'.$env{'form.title'}.'" />'."\n".   '<input type="hidden" name="title"   value="'.$env{'form.title'}.'" />'."\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="overRideScore" value="no" />'."\n".   '<input type="hidden" name="overRideScore" value="no" />'."\n";
  '<input type="hidden" name="saveState" value="'.$env{'form.saveState'}.'" />'."\n";  
   
     if (defined($env{'form.CODE'})) {      if (defined($env{'form.CODE'})) {
  $studentTable.=   $studentTable.=
Line 5080  sub displayPage { Line 5360  sub displayPage {
         '</span>'."\n".          '</span>'."\n".
  &Apache::loncommon::start_data_table().   &Apache::loncommon::start_data_table().
  &Apache::loncommon::start_data_table_header_row().   &Apache::loncommon::start_data_table_header_row().
  '<th align="center">&nbsp;Prob.&nbsp;</th>'.   '<th>'.&mt('Prob.').'</th>'.
  '<th>&nbsp;'.($env{'form.vProb'} eq 'no' ? &mt('Title') : &mt('Problem Text')).'/'.&mt('Grade').'</th>'.   '<th>&nbsp;'.($env{'form.vProb'} eq 'no' ? &mt('Title') : &mt('Problem Text')).'/'.&mt('Grade').'</th>'.
  &Apache::loncommon::end_data_table_header_row();   &Apache::loncommon::end_data_table_header_row();
   
Line 5164  sub displayPage { Line 5444  sub displayPage {
  }   }
         $curRes = $iterator->next();          $curRes = $iterator->next();
     }      }
       my $disabled;
       unless (&canmodify($usec)) {
           $disabled = ' disabled="disabled"';
       }
   
     $studentTable.=      $studentTable.=
         '</table>'."\n".          '</table>'."\n".
         '<input type="button" value="'.&mt('Save').'" '.          '<input type="button" value="'.&mt('Save').'"'.$disabled.' '.
         'onclick="javascript:checkSubmitPage(this.form,'.$question.');" />'.          'onclick="javascript:checkSubmitPage(this.form,'.$question.');" />'.
         '</form>'."\n";          '</form>'."\n";
     $studentTable.=&show_grading_menu_form($symb);  
     $request->print($studentTable);      $request->print($studentTable);
   
     return '';      return '';
Line 5227  sub displaySubByDates { Line 5510  sub displaySubByDates {
             if (($type eq 'anonsurvey') || ($type eq 'anonsurveycred')) {              if (($type eq 'anonsurvey') || ($type eq 'anonsurveycred')) {
                 $hidden = 1;                  $hidden = 1;
             }              }
     my @matchKey = ($isTask ? sort(grep /^resource\.\d+\.\Q$partid\E\.award$/,@versionKeys)      my @matchKey;
             : sort(grep /^resource\.\Q$partid\E\..*?\.submission$/,@versionKeys));              if ($isTask) {
                       @matchKey = sort(grep(/^resource\.\d+\.\Q$partid\E\.award$/,@versionKeys));
               } else {
    @matchKey = sort(grep(/^resource\.\Q$partid\E\..*?\.submission$/,@versionKeys));
               }
 #    next if ($$record{"$version:resource.$partid.solved"} eq '');  #    next if ($$record{"$version:resource.$partid.solved"} eq '');
     my $display_part=&get_display_part($partid,$symb);      my $display_part=&get_display_part($partid,$symb);
     foreach my $matchKey (@matchKey) {      foreach my $matchKey (@matchKey) {
Line 5317  sub displaySubByDates { Line 5603  sub displaySubByDates {
 }  }
   
 sub updateGradeByPage {  sub updateGradeByPage {
     my ($request) = shift;      my ($request,$symb) = @_;
   
     my $cdom      = $env{"course.$env{'request.course.id'}.domain"};      my $cdom      = $env{"course.$env{'request.course.id'}.domain"};
     my $cnum      = $env{"course.$env{'request.course.id'}.num"};      my $cnum      = $env{"course.$env{'request.course.id'}.num"};
Line 5328  sub updateGradeByPage { Line 5614  sub updateGradeByPage {
     my $usec=$classlist->{$env{'form.student'}}[5];      my $usec=$classlist->{$env{'form.student'}}[5];
     if (!&canmodify($usec)) {      if (!&canmodify($usec)) {
  $request->print('<span class="LC_warning">'.&mt('Unable to modify requested student ([_1])',$env{'form.student'}).'</span>');   $request->print('<span class="LC_warning">'.&mt('Unable to modify requested student ([_1])',$env{'form.student'}).'</span>');
  $request->print(&show_grading_menu_form($env{'form.symb'}));  
  return;   return;
     }      }
     my $result='<h3><span class="LC_info">&nbsp;'.$env{'form.title'}.'</span></h3>';      my $result='<h3><span class="LC_info">&nbsp;'.$env{'form.title'}.'</span></h3>';
Line 5347  sub updateGradeByPage { Line 5632  sub updateGradeByPage {
     my $map = $navmap->getResourceByUrl($resUrl); # add to navmaps      my $map = $navmap->getResourceByUrl($resUrl); # add to navmaps
     if (!$map) {      if (!$map) {
  $request->print('<span class="LC_warning">'.&mt('Unable to grade requested sequence ([_1]).',$resUrl).'</span>');   $request->print('<span class="LC_warning">'.&mt('Unable to grade requested sequence ([_1]).',$resUrl).'</span>');
  my ($symb)=&get_symb($request);  
  $request->print(&show_grading_menu_form($symb));  
  return;    return; 
     }      }
     my $iterator = $navmap->getIterator($map->map_start(),      my $iterator = $navmap->getIterator($map->map_start(),
Line 5386  sub updateGradeByPage { Line 5669  sub updateGradeByPage {
     my @displayPts=();      my @displayPts=();
             my %aggregate = ();              my %aggregate = ();
             my $aggregateflag = 0;              my $aggregateflag = 0;
               my %queueable;
             if ($env{'form.HIDE'.$prob}) {              if ($env{'form.HIDE'.$prob}) {
                 my %record = &Apache::lonnet::restore($symbx,$env{'request.course.id'},$udom,$uname);                  my %record = &Apache::lonnet::restore($symbx,$env{'request.course.id'},$udom,$uname);
                 my ($version,$parts) = split(/:/,$env{'form.HIDE'.$prob},2);                  my ($version,$parts) = split(/:/,$env{'form.HIDE'.$prob},2);
Line 5395  sub updateGradeByPage { Line 5679  sub updateGradeByPage {
     foreach my $partid (@{$parts}) {      foreach my $partid (@{$parts}) {
  my $newpts = $env{'form.GD_BOX'.$question.'_'.$partid};   my $newpts = $env{'form.GD_BOX'.$question.'_'.$partid};
  my $oldpts = $env{'form.oldpts'.$question.'_'.$partid};   my $oldpts = $env{'form.oldpts'.$question.'_'.$partid};
                   my @types = $curRes->responseType($partid);
                   if (grep(/^essay$/,@types)) {
                       $queueable{$partid} = 1;
                   } else {
                       my @ids = $curRes->responseIds($partid);
                       for (my $i=0; $i < scalar(@ids); $i++) {
                           my $hndgrd = &Apache::lonnet::EXT('resource.'.$partid.'_'.$ids[$i].
                                                             '.handgrade',$symb);
                           if (lc($hndgrd) eq 'yes') {
                               $queueable{$partid} = 1;
                               last;
                           }
                       }
                   }
  my $wgt = $env{'form.WGT'.$question.'_'.$partid} != 0 ?    my $wgt = $env{'form.WGT'.$question.'_'.$partid} != 0 ? 
     $env{'form.WGT'.$question.'_'.$partid} : 1;      $env{'form.WGT'.$question.'_'.$partid} : 1;
  my $partial = $newpts/$wgt;   my $partial = $newpts/$wgt;
Line 5461  sub updateGradeByPage { Line 5758  sub updateGradeByPage {
    $env{'request.course.id'},     $env{'request.course.id'},
    $udom,$uname);     $udom,$uname);
  &check_and_remove_from_queue($parts,\%record,undef,$symbx,   &check_and_remove_from_queue($parts,\%record,undef,$symbx,
      $cdom,$cnum,$udom,$uname);       $cdom,$cnum,$udom,$uname,\%queueable);
     }      }
           
             if ($aggregateflag) {              if ($aggregateflag) {
Line 5480  sub updateGradeByPage { Line 5777  sub updateGradeByPage {
     }      }
   
     $studentTable.=&Apache::loncommon::end_data_table();      $studentTable.=&Apache::loncommon::end_data_table();
     $studentTable.=&show_grading_menu_form($env{'form.symb'});  
     my $grademsg=($changeflag == 0 ? &mt('No score was changed or updated.') :      my $grademsg=($changeflag == 0 ? &mt('No score was changed or updated.') :
   &mt('The scores were changed for [quant,_1,problem].',    &mt('The scores were changed for [quant,_1,problem].',
   $changeflag).'<br />');    $changeflag).'<br />');
Line 5561  the homework problem. Line 5857  the homework problem.
   
 sub defaultFormData {  sub defaultFormData {
     my ($symb)=@_;      my ($symb)=@_;
     return '<input type="hidden" name="symb"    value="'.&Apache::lonenc::check_encrypt($symb).'" />'."\n".      return '<input type="hidden" name="symb" value="'.&Apache::lonenc::check_encrypt($symb).'" />';
      '<input type="hidden" name="saveState" value="'.$env{'form.saveState'}.'" />'."\n".  
      '<input type="hidden" name="probTitle" value="'.$env{'form.probTitle'}.'" />'."\n";  
 }  }
   
   
Line 5789  sub scantron_CODEunique { Line 6083  sub scantron_CODEunique {
 =cut  =cut
   
 sub scantron_selectphase {  sub scantron_selectphase {
     my ($r,$file2grade) = @_;      my ($r,$file2grade,$symb) = @_;
     my ($symb)=&get_symb($r);  
     if (!$symb) {return '';}      if (!$symb) {return '';}
     my $map_error;      my $map_error;
     my $sequence_selector=&getSequenceDropDown($symb,\$map_error);      my $sequence_selector=&getSequenceDropDown($symb,\$map_error);
Line 5799  sub scantron_selectphase { Line 6092  sub scantron_selectphase {
         return;          return;
     }      }
     my $default_form_data=&defaultFormData($symb);      my $default_form_data=&defaultFormData($symb);
     my $grading_menu_button=&show_grading_menu_form($symb);  
     my $file_selector=&scantron_uploads($file2grade);      my $file_selector=&scantron_uploads($file2grade);
     my $format_selector=&scantron_scantab();      my $format_selector=&scantron_scantab();
     my $CODE_selector=&scantron_CODElist();      my $CODE_selector=&scantron_CODElist();
Line 5815  sub scantron_selectphase { Line 6107  sub scantron_selectphase {
   
         $r->print('          $r->print('
     <br />');      <br />');
     my $default_form_data=&defaultFormData($symb);          my $cdom= $env{'course.'.$env{'request.course.id'}.'.domain'};
     my $cdom= $env{'course.'.$env{'request.course.id'}.'.domain'};          my $cnum= $env{'course.'.$env{'request.course.id'}.'.num'};
     my $cnum= $env{'course.'.$env{'request.course.id'}.'.num'};          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.');          &js_escape(\$alertmsg);
     &js_escape(\$alertmsg);          my ($formatoptions,$formattitle,$formatjs) = &scantron_upload_dataformat($cdom);
     my ($formatoptions,$formattitle,$formatjs) = &scantron_upload_dataformat($cdom);          $r->print(&Apache::lonhtmlcommon::scripttag('
     $r->print(&Apache::lonhtmlcommon::scripttag('  
     function checkUpload(formname) {      function checkUpload(formname) {
         if (formname.upfile.value == "") {          if (formname.upfile.value == "") {
             alert("'.$alertmsg.'");              alert("'.$alertmsg.'");
Line 5829  sub scantron_selectphase { Line 6120  sub scantron_selectphase {
         }          }
         formname.submit();          formname.submit();
     }'."\n".$formatjs));      }'."\n".$formatjs));
     $r->print('          $r->print('
               <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.'
                 <input name="courseid" type="hidden" value="'.$cnum.'" />                  <input name="courseid" type="hidden" value="'.$cnum.'" />
Line 5844  sub scantron_selectphase { Line 6135  sub scantron_selectphase {
               '.&Apache::loncommon::start_data_table_row().'                '.&Apache::loncommon::start_data_table_row().'
             <td>              <td>
                 '.&mt('File to upload: [_1]','<input type="file" name="upfile" size="50" />').'<br />'."\n");                  '.&mt('File to upload: [_1]','<input type="file" name="upfile" size="50" />').'<br />'."\n");
     if ($formatoptions) {          if ($formatoptions) {
         $r->print('</td>              $r->print('</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>'.$formattitle.('&nbsp;'x2).$formatoptions.'                   <td>'.$formattitle.('&nbsp;'x2).$formatoptions.'
Line 5853  sub scantron_selectphase { Line 6144  sub scantron_selectphase {
                  '.&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>'                   <td>'
         );              );
     } else {          } else {
         $r->print(' <br />');              $r->print(' <br />');
     }          }
     $r->print('<input type="button" onclick="javascript:checkUpload(this.form);" value="'.&mt('Upload Bubblesheet Data').'" />          $r->print('<input type="button" onclick="javascript:checkUpload(this.form);" value="'.&mt('Upload Bubblesheet Data').'" />
               </td>                </td>
              '.&Apache::loncommon::end_data_table_row().'               '.&Apache::loncommon::end_data_table_row().'
              '.&Apache::loncommon::end_data_table().'               '.&Apache::loncommon::end_data_table().'
              </form>'               </form>'
     );          );
   
     }      }
   
Line 5971  sub scantron_selectphase { Line 6262  sub scantron_selectphase {
               &Apache::loncommon::end_data_table_row()."\n".                &Apache::loncommon::end_data_table_row()."\n".
               &Apache::loncommon::end_data_table()."\n".                &Apache::loncommon::end_data_table()."\n".
               '</form><br />');                '</form><br />');
     $r->print($grading_menu_button);  
     return;      return;
 }  }
   
Line 6377  sub scantron_parse_scanline { Line 6667  sub scantron_parse_scanline {
 }  }
   
 sub get_master_seq {  sub get_master_seq {
     my ($resources,$master_seq,$symb_to_resource) = @_;      my ($resources,$master_seq,$symb_to_resource,$need_symb_in_map,$symb_for_examcode) = @_;
     return unless ((ref($resources) eq 'ARRAY') && (ref($master_seq) eq 'ARRAY') &&      return unless ((ref($resources) eq 'ARRAY') && (ref($master_seq) eq 'ARRAY') &&
                    (ref($symb_to_resource) eq 'HASH'));                     (ref($symb_to_resource) eq 'HASH'));
       if ($need_symb_in_map) {
           return unless (ref($symb_for_examcode) eq 'HASH');
       }
     my $resource_error;      my $resource_error;
     foreach my $resource (@{$resources}) {      foreach my $resource (@{$resources}) {
         my $ressymb;          my $ressymb;
Line 6387  sub get_master_seq { Line 6680  sub get_master_seq {
             $ressymb = $resource->symb();              $ressymb = $resource->symb();
             push(@{$master_seq},$ressymb);              push(@{$master_seq},$ressymb);
             $symb_to_resource->{$ressymb} = $resource;              $symb_to_resource->{$ressymb} = $resource;
               if ($need_symb_in_map) {
                   unless ($resource->is_map()) {
                       my $map=(&Apache::lonnet::decode_symb($ressymb))[0];
                       unless (exists($symb_for_examcode->{$map})) {
                           $symb_for_examcode->{$map} = $ressymb;
                       }
                   }
               }
         } else {          } else {
             $resource_error = 1;              $resource_error = 1;
             last;              last;
Line 6870  sub check_for_error { Line 7171  sub check_for_error {
 =cut  =cut
   
 sub scantron_warning_screen {  sub scantron_warning_screen {
     my ($button_text)=@_;      my ($button_text,$symb)=@_;
     my $title=&Apache::lonnet::gettitle($env{'form.selectpage'});      my $title=&Apache::lonnet::gettitle($env{'form.selectpage'});
     my %scantron_config=&Apache::lonnet::get_scantron_config($env{'form.scantron_format'});      my %scantron_config=&Apache::lonnet::get_scantron_config($env{'form.scantron_format'});
     my $CODElist;      my $CODElist;
Line 6899  sub scantron_warning_screen { Line 7200  sub scantron_warning_screen {
 <tr><td><b>'.&mt('Data File that will be used:').'</b></td><td><tt>'.$env{'form.scantron_selectfile'}.'</tt></td></tr>  <tr><td><b>'.&mt('Data File that will be used:').'</b></td><td><tt>'.$env{'form.scantron_selectfile'}.'</tt></td></tr>
 '.$CODElist.$lastbubblepoints.'  '.$CODElist.$lastbubblepoints.'
 </table>  </table>
 <br />  <p> '.&mt("If this information is correct, please click on '[_1]'.",&mt($button_text)).'<br />
 <p> '.&mt("If this information is correct, please click on '[_1]'.",&mt($button_text)).'</p>  '.&mt('If something is incorrect, please return to [_1]Grade/Manage/Review Bubblesheets[_2] to start over.','<a href="/adm/grades?symb='.$symb.'&command=scantron_selectphase" class="LC_info">','</a>').'</p>
 <p> '.&mt("If something is incorrect, please click the 'Grading Menu' button to start over.").'</p>  
   
 <br />  <br />
 ');  ');
Line 6917  sub scantron_warning_screen { Line 7217  sub scantron_warning_screen {
 =cut  =cut
   
 sub scantron_do_warning {  sub scantron_do_warning {
     my ($r)=@_;      my ($r,$symb)=@_;
     my ($symb)=&get_symb($r);  
     if (!$symb) {return '';}      if (!$symb) {return '';}
     my $default_form_data=&defaultFormData($symb);      my $default_form_data=&defaultFormData($symb);
     $r->print(&scantron_form_start().$default_form_data);      $r->print(&scantron_form_start().$default_form_data);
Line 6936  sub scantron_do_warning { Line 7235  sub scantron_do_warning {
     $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 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',$symb);
         my $bubbledbyhand=&hand_bubble_option();          my $bubbledbyhand=&hand_bubble_option();
  $r->print('   $r->print('
 '.$warning.$bubbledbyhand.'  '.$warning.$bubbledbyhand.'
Line 6944  sub scantron_do_warning { Line 7243  sub scantron_do_warning {
 <input type="hidden" name="command" value="scantron_validate" />  <input type="hidden" name="command" value="scantron_validate" />
 ');  ');
     }      }
     $r->print("</form><br />".&show_grading_menu_form($symb));      $r->print("</form><br />");
     return '';      return '';
 }  }
   
Line 7002  SCANTRONFORM Line 7301  SCANTRONFORM
 =cut  =cut
   
 sub scantron_validate_file {  sub scantron_validate_file {
     my ($r) = @_;      my ($r,$symb) = @_;
     my ($symb)=&get_symb($r);  
     if (!$symb) {return '';}      if (!$symb) {return '';}
     my $default_form_data=&defaultFormData($symb);      my $default_form_data=&defaultFormData($symb);
           
Line 7066  sub scantron_validate_file { Line 7364  sub scantron_validate_file {
  }   }
     }      }
     if (!$stop) {      if (!$stop) {
  my $warning=&scantron_warning_screen('Start Grading');   my $warning=&scantron_warning_screen('Start Grading',$symb);
  $r->print(&mt('Validation process complete.').'<br />'.   $r->print(&mt('Validation process complete.').'<br />'.
                   $warning.                    $warning.
                   &mt('Perform verification for each student after storage of submissions?').                    &mt('Perform verification for each student after storage of submissions?').
Line 7076  sub scantron_validate_file { Line 7374  sub scantron_validate_file {
                   '<input type="radio" name="verifyrecord" value="0" checked="checked" />'.&mt('No').                    '<input type="radio" name="verifyrecord" value="0" checked="checked" />'.&mt('No').
                   '</label></span><br />'.                    '</label></span><br />'.
                   &mt('Grading will take longer if you use verification.').'<br />'.                    &mt('Grading will take longer if you use verification.').'<br />'.
                   &mt("Alternatively, the 'Review bubblesheet data' utility (see grading menu) can be used for all students after grading is complete.").'<br /><br />'.                    &mt('Otherwise, Grade/Manage/Review Bubblesheets [_1] Review bubblesheet data can be used once grading is complete.','&raquo;').'<br /><br />'.
                   '<input type="submit" name="submit" value="'.&mt('Start Grading').'" />'.                    '<input type="submit" name="submit" value="'.&mt('Start Grading').'" />'.
                   '<input type="hidden" name="command" value="scantron_process" />'."\n");                    '<input type="hidden" name="command" value="scantron_process" />'."\n");
     } else {      } else {
Line 7088  sub scantron_validate_file { Line 7386  sub scantron_validate_file {
     $r->print('<input type="submit" name="submit" value="'.&mt('Ignore').' &rarr; " />');      $r->print('<input type="submit" name="submit" value="'.&mt('Ignore').' &rarr; " />');
     $r->print(' '.&mt('this error').' <br />');      $r->print(' '.&mt('this error').' <br />');
   
     $r->print(" <p>".&mt("Or click the 'Grading Menu' button to start over.")."</p>");              $r->print('<p>'.&mt('Or return to [_1]Grade/Manage/Review Bubblesheets[_2] to start over.','<a href="/adm/grades?symb='.$symb.'&command=scantron_selectphase" class="LC_info">','</a>').'</p>');
  } else {   } else {
             if ($validate_phases[$currentphase] eq 'doublebubble' || $validate_phases[$currentphase] eq 'missingbubbles') {              if ($validate_phases[$currentphase] eq 'doublebubble' || $validate_phases[$currentphase] eq 'missingbubbles') {
         $r->print('<input type="button" name="submitbutton" value="'.&mt('Continue').' &rarr;" onclick="javascript:verify_bubble_radio(this.form)" />');          $r->print('<input type="button" name="submitbutton" value="'.&mt('Continue').' &rarr;" onclick="javascript:verify_bubble_radio(this.form)" />');
Line 7100  sub scantron_validate_file { Line 7398  sub scantron_validate_file {
     $r->print(" ".&mt("this scanline saving it for later."));      $r->print(" ".&mt("this scanline saving it for later."));
  }   }
     }      }
     $r->print(" </form><br />".&show_grading_menu_form($symb));      $r->print(" </form><br />");
     return '';      return '';
 }  }
   
Line 7651  sub scantron_get_correction { Line 7949  sub scantron_get_correction {
     $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 7660  function change_radio(field) { Line 7957  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 7739  sub verify_bubbles_checked { Line 8035  sub verify_bubbles_checked {
     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.");
     &js_escape(\$warning);      &js_escape(\$warning);
     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 7763  function verify_bubble_radio(form) { Line 8058  function verify_bubble_radio(form) {
     }      }
     form.submit();       form.submit(); 
 }  }
 </script>  
 ENDSCRIPT  ENDSCRIPT
     return $output;      return $output;
 }  }
Line 8210  sub scantron_validate_doublebubble { Line 8504  sub scantron_validate_doublebubble {
     if (ref($map)) {      if (ref($map)) {
         $randomorder = $map->randomorder();          $randomorder = $map->randomorder();
         $randompick = $map->randompick();          $randompick = $map->randompick();
           unless ($randomorder || $randompick) {
               foreach my $res ($navmap->retrieveResources($map,sub { $_[0]->is_map() },1,0,1)) {
                   if ($res->randomorder()) {
                       $randomorder = 1;
                   }
                   if ($res->randompick()) {
                       $randompick = 1;
                   }
                   last if ($randomorder || $randompick);
               }
           }
         if ($randomorder || $randompick) {          if ($randomorder || $randompick) {
             $nav_error = &get_master_seq(\@resources,\@master_seq,\%symb_to_resource);              $nav_error = &get_master_seq(\@resources,\@master_seq,\%symb_to_resource);
             if ($nav_error) {              if ($nav_error) {
Line 8393  sub scantron_validate_missingbubbles { Line 8698  sub scantron_validate_missingbubbles {
     if (ref($map)) {      if (ref($map)) {
         $randomorder = $map->randomorder();          $randomorder = $map->randomorder();
         $randompick = $map->randompick();          $randompick = $map->randompick();
           unless ($randomorder || $randompick) {
               foreach my $res ($navmap->retrieveResources($map,sub { $_[0]->is_map() },1,0,1)) {
                   if ($res->randomorder()) {
                       $randomorder = 1;
                   }
                   if ($res->randompick()) {
                       $randompick = 1;
                   }
                   last if ($randomorder || $randompick);
               }
           }
         if ($randomorder || $randompick) {          if ($randomorder || $randompick) {
             $nav_error = &get_master_seq(\@resources,\@master_seq,\%symb_to_resource);              $nav_error = &get_master_seq(\@resources,\@master_seq,\%symb_to_resource);
             if ($nav_error) {              if ($nav_error) {
Line 8514  sub hand_bubble_option { Line 8830  sub hand_bubble_option {
 }  }
   
 sub scantron_process_students {  sub scantron_process_students {
     my ($r) = @_;      my ($r,$symb) = @_;
   
     my (undef,undef,$sequence)=&Apache::lonnet::decode_symb($env{'form.selectpage'});      my (undef,undef,$sequence)=&Apache::lonnet::decode_symb($env{'form.selectpage'});
     my ($symb)=&get_symb($r);  
     if (!$symb) {      if (!$symb) {
  return '';   return '';
     }      }
Line 8535  sub scantron_process_students { Line 8850  sub scantron_process_students {
     }      }
     my $map=$navmap->getResourceByUrl($sequence);      my $map=$navmap->getResourceByUrl($sequence);
     my ($randomorder,$randompick,@master_seq,%symb_to_resource,%grader_partids_by_symb,      my ($randomorder,$randompick,@master_seq,%symb_to_resource,%grader_partids_by_symb,
         %grader_randomlists_by_symb);          %grader_randomlists_by_symb,%symb_for_examcode);
     if (ref($map)) {      if (ref($map)) {
         $randomorder = $map->randomorder();          $randomorder = $map->randomorder();
         $randompick = $map->randompick();          $randompick = $map->randompick();
           unless ($randomorder || $randompick) {
               foreach my $res ($navmap->retrieveResources($map,sub { $_[0]->is_map() },1,0,1)) {
                   if ($res->randomorder()) {
                       $randomorder = 1;
                   }
                   if ($res->randompick()) {
                       $randompick = 1;
                   }
                   last if ($randomorder || $randompick);
               }
           }
     } else {      } else {
         $r->print(&navmap_errormsg());          $r->print(&navmap_errormsg());
         return '';          return '';
Line 8546  sub scantron_process_students { Line 8872  sub scantron_process_students {
     my $nav_error;      my $nav_error;
     my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0);      my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0);
     if ($randomorder || $randompick) {      if ($randomorder || $randompick) {
         $nav_error = &get_master_seq(\@resources,\@master_seq,\%symb_to_resource);          $nav_error = &get_master_seq(\@resources,\@master_seq,\%symb_to_resource,1,\%symb_for_examcode);
         if ($nav_error) {          if ($nav_error) {
             $r->print(&navmap_errormsg());              $r->print(&navmap_errormsg());
             return '';              return '';
Line 8569  SCANTRONFORM Line 8895  SCANTRONFORM
     my $lock=&Apache::lonnet::set_lock(&mt('Grading bubblesheet exam'));      my $lock=&Apache::lonnet::set_lock(&mt('Grading bubblesheet exam'));
     my $count=&get_todo_count($scanlines,$scan_data);      my $count=&get_todo_count($scanlines,$scan_data);
     my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,$count);      my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,$count);
     &Apache::lonhtmlcommon::Update_PrgWin($r,\%prog_state,      &Apache::lonhtmlcommon::Update_PrgWin($r,\%prog_state,'Processing first student');
   'Processing first student');  
     $r->print('<br />');      $r->print('<br />');
     my $start=&Time::HiRes::time();      my $start=&Time::HiRes::time();
     my $i=-1;      my $i=-1;
Line 8588  SCANTRONFORM Line 8913  SCANTRONFORM
     if ($ssi_error) {      if ($ssi_error) {
  $r->print("</form>");   $r->print("</form>");
  &ssi_print_error($r);   &ssi_print_error($r);
  $r->print(&show_grading_menu_form($symb));  
         &Apache::lonnet::remove_lock($lock);          &Apache::lonnet::remove_lock($lock);
  return ''; # Dunno why the other returns return '' rather than just returning.   return ''; # Dunno why the other returns return '' rather than just returning.
     }      }
Line 8603  SCANTRONFORM Line 8927  SCANTRONFORM
   my $line=&scantron_get_line($scanlines,$scan_data,$i);    my $line=&scantron_get_line($scanlines,$scan_data,$i);
   if ($line=~/^[\s\cz]*$/) { next; }    if ($line=~/^[\s\cz]*$/) { next; }
  if ($started) {   if ($started) {
     &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,      &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,'last student');
      'last student');  
  }   }
  $started=1;   $started=1;
         my %respnumlookup = ();          my %respnumlookup = ();
Line 8691  SCANTRONFORM Line 9014  SCANTRONFORM
             $ssi_error = 0; # So end of handler error message does not trigger.              $ssi_error = 0; # So end of handler error message does not trigger.
             $r->print("</form>");              $r->print("</form>");
             &ssi_print_error($r);              &ssi_print_error($r);
             $r->print(&show_grading_menu_form($symb));  
             &Apache::lonnet::remove_lock($lock);              &Apache::lonnet::remove_lock($lock);
             return '';      # Why return ''?  Beats me.              return '';      # Why return ''?  Beats me.
         }          }
   
         if (($scancode) && ($randomorder || $randompick)) {          if (($scancode) && ($randomorder || $randompick)) {
             my $parmresult =              foreach my $key (keys(%symb_for_examcode)) {
                 &Apache::lonparmset::storeparm_by_symb($symb,                  my $symb_in_map = $symb_for_examcode{$key};
                                                        '0_examcode',2,$scancode,                  if ($symb_in_map ne '') {
                                                        'string_examcode',$uname,                      my $parmresult =
                                                        $udom);                          &Apache::lonparmset::storeparm_by_symb($symb_in_map,
                                                                  '0_examcode',2,$scancode,
                                                                  'string_examcode',$uname,
                                                                  $udom);
                   }
               }
         }          }
  $completedstudents{$uname}={'line'=>$line};   $completedstudents{$uname}={'line'=>$line};
         if ($env{'form.verifyrecord'}) {          if ($env{'form.verifyrecord'}) {
Line 8736  SCANTRONFORM Line 9063  SCANTRONFORM
                     $ssi_error = 0; # So end of handler error message does not trigger.                      $ssi_error = 0; # So end of handler error message does not trigger.
                     $r->print("</form>");                      $r->print("</form>");
                     &ssi_print_error($r);                      &ssi_print_error($r);
                     $r->print(&show_grading_menu_form($symb));  
                     &Apache::lonnet::remove_lock($lock);                      &Apache::lonnet::remove_lock($lock);
                     delete($completedstudents{$uname});                      delete($completedstudents{$uname});
                     return '';                      return '';
Line 8794  SCANTRONFORM Line 9120  SCANTRONFORM
 #    $r->print("<p>took $lasttime</p>");  #    $r->print("<p>took $lasttime</p>");
   
     $r->print("</form>");      $r->print("</form>");
     $r->print(&show_grading_menu_form($symb));  
     return '';      return '';
 }  }
   
Line 8922  sub grade_student_bubbles { Line 9247  sub grade_student_bubbles {
 }  }
   
 sub scantron_upload_scantron_data {  sub scantron_upload_scantron_data {
     my ($r)=@_;      my ($r,$symb) = @_;
     my $dom = $env{'request.role.domain'};      my $dom = $env{'request.role.domain'};
     my ($formatoptions,$formattitle,$formatjs) = &scantron_upload_dataformat($dom);      my ($formatoptions,$formattitle,$formatjs) = &scantron_upload_dataformat($dom);
     my $domdesc = &Apache::lonnet::domain($dom,'description');      my $domdesc = &Apache::lonnet::domain($dom,'description');
Line 8932  sub scantron_upload_scantron_data { Line 9257  sub scantron_upload_scantron_data {
   'coursename',$dom);    'coursename',$dom);
     my $syllabuslink = '<a href="javascript:ToSyllabus();">'.&mt('Syllabus').'</a>'.      my $syllabuslink = '<a href="javascript:ToSyllabus();">'.&mt('Syllabus').'</a>'.
                        ('&nbsp'x2).&mt('(shows course personnel)');                         ('&nbsp'x2).&mt('(shows course personnel)');
     my ($symb) = &get_symb($r,1);  
     my $default_form_data=&defaultFormData($symb);      my $default_form_data=&defaultFormData($symb);
     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.');
     &js_escape(\$nofile_alert);      &js_escape(\$nofile_alert);
Line 9026  END Line 9350  END
                             if ($count > 1) {                              if ($count > 1) {
                                 $formatextra = '<div style="display:none" id="bubbletype">'.                                  $formatextra = '<div style="display:none" id="bubbletype">'.
                                                '<span class="LC_nobreak">'.                                                 '<span class="LC_nobreak">'.
                                                &mt('Bubblesheet type:').'&nbsp;'.                                                 &mt('Bubblesheet type').':&nbsp;'.
                                                &scantron_scantab().'</span></div>';                                                 &scantron_scantab().'</span></div>';
                                 $onclick = ' onclick="toggleScantab(this.form);"';                                  $onclick = ' onclick="toggleScantab(this.form);"';
                                 $formatjs = <<"END";                                  $formatjs = <<"END";
Line 9079  END Line 9403  END
 }  }
   
 sub scantron_upload_scantron_data_save {  sub scantron_upload_scantron_data_save {
     my($r)=@_;      my ($r,$symb) = @_;
     my ($symb)=&get_symb($r,1);  
     my $doanotherupload=      my $doanotherupload=
  '<br /><form action="/adm/grades" method="post">'."\n".   '<br /><form action="/adm/grades" method="post">'."\n".
  '<input type="hidden" name="command" value="scantronupload" />'."\n".   '<input type="hidden" name="command" value="scantronupload" />'."\n".
Line 9090  sub scantron_upload_scantron_data_save { Line 9413  sub scantron_upload_scantron_data_save {
  !&Apache::lonnet::allowed('usc',   !&Apache::lonnet::allowed('usc',
     $env{'form.domainid'}.'_'.$env{'form.courseid'})) {      $env{'form.domainid'}.'_'.$env{'form.courseid'})) {
  $r->print(&mt("You are not allowed to upload bubblesheet data to the requested course.")."<br />");   $r->print(&mt("You are not allowed to upload bubblesheet data to the requested course.")."<br />");
  if ($symb) {          unless ($symb) {
     $r->print(&show_grading_menu_form($symb));  
  } else {  
     $r->print($doanotherupload);      $r->print($doanotherupload);
  }   }
  return '';   return '';
Line 9157  sub scantron_upload_scantron_data_save { Line 9478  sub scantron_upload_scantron_data_save {
  }   }
     }      }
     if ($symb) {      if ($symb) {
  $r->print(&scantron_selectphase($r,$uploadedfile));   $r->print(&scantron_selectphase($r,$uploadedfile,$symb));
     } else {      } else {
  $r->print($doanotherupload);   $r->print($doanotherupload);
     }      }
Line 9283  sub valid_file { Line 9604  sub valid_file {
 }  }
   
 sub scantron_download_scantron_data {  sub scantron_download_scantron_data {
     my ($r)=@_;      my ($r,$symb) = @_;
     my ($symb) = &get_symb($r,1);  
     my $default_form_data=&defaultFormData($symb);      my $default_form_data=&defaultFormData($symb);
     my $cname=$env{'course.'.$env{'request.course.id'}.'.num'};      my $cname=$env{'course.'.$env{'request.course.id'}.'.num'};
     my $cdom=$env{'course.'.$env{'request.course.id'}.'.domain'};      my $cdom=$env{'course.'.$env{'request.course.id'}.'.domain'};
Line 9295  sub scantron_download_scantron_data { Line 9615  sub scantron_download_scantron_data {
     '.&mt('The requested filename was invalid.').'      '.&mt('The requested filename was invalid.').'
         </p>          </p>
 ');  ');
  $r->print(&show_grading_menu_form($symb));  
  return;   return;
     }      }
     my $orig='/uploaded/'.$cdom.'/'.$cname.'/scantron_orig_'.$file;      my $orig='/uploaded/'.$cdom.'/'.$cname.'/scantron_orig_'.$file;
Line 9306  sub scantron_download_scantron_data { Line 9625  sub scantron_download_scantron_data {
     &Apache::lonnet::allowuploaded('/adm/grades',$skipped);      &Apache::lonnet::allowuploaded('/adm/grades',$skipped);
     $r->print('      $r->print('
     <p>      <p>
  '.&mt('[_1]Original[_2] file as uploaded by bubblesheet scanning office.',   '.&mt('[_1]Original[_2] file as uploaded by the bubblesheet scanning office.',
       '<a href="'.$orig.'">','</a>').'        '<a href="'.$orig.'">','</a>').'
     </p>      </p>
     <p>      <p>
Line 9318  sub scantron_download_scantron_data { Line 9637  sub scantron_download_scantron_data {
       '<a href="'.$skipped.'">','</a>').'        '<a href="'.$skipped.'">','</a>').'
     </p>      </p>
 ');  ');
     $r->print(&show_grading_menu_form($symb));  
     return '';      return '';
 }  }
   
 sub checkscantron_results {  sub checkscantron_results {
     my ($r) = @_;      my ($r,$symb) = @_;
     my ($symb)=&get_symb($r);  
     if (!$symb) {return '';}      if (!$symb) {return '';}
     my $grading_menu_button=&show_grading_menu_form($symb);  
     my $cid = $env{'request.course.id'};      my $cid = $env{'request.course.id'};
     my %lettdig = &Apache::lonnet::letter_to_digits();      my %lettdig = &Apache::lonnet::letter_to_digits();
     my $numletts = scalar(keys(%lettdig));      my $numletts = scalar(keys(%lettdig));
Line 9351  sub checkscantron_results { Line 9667  sub checkscantron_results {
     if (ref($map)) {      if (ref($map)) {
         $randomorder=$map->randomorder();          $randomorder=$map->randomorder();
         $randompick=$map->randompick();          $randompick=$map->randompick();
           unless ($randomorder || $randompick) {
               foreach my $res ($navmap->retrieveResources($map,sub { $_[0]->is_map() },1,0,1)) {
                   if ($res->randomorder()) {
                       $randomorder = 1;
                   }
                   if ($res->randompick()) {
                       $randompick = 1;
                   }
                   last if ($randomorder || $randompick);
               }
           }
     }      }
     my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0);      my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0);
     my $nav_error = &get_master_seq(\@resources,\@master_seq,\%symb_to_resource);      my $nav_error = &get_master_seq(\@resources,\@master_seq,\%symb_to_resource);
Line 9533  sub checkscantron_results { Line 9860  sub checkscantron_results {
                  &Apache::loncommon::end_data_table()).'<br />'.                   &Apache::loncommon::end_data_table()).'<br />'.
                  &mt('Differences can occur if submissions were modified using manual grading after a bubblesheet grading pass.').'<br />'.&mt('If unexpected discrepancies were detected, it is recommended that you inspect the original bubblesheets.');                     &mt('Differences can occur if submissions were modified using manual grading after a bubblesheet grading pass.').'<br />'.&mt('If unexpected discrepancies were detected, it is recommended that you inspect the original bubblesheets.');  
     }      }
     $r->print('</form><br />'.$grading_menu_button);      $r->print('</form><br />');
     return;      return;
 }  }
   
Line 9665  sub verify_scantron_grading { Line 9992  sub verify_scantron_grading {
   
 #-------------------------- Menu interface -------------------------  #-------------------------- Menu interface -------------------------
 #  #
 #--- Show a Grading Menu button - Calls the next routine ---  
 sub show_grading_menu_form {  
     my ($symb)=@_;  
     my $result.='<br /><form action="/adm/grades" method="post">'."\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="command" value="gradingmenu" />'."\n".  
  '<input type="submit" name="submit" value="'.&mt('Grading Menu').'" />'."\n".  
  '</form>'."\n";  
     return $result;  
 }  
   
 # -- Retrieve choices for grading form  
 sub savedState {  
     my %savedState = ();  
     if ($env{'form.saveState'}) {  
  foreach (split(/:/,$env{'form.saveState'})) {  
     my ($key,$value) = split(/=/,$_,2);  
     $savedState{$key} = $value;  
  }  
     }  
     return \%savedState;  
 }  
   
 #--- Href with symb and command ---  #--- Href with symb and command ---
   
 sub href_symb_cmd {  sub href_symb_cmd {
Line 9697  sub href_symb_cmd { Line 10000  sub href_symb_cmd {
 }  }
   
 sub grading_menu {  sub grading_menu {
     my ($request) = @_;      my ($request,$symb) = @_;
     my ($symb)=&get_symb($request);  
     if (!$symb) {return '';}      if (!$symb) {return '';}
     my $probTitle = &Apache::lonnet::gettitle($symb);  
     my ($table,undef,$hdgrade) = &showResourceInfo($symb,$probTitle);  
   
     $request->print($table);  
     my %fields = ('symb'=>&Apache::lonenc::check_encrypt($symb),      my %fields = ('symb'=>&Apache::lonenc::check_encrypt($symb),
                   'handgrade'=>$hdgrade,                    'command'=>'individual');
                   'probTitle'=>$probTitle,  
                   'command'=>'submit_options',      my $url1a = &Apache::lonhtmlcommon::build_url('grades/',\%fields);
                   'saveState'=>"",  
                   'gradingMenu'=>1,      $fields{'command'}='ungraded';
                   'showgrading'=>"yes");      my $url1b=&Apache::lonhtmlcommon::build_url('grades/',\%fields);
       
     my $url1 = &Apache::lonhtmlcommon::build_url('grades/',\%fields);      $fields{'command'}='table';
       my $url1c=&Apache::lonhtmlcommon::build_url('grades/',\%fields);
   
       $fields{'command'}='all_for_one';
       my $url1d=&Apache::lonhtmlcommon::build_url('grades/',\%fields);
   
       $fields{'command'}='downloadfilesselect';
       my $url1e=&Apache::lonhtmlcommon::build_url('grades/',\%fields);
           
     $fields{'command'} = 'csvform';      $fields{'command'} = 'csvform';
     my $url2 = &Apache::lonhtmlcommon::build_url('grades/',\%fields);      my $url2 = &Apache::lonhtmlcommon::build_url('grades/',\%fields);
Line 9722  sub grading_menu { Line 10028  sub grading_menu {
           
     $fields{'command'} = 'scantron_selectphase';      $fields{'command'} = 'scantron_selectphase';
     my $url4 = &Apache::lonhtmlcommon::build_url('grades/',\%fields);      my $url4 = &Apache::lonhtmlcommon::build_url('grades/',\%fields);
       
     my @menu = ({ categorytitle=>'Course Grading',      $fields{'command'} = 'initialverifyreceipt';
       my $url5 = &Apache::lonhtmlcommon::build_url('grades/',\%fields);
   
       my %permissions;
       if ($perm{'mgr'}) {
           $permissions{'either'} = 'F';
           $permissions{'mgr'} = 'F';
       }
       if ($perm{'vgr'}) {
           $permissions{'either'} = 'F';
           $permissions{'vgr'} = 'F';
       }
   
       my @menu = ({ categorytitle=>'Hand Grading',
             items =>[              items =>[
                         { linktext => 'Manual Grading/View Submissions',                          {       linktext => 'Select individual students to grade',
                     url => $url1,                                  url => $url1a,
                     permission => 'F',                                  permission => $permissions{'either'},
                     icon => 'edit-find-replace.png',                                  icon => 'grade_students.png',
                     linktitle => 'Start the process of hand grading submissions.'                                  linktitle => 'Grade current resource for a selection of students.'
                           },
                           {       linktext => 'Grade ungraded submissions',
                                   url => $url1b,
                                   permission => $permissions{'either'},
                                   icon => 'ungrade_sub.png',
                                   linktitle => 'Grade all submissions that have not been graded yet.'
                           },
   
                           {       linktext => 'Grading table',
                                   url => $url1c,
                                   permission => $permissions{'either'},
                                   icon => 'grading_table.png',
                                   linktitle => 'Grade current resource for all students.'
                           },
                           {       linktext => 'Grade page/folder for one student',
                                   url => $url1d,
                                   permission => $permissions{'either'},
                                   icon => 'grade_PageFolder.png',
                                   linktitle => 'Grade all resources in current page/sequence/folder for one student.'
                         },                          },
                           {       linktext => 'Download submitted files',
                                   url => $url1e,
                                   permission => $permissions{'either'},
                                   icon => 'download_sub.png',
                                   linktitle => 'Download all files submitted by students.'
                           }]},
                            { categorytitle=>'Automated Grading',
                  items =>[
   
                    { linktext => 'Upload Scores',                     { linktext => 'Upload Scores',
                     url => $url2,                      url => $url2,
                     permission => 'F',                      permission => $permissions{'mgr'},
                     icon => 'uploadscores.png',                      icon => 'uploadscores.png',
                     linktitle => 'Specify a file containing the class scores for current resource.'                      linktitle => 'Specify a file containing the class scores for current resource.'
                    },                     },
                    { linktext => 'Process Clicker',                     { linktext => 'Process Clicker',
                     url => $url3,                      url => $url3,
                     permission => 'F',                      permission => $permissions{'mgr'},
                     icon => 'addClickerInfoFile.png',                      icon => 'addClickerInfoFile.png',
                     linktitle => 'Specify a file containing the clicker information for this resource.'                      linktitle => 'Specify a file containing the clicker information for this resource.'
                    },                     },
                    { linktext => 'Grade/Manage/Review Bubblesheets',                     { linktext => 'Grade/Manage/Review Bubblesheets',
                     url => $url4,                      url => $url4,
                     permission => 'F',                      permission => $permissions{'mgr'},
                     icon => 'stat.png',                      icon => 'bubblesheet.png',
                     linktitle => 'Grade bubblesheet exams, upload/download bubblesheet data files, and review previously graded bubblesheet exams.'                      linktitle => 'Grade bubblesheet exams, upload/download bubblesheet data files, and review previously graded bubblesheet exams.'
                    }                     },
                               {   linktext => 'Verify Receipt Number',
                                   url => $url5,
                                   permission => $permissions{'either'},
                                   icon => 'receipt_number.png',
                                   linktitle => 'Verify a system-generated receipt number for correct problem solution.'
                               }
   
                     ]                      ]
             });              });
   
     #$fields{'command'} = 'verify';  
     #$url = &Apache::lonhtmlcommon::build_url('grades/',\%fields);  
     #  
     # Create the menu      # Create the menu
     my $Str;      my $Str;
     # $Str .= '<h2>'.&mt('Please select a grading task').'</h2>';  
     $Str .= '<form method="post" action="" name="gradingMenu">';      $Str .= '<form method="post" action="" name="gradingMenu">';
     $Str .= '<input type="hidden" name="command" value="" />'.      $Str .= '<input type="hidden" name="command" value="" />'.
     '<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="handgrade"   value="'.$hdgrade.'" />'."\n".  
  '<input type="hidden" name="probTitle"   value="'.$probTitle.'" />'."\n".  
  '<input type="hidden" name="saveState"   value="" />'."\n".  
  '<input type="hidden" name="gradingMenu" value="1" />'."\n".  
  '<input type="hidden" name="showgrading" value="yes" />'."\n";  
   
     $Str .= Apache::lonhtmlcommon::generate_menu(@menu);  
     #$menudata->{'jscript'}  
     $Str .='<hr /><input type="button" value="'.&mt('Verify Receipt No.').'" '.  
         ' onclick="javascript:checkChoice(document.forms.gradingMenu,\'5\',\'verify\')" '.  
         ' /> '.  
         &Apache::lonnet::recprefix($env{'request.course.id'}).  
         '-<input type="text" name="receipt" size="4" onchange="javascript:checkReceiptNo(this.form,\'OK\')" />';  
   
     $Str .="</form>\n";      $Str .= &Apache::lonhtmlcommon::generate_menu(@menu);
     my $receiptalert = &mt("Please enter a receipt number given by a student in the receipt box.");  
     $request->print(<<GRADINGMENUJS);  
 <script type="text/javascript" language="javascript">  
     function checkChoice(formname,val,cmdx) {  
  if (val <= 2) {  
     var cmd = radioSelection(formname.radioChoice);  
     var cmdsave = cmd;  
  } else {  
     cmd = cmdx;  
     cmdsave = 'submission';  
  }  
  formname.command.value = cmd;  
  if (val < 5) formname.submit();  
  if (val == 5) {  
     if (!checkReceiptNo(formname,'notOK')) {   
         return false;  
     } else {  
         formname.submit();  
     }  
  }  
     }  
   
     function checkReceiptNo(formname,nospace) {  
  var receiptNo = formname.receipt.value;  
  var checkOpt = false;  
  if (nospace == "OK" && isNaN(receiptNo)) {checkOpt = true;}  
  if (nospace == "notOK" && (isNaN(receiptNo) || receiptNo == "")) {checkOpt = true;}  
  if (checkOpt) {  
     alert("$receiptalert");  
     formname.receipt.value = "";  
     formname.receipt.focus();  
     return false;  
  }  
  return true;  
     }  
 </script>  
 GRADINGMENUJS  
     &commonJSfunctions($request);  
     return $Str;          return $Str;    
 }  }
   
   sub ungraded {
       my ($request)=@_;
       &submit_options($request);
   }
   
 #--- Displays the submissions first page -------  sub submit_options_sequence {
 sub submit_options {      my ($request,$symb) = @_;
     my ($request) = @_;  
     my ($symb)=&get_symb($request);  
     if (!$symb) {return '';}      if (!$symb) {return '';}
     my $probTitle = &Apache::lonnet::gettitle($symb);      &commonJSfunctions($request);
       my $result;
   
     my $receiptalert = &mt("Please enter a receipt number given by a student in the receipt box.");       $result.='<form action="/adm/grades" method="post" name="gradingMenu">'."\n".
     $request->print(<<GRADINGMENUJS);          '<input type="hidden" name="symb"        value="'.&Apache::lonenc::check_encrypt($symb).'" />'."\n";
 <script type="text/javascript" language="javascript">      $result.=&selectfield(0).
     function checkChoice(formname,val,cmdx) {              '<input type="hidden" name="command" value="pickStudentPage" />
  if (val <= 2) {              <div>
     var cmd = radioSelection(formname.radioChoice);                <input type="submit" value="'.&mt('Next').' &rarr;" />
     var cmdsave = cmd;              </div>
  } else {          </div>
     cmd = cmdx;    </form>';
     cmdsave = 'submission';      return $result;
  }  }
  formname.command.value = cmd;  
  formname.saveState.value = "saveCmd="+cmdsave+":saveSec="+pullDownSelection(formname.section)+  sub submit_options_table {
     ":saveSub="+pullDownSelection(formname.submitonly)+":saveStatus="+pullDownSelection(formname.Status);      my ($request,$symb) = @_;
  if (val < 5) formname.submit();      if (!$symb) {return '';}
  if (val == 5) {  
     if (!checkReceiptNo(formname,'notOK')) { return false;}  
     formname.submit();  
  }  
  if (val < 7) formname.submit();  
     }  
   
     function checkReceiptNo(formname,nospace) {  
  var receiptNo = formname.receipt.value;  
  var checkOpt = false;  
  if (nospace == "OK" && isNaN(receiptNo)) {checkOpt = true;}  
  if (nospace == "notOK" && (isNaN(receiptNo) || receiptNo == "")) {checkOpt = true;}  
  if (checkOpt) {  
     alert("$receiptalert");  
     formname.receipt.value = "";  
     formname.receipt.focus();  
     return false;  
  }  
  return true;  
     }  
 </script>  
 GRADINGMENUJS  
     &commonJSfunctions($request);      &commonJSfunctions($request);
     my ($table,undef,$hdgrade) = &showResourceInfo($symb,$probTitle);  
     my $result;      my $result;
     my (undef,$sections) = &getclasslist('all','0');  
     my $savedState = &savedState();      $result.='<form action="/adm/grades" method="post" name="gradingMenu">'."\n".
     my $saveCmd = ($$savedState{'saveCmd'} eq '' ? 'submission' : $$savedState{'saveCmd'});          '<input type="hidden" name="symb"        value="'.&Apache::lonenc::check_encrypt($symb).'" />'."\n";
     my $saveSec = ($$savedState{'saveSec'} eq '' ? 'all' : $$savedState{'saveSec'});  
     my $saveSub = ($$savedState{'saveSub'} eq '' ? 'all' : $$savedState{'saveSub'});      $result.=&selectfield(1).
     my $saveStatus = ($$savedState{'saveStatus'} eq '' ? 'Active' : $$savedState{'saveStatus'});              '<input type="hidden" name="command" value="viewgrades" />
               <div>
     # Preselect sections                <input type="submit" value="'.&mt('Next').' &rarr;" />
     my $selsec="";              </div>
     if (ref($sections)) {          </div>
         foreach my $section (sort(@$sections)) {    </form>';
             $selsec.='<option value="'.$section.'" '.      return $result;
                 ($saveSec eq $section ? 'selected="selected"':'').'>'.$section.'</option>'."\n";  }
   
   sub submit_options_download {
       my ($request,$symb) = @_;
       if (!$symb) {return '';}
   
       my $res_error;
       my ($partlist,$handgrade,$responseType,$numresp,$numessay,$numdropbox) =
           &response_type($symb,\$res_error);
       if ($res_error) {
           $request->print(&mt('An error occurred retrieving response types'));
           return;
       }
       unless ($numessay) {
           $request->print(&mt('No essayresponse items found'));
           return;
       }
       my $table;
       if (ref($partlist) eq 'ARRAY') {
           if (scalar(@$partlist) > 1 ) {
               $table = &showResourceInfo($symb,$partlist,$responseType,'gradingMenu',1,1);
         }          }
     }      }
   
     $result.='<form action="/adm/grades" method="post" name="gradingMenu">'."\n".      &commonJSfunctions($request);
  '<input type="hidden" name="symb"        value="'.&Apache::lonenc::check_encrypt($symb).'" />'."\n".  
  '<input type="hidden" name="handgrade"   value="'.$hdgrade.'" />'."\n".  
  '<input type="hidden" name="probTitle"   value="'.$probTitle.'" />'."\n".  
  '<input type="hidden" name="command"     value="" />'."\n".  
  '<input type="hidden" name="saveState"   value="" />'."\n".  
  '<input type="hidden" name="gradingMenu" value="1" />'."\n".  
  '<input type="hidden" name="showgrading" value="yes" />'."\n";  
   
       my $result='<form action="/adm/grades" method="post" name="gradingMenu">'."\n".
           $table."\n".
           '<input type="hidden" name="symb" value="'.&Apache::lonenc::check_encrypt($symb).'" />'."\n";
     $result.='      $result.='
 <h2>  <h2>
   '.&mt('Grade Current Resource').'    '.&mt('Select Students for whom to Download Submitted Files').'
 </h2>  </h2>'.&selectfield(1).'
 <div>                  <input type="hidden" name="command" value="downloadfileslink" />
   '.$table.'                <input type="submit" value="'.&mt('Next').' &rarr;" />
 </div>              </div>
             </div>
   
   
     </form>';
       return $result;
   }
   
   #--- Displays the submissions first page -------
   sub submit_options {
       my ($request,$symb) = @_;
       if (!$symb) {return '';}
   
       &commonJSfunctions($request);
       my $result;
   
       $result.='<form action="/adm/grades" method="post" name="gradingMenu">'."\n".
    '<input type="hidden" name="symb"        value="'.&Apache::lonenc::check_encrypt($symb).'" />'."\n";
       $result.=&selectfield(1).'
                   <input type="hidden" name="command" value="submission" />
                 <input type="submit" value="'.&mt('Next').' &rarr;" />
               </div>
             </div>
     </form>';
       return $result;
   }
   
   sub selectfield {
      my ($full)=@_;
      my %options =
          (&substatus_options,
           'select_form_order' => ['yes','queued','graded','incorrect','all']);
   
     #
     # PrepareClasslist() needs to be called to avoid getting a sections list
     # for a different course from the @Sections global in lonstatistics.pm,
     # populated by an earlier request.
     #
      &Apache::lonstatistics::PrepareClasslist();
   
      my $result='<div class="LC_columnSection">
   
 <div class="LC_columnSection">  
     
     <fieldset>      <fieldset>
       <legend>        <legend>
        '.&mt('Sections').'         '.&mt('Sections').'
       </legend>        </legend>
       <select name="section" multiple="multiple" size="5">'."\n";        '.&Apache::lonstatistics::SectionSelect('section','multiple',5).'
     $result.= $selsec;  
     $result.= '<option value="all" '.($saveSec eq 'all' ? 'selected="selected"' : ''). '>all</option></select> &nbsp; ';  
     $result.='  
     </fieldset>      </fieldset>
     
     <fieldset>      <fieldset>
       <legend>        <legend>
         '.&mt('Groups').'          '.&mt('Groups').'
       </legend>        </legend>
       '.&Apache::lonstatistics::GroupSelect('group','multiple',5).'        '.&Apache::lonstatistics::GroupSelect('group','multiple',5).'
     </fieldset>      </fieldset>
      
     <fieldset>      <fieldset>
       <legend>        <legend>
         '.&mt('Access Status').'          '.&mt('Access Status').'
       </legend>        </legend>
       '.&Apache::lonhtmlcommon::StatusOptions($saveStatus,undef,5,undef,'mult').'        '.&Apache::lonhtmlcommon::StatusOptions(undef,undef,5,undef,'mult').'
     </fieldset>      </fieldset>';
         if ($full) {
           $result.='
     <fieldset>      <fieldset>
       <legend>        <legend>
         '.&mt('Submission Status').'          '.&mt('Submission Status').'
       </legend>        </legend>'.
       <select name="submitonly" size="5">         &Apache::loncommon::select_form('all','submitonly',\%options).
          <option value="yes" '.      ($saveSub eq 'yes'       ? 'selected="selected"' : '').'>'.&mt('with submissions').'</option>     '</fieldset>';
          <option value="queued" '.   ($saveSub eq 'queued'    ? 'selected="selected"' : '').'>'.&mt('in grading queue').'</option>      }
          <option value="graded" '.   ($saveSub eq 'graded'    ? 'selected="selected"' : '').'>'.&mt('with ungraded submissions').'</option>      $result.='</div><br />';
          <option value="incorrect" '.($saveSub eq 'incorrect' ? 'selected="selected"' : '').'>'.&mt('with incorrect submissions').'</option>  
                  <option value="all" '.      ($saveSub eq 'all'       ? 'selected="selected"' : '').'>'.&mt('with any status').'</option>  
       </select>  
     </fieldset>  
     
 </div>  
   
 <br />  
           <div>  
             <div>  
               <label>  
                 <input type="radio" name="radioChoice" value="submission" '.  
                   ($saveCmd eq 'submission' ? 'checked="checked"' : '').' /> '.  
              &mt('Select individual students to grade and view submissions.').'  
       </label>   
             </div>  
             <div>  
       <label>  
                 <input type="radio" name="radioChoice" value="viewgrades" '.  
                   ($saveCmd eq 'viewgrades' ? 'checked="checked"' : '').' /> '.  
                     &mt('Grade all selected students in a grading table.').'  
               </label>  
             </div>  
             <div>  
       <input type="button" onclick="javascript:checkChoice(this.form,\'2\');" value="'.&mt('Next').' &rarr;" />  
             </div>  
           </div>  
   
   
         <h2>  
          '.&mt('Grade Complete Folder for One Student').'  
         </h2>  
         <div>  
             <div>  
               <label>  
                 <input type="radio" name="radioChoice" value="pickStudentPage" '.  
   ($saveCmd eq 'pickStudentPage' ? 'checked="checked"' : '').' /> '.  
   &mt('The <b>complete</b> page/sequence/folder: For one student').'  
               </label>  
             </div>  
             <div>  
       <input type="button" onclick="javascript:checkChoice(this.form,\'2\');" value="'.&mt('Next').' &rarr;" />  
             </div>  
         </div>  
   </form>';  
     $result .= &show_grading_menu_form($symb);  
     return $result;      return $result;
 }  }
   
Line 9991  sub substatus_options { Line 10276  sub substatus_options {
                                       );                                        );
 }  }
   
   sub transtatus_options {
       return &Apache::lonlocal::texthash(
                                          'yes'       => 'with score transactions',
                                          'incorrect' => 'with less than full credit',
                                          'all'       => 'with any status',
                                         );
   }
   
 sub reset_perm {  sub reset_perm {
     undef(%perm);      undef(%perm);
 }  }
Line 10090  sub clicker_grading_parameters { Line 10383  sub clicker_grading_parameters {
 }  }
   
 sub process_clicker {  sub process_clicker {
     my ($r)=@_;      my ($r,$symb)=@_;
     my ($symb)=&get_symb($r);  
     if (!$symb) {return '';}      if (!$symb) {return '';}
     my $result=&checkforfile_js();      my $result=&checkforfile_js();
     $env{'form.probTitle'} = &Apache::lonnet::gettitle($symb);      $result.=&Apache::loncommon::start_data_table().
     my ($table) = &showResourceInfo($symb,$env{'form.probTitle'});               &Apache::loncommon::start_data_table_header_row().
     $result.=$table;               '<th>'.&mt('Specify a file containing clicker information and set grading options.').'</th>'.
     $result.='<br /><table width="100%" border="0"><tr><td bgcolor="#777777">'."\n";               &Apache::loncommon::end_data_table_header_row().
     $result.='<table width="100%" border="0"><tr bgcolor="#e6ffff"><td>'."\n";               &Apache::loncommon::start_data_table_row()."<td>\n";
     $result.='&nbsp;<b>'.&mt('Specify a file containing the clicker information for this resource.').  
         '</b></td></tr>'."\n";  
     $result.='<tr bgcolor="#ffffe6"><td>'."\n";  
 # 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 10118  sub process_clicker { Line 10407  sub process_clicker {
        }         }
     }      }
   
     my $upload=&mt("Upload File");      my $upload=&mt("Evaluate File");
     my $type=&mt("Type");      my $type=&mt("Type");
     my $attendance=&mt("Award points just for participation");      my $attendance=&mt("Award points just for participation");
     my $personnel=&mt("Correctness determined from response by course personnel");      my $personnel=&mt("Correctness determined from response by course personnel");
Line 10132  sub process_clicker { Line 10421  sub process_clicker {
                                                     'interwrite' => 'interwrite PRS',                                                      'interwrite' => 'interwrite PRS',
                                                     'turning' => 'Turning Technologies'});                                                      'turning' => 'Turning Technologies'});
     $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 10171  function sanitycheck() { Line 10459  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" />
 <input type="hidden" name="probTitle" value="$env{'form.probTitle'}" />  
 <input type="hidden" name="saveState"  value="$env{'form.saveState'}" />  
 <input type="file" name="upfile" size="50" />  <input type="file" name="upfile" size="50" />
 <br /><label>$type: $selectform</label>  <br /><label>$type: $selectform</label>
 <br /><label><input type="radio" name="gradingmechanism" value="attendance"$checked{'attendance'} onclick="sanitycheck()" />$attendance </label>  ENDUPFORM
       $result.='</td>'.&Apache::loncommon::end_data_table_row().
                        &Apache::loncommon::start_data_table_row().'<td>'.(<<ENDGRADINGFORM);
         <label><input type="radio" name="gradingmechanism" value="attendance"$checked{'attendance'} onclick="sanitycheck()" />$attendance </label>
 <br /><label><input type="radio" name="gradingmechanism" value="personnel"$checked{'personnel'} onclick="sanitycheck()" />$personnel</label>  <br /><label><input type="radio" name="gradingmechanism" value="personnel"$checked{'personnel'} onclick="sanitycheck()" />$personnel</label>
 <br /><label><input type="radio" name="gradingmechanism" value="specific"$checked{'specific'} onclick="sanitycheck()" />$specific </label>  <br /><label><input type="radio" name="gradingmechanism" value="specific"$checked{'specific'} onclick="sanitycheck()" />$specific </label>
 <input type="text" name="specificid" value="$env{'form.specificid'}" size="20" />  <input type="text" name="specificid" value="$env{'form.specificid'}" size="20" />
Line 10187  function sanitycheck() { Line 10477  function sanitycheck() {
 <br />&nbsp;&nbsp;&nbsp;  <br />&nbsp;&nbsp;&nbsp;
 <input type="text" name="givenanswer" size="50" />  <input type="text" name="givenanswer" size="50" />
 <input type="hidden" name="waschecked" value="$env{'form.gradingmechanism'}" />  <input type="hidden" name="waschecked" value="$env{'form.gradingmechanism'}" />
 <br /><label>$pcorrect: <input type="text" name="pcorrect" size="4" value="$env{'form.pcorrect'}" onchange="sanitycheck()" /></label>  ENDGRADINGFORM
       $result.='</td>'.&Apache::loncommon::end_data_table_row().
                        &Apache::loncommon::start_data_table_row().'<td>'.(<<ENDPERCFORM);
         <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  ENDPERCFORM
     $result.='</td></tr></table>'."\n".      $result.='</td>'.
              '</td></tr></table><br /><br />'."\n";               &Apache::loncommon::end_data_table_row().
     $result.=&show_grading_menu_form($symb);               &Apache::loncommon::end_data_table();
     return $result;      return $result;
 }  }
   
 sub process_clicker_file {  sub process_clicker_file {
     my ($r)=@_;      my ($r,$symb) = @_;
     my ($symb)=&get_symb($r);  
     if (!$symb) {return '';}      if (!$symb) {return '';}
   
     my %Saveable_Parameters=&clicker_grading_parameters();      my %Saveable_Parameters=&clicker_grading_parameters();
     &Apache::loncommon::store_course_settings('grades_clicker',      &Apache::loncommon::store_course_settings('grades_clicker',
                                               \%Saveable_Parameters);                                                \%Saveable_Parameters);
       my $result='';
     my ($result) = &showResourceInfo($symb,$env{'form.probTitle'});  
     if (($env{'form.gradingmechanism'} eq 'specific') && ($env{'form.specificid'}!~/\w/)) {      if (($env{'form.gradingmechanism'} eq 'specific') && ($env{'form.specificid'}!~/\w/)) {
  $result.='<span class="LC_error">'.&mt('You need to specify a clicker ID for the correct answer').'</span>';   $result.='<span class="LC_error">'.&mt('You need to specify a clicker ID for the correct answer').'</span>';
  return $result.&show_grading_menu_form($symb);   return $result;
     }      }
     if (($env{'form.gradingmechanism'} eq 'given') && ($env{'form.givenanswer'}!~/\S/)) {      if (($env{'form.gradingmechanism'} eq 'given') && ($env{'form.givenanswer'}!~/\S/)) {
         $result.='<span class="LC_error">'.&mt('You need to specify the correct answer').'</span>';          $result.='<span class="LC_error">'.&mt('You need to specify the correct answer').'</span>';
         return $result.&show_grading_menu_form($symb);          return $result;
     }      }
     my $foundgiven=0;      my $foundgiven=0;
     if ($env{'form.gradingmechanism'} eq 'given') {      if ($env{'form.gradingmechanism'} eq 'given') {
Line 10263  sub process_clicker_file { Line 10554  sub process_clicker_file {
             $result .=              $result .=
                  &Apache::lonhtmlcommon::confirm_success(                   &Apache::lonhtmlcommon::confirm_success(
                      &mt('No IDs found to determine correct answer'),1);                       &mt('No IDs found to determine correct answer'),1);
             return $result,.&show_grading_menu_form($symb);              return $result;
         }          }
     }      }
     if (length($env{'form.upfile'}) < 2) {      if (length($env{'form.upfile'}) < 2) {
Line 10271  sub process_clicker_file { Line 10562  sub process_clicker_file {
             &Apache::lonhtmlcommon::confirm_success(              &Apache::lonhtmlcommon::confirm_success(
                 &mt('The file: [_1] you attempted to upload contained no information. Please check that you entered the correct filename.',                  &mt('The file: [_1] you attempted to upload contained no information. Please check that you entered the correct filename.',
                         '<span class="LC_filename">'.&HTML::Entities::encode($env{'form.upfile.filename'},'<>&"').'</span>'),1);                          '<span class="LC_filename">'.&HTML::Entities::encode($env{'form.upfile.filename'},'<>&"').'</span>'),1);
         return $result.&show_grading_menu_form($symb);          return $result;
       }
       my $mimetype;
       if ($env{'form.upfiletype'} eq 'iclicker') {
           my $mm = new File::MMagic;
           $mimetype = $mm->checktype_contents($env{'form.upfile'});
           unless (($mimetype eq 'text/plain') || ($mimetype eq 'text/html')) {
               $result.= '<p>'.
                   &Apache::lonhtmlcommon::confirm_success(
                       &mt('File format is neither csv (iclicker 6) nor xml (iclicker 7)'),1).'</p>';
               return $result;
           }
       } elsif (($env{'form.upfiletype'} ne 'interwrite') && ($env{'form.upfiletype'} ne 'turning')) {
           $result .= '<p>'.
               &Apache::lonhtmlcommon::confirm_success(
                   &mt('Invalid clicker type: choose one of: i>clicker, Interwrite PRS, or Turning Technologies.'),1).'</p>';
           return $result;
     }      }
   
 # Were able to get all the info needed, now analyze the file  # Were able to get all the info needed, now analyze the file
   
     $result.=&Apache::loncommon::studentbrowser_javascript();      $result.=&Apache::loncommon::studentbrowser_javascript();
     $symb = &Apache::lonenc::check_encrypt($symb);      $symb = &Apache::lonenc::check_encrypt($symb);
     my $heading=&mt('Scanning clicker file');      $result.=&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('Evaluate 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().(<<ENDHEADER);
   <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" />
 <input type="hidden" name="probTitle" value="$env{'form.probTitle'}" />  
 <input type="hidden" name="saveState"  value="$env{'form.saveState'}" />  
 <input type="hidden" name="gradingmechanism" value="$env{'form.gradingmechanism'}" />  <input type="hidden" name="gradingmechanism" value="$env{'form.gradingmechanism'}" />
 <input type="hidden" name="pcorrect" value="$env{'form.pcorrect'}" />  <input type="hidden" name="pcorrect" value="$env{'form.pcorrect'}" />
 <input type="hidden" name="pincorrect" value="$env{'form.pincorrect'}" />  <input type="hidden" name="pincorrect" value="$env{'form.pincorrect'}" />
Line 10300  ENDHEADER Line 10606  ENDHEADER
     my $errormsg='';      my $errormsg='';
     my $number=0;      my $number=0;
     if ($env{'form.upfiletype'} eq 'iclicker') {      if ($env{'form.upfiletype'} eq 'iclicker') {
  ($errormsg,$number)=&iclicker_eval(\@questiontitles,\%responses);          if ($mimetype eq 'text/plain') {
     }              ($errormsg,$number)=&iclicker_eval(\@questiontitles,\%responses);
     if ($env{'form.upfiletype'} eq 'interwrite') {          } elsif ($mimetype eq 'text/html') {
               ($errormsg,$number)=&iclickerxml_eval(\@questiontitles,\%responses);
           }
       } elsif ($env{'form.upfiletype'} eq 'interwrite') {
         ($errormsg,$number)=&interwrite_eval(\@questiontitles,\%responses);          ($errormsg,$number)=&interwrite_eval(\@questiontitles,\%responses);
     }      } elsif ($env{'form.upfiletype'} eq 'turning') {
     if ($env{'form.upfiletype'} eq 'turning') {  
         ($errormsg,$number)=&turning_eval(\@questiontitles,\%responses);          ($errormsg,$number)=&turning_eval(\@questiontitles,\%responses);
     }      }
     $result.='<br />'.&mt('Found [_1] question(s)',$number).'<br />'.      $result.='<br />'.&mt('Found [_1] question(s)',$number).'<br />'.
Line 10315  ENDHEADER Line 10623  ENDHEADER
              '<br />';               '<br />';
     if (($env{'form.gradingmechanism'} eq 'given') && ($number!=$foundgiven)) {      if (($env{'form.gradingmechanism'} eq 'given') && ($number!=$foundgiven)) {
        $result.='<span class="LC_error">'.&mt('Number of given answers does not agree with number of questions in file.').'</span>';         $result.='<span class="LC_error">'.&mt('Number of given answers does not agree with number of questions in file.').'</span>';
        return $result.&show_grading_menu_form($symb);         return $result;
     }       } 
 # Remember Question Titles  # Remember Question Titles
 # FIXME: Possibly need delimiter other than ":"  # FIXME: Possibly need delimiter other than ":"
Line 10335  ENDHEADER Line 10643  ENDHEADER
        } elsif ($clicker_ids{$id}) {         } elsif ($clicker_ids{$id}) {
           if ($clicker_ids{$id}=~/\,/) {            if ($clicker_ids{$id}=~/\,/) {
 # More than one user with the same clicker!  # More than one user with the same clicker!
              $result.="\n<hr />".&mt('Clicker registered more than once').": <tt>".$id."</tt><br />";               $result.="</td>".&Apache::loncommon::end_data_table_row().
                              &Apache::loncommon::start_data_table_row()."<td>".
                          &mt('Clicker registered more than once').": <tt>".$id."</tt><br />";
              $result.="\n".'<input type="hidden" name="unknown:'.$id.'" value="'.$responses{$id}.'" />'.               $result.="\n".'<input type="hidden" name="unknown:'.$id.'" value="'.$responses{$id}.'" />'.
                            "<select name='multi".$id."'>";                             "<select name='multi".$id."'>";
              foreach my $reguser (sort(split(/\,/,$clicker_ids{$id}))) {               foreach my $reguser (sort(split(/\,/,$clicker_ids{$id}))) {
Line 10349  ENDHEADER Line 10659  ENDHEADER
              $student_count++;               $student_count++;
           }            }
        } else {         } else {
           $result.="\n<hr />".&mt('Unregistered Clicker')." <tt>".$id."</tt><br />";            $result.="</td>".&Apache::loncommon::end_data_table_row().
                              &Apache::loncommon::start_data_table_row()."<td>".
                       &mt('Unregistered Clicker')." <tt>".$id."</tt><br />";
           $result.="\n".'<input type="hidden" name="unknown:'.$id.'" value="'.$responses{$id}.'" />'.            $result.="\n".'<input type="hidden" name="unknown:'.$id.'" value="'.$responses{$id}.'" />'.
                    "\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,'',$id);
           $unknown_count++;            $unknown_count++;
        }         }
     }      }
Line 10375  ENDHEADER Line 10687  ENDHEADER
     } else {      } else {
        $result.='<br /><input type="submit" name="finalize" value="'.&mt('Finalize Grading').'" />';         $result.='<br /><input type="submit" name="finalize" value="'.&mt('Finalize Grading').'" />';
     }      }
     $result.='</form></td></tr></table>'."\n".      $result.='</form></td>'.
              '</td></tr></table><br /><br />'."\n";               &Apache::loncommon::end_data_table_row().
     return $result.&show_grading_menu_form($symb);               &Apache::loncommon::end_data_table();
       return $result;
 }  }
   
 sub iclicker_eval {  sub iclicker_eval {
Line 10408  sub iclicker_eval { Line 10721  sub iclicker_eval {
     return ($errormsg,$number);      return ($errormsg,$number);
 }  }
   
   sub iclickerxml_eval {
       my ($questiontitles,$responses)=@_;
       my $number=0;
       my $errormsg='';
       my @state;
       my %respbyid;
       my $p = HTML::Parser->new
       (
           xml_mode => 1,
           start_h =>
               [sub {
                    my ($tagname,$attr) = @_;
                    push(@state,$tagname);
                    if ("@state" eq "ssn p") {
                        my $title = $attr->{qn};
                        $title =~ s/(^\s+|\s+$)//g;
                        $questiontitles->[$number]=$title;
                    } elsif ("@state" eq "ssn p v") {
                        my $id = $attr->{id};
                        my $entry = $attr->{ans};
                        $id=~s/^[\#0]+//;
                        $entry =~s/[^a-zA-Z0-9\.\*\-\+]+//g;
                        $respbyid{$id}[$number] = $entry;
                    }
               }, "tagname, attr"],
            end_h =>
                  [sub {
                      my ($tagname) = @_;
                      if ("@state" eq "ssn p") {
                          $number++;
                      }
                      pop(@state);
                   }, "tagname"],
       );
   
       $p->parse($env{'form.upfile'});
       $p->eof;
       foreach my $id (keys(%respbyid)) {
           $responses->{$id}=join(',',@{$respbyid{$id}});
       }
       return ($errormsg,$number);
   }
   
 sub interwrite_eval {  sub interwrite_eval {
     my ($questiontitles,$responses)=@_;      my ($questiontitles,$responses)=@_;
     my $number=0;      my $number=0;
Line 10465  sub turning_eval { Line 10821  sub turning_eval {
 }  }
   
 sub assign_clicker_grades {  sub assign_clicker_grades {
     my ($r)=@_;      my ($r,$symb) = @_;
     my ($symb)=&get_symb($r);  
     if (!$symb) {return '';}      if (!$symb) {return '';}
 # See which part we are saving to  # See which part we are saving to
     my $res_error;      my $res_error;
Line 10477  sub assign_clicker_grades { Line 10832  sub assign_clicker_grades {
 # FIXME: This should probably look for the first handgradeable part  # FIXME: This should probably look for the first handgradeable part
     my $part=$$partlist[0];      my $part=$$partlist[0];
 # Start screen output  # Start screen output
     my ($result) = &showResourceInfo($symb,$env{'form.probTitle'});      my $result = &Apache::loncommon::start_data_table(). 
                    &Apache::loncommon::start_data_table_header_row().
     $result .= '<br />'.                   '<th>'.&mt('Assigning grades based on clicker file').'</th>'.
                &Apache::loncommon::start_data_table().                   &Apache::loncommon::end_data_table_header_row().
                &Apache::loncommon::start_data_table_header_row().                   &Apache::loncommon::start_data_table_row().'<td>';
                '<th>'.&mt('Assigning grades based on clicker file').'</th>'.  
                &Apache::loncommon::end_data_table_header_row().  
                &Apache::loncommon::start_data_table_row().'<td>';  
   
 # Get correct result  # Get correct result
 # FIXME: Possibly need delimiter other than ":"  # FIXME: Possibly need delimiter other than ":"
     my @correct=();      my @correct=();
Line 10547  sub assign_clicker_grades { Line 10898  sub assign_clicker_grades {
           for (my $i=0;$i<$number;$i++) {            for (my $i=0;$i<$number;$i++) {
              if  ($correct[$i] eq '-') {               if  ($correct[$i] eq '-') {
                 $realnumber--;                  $realnumber--;
              } elsif ($answer[$i]) {               } elsif (($answer[$i]) || ($answer[$i]=~/^[0\.]+$/)) {
                 if ($gradingmechanism eq 'attendance') {                  if ($gradingmechanism eq 'attendance') {
                    $sum+=$pcorrect;                     $sum+=$pcorrect;
                 } elsif ($correct[$i] eq '*') {                  } elsif ($correct[$i] eq '*') {
Line 10594  sub assign_clicker_grades { Line 10945  sub assign_clicker_grades {
     $result.='<br />'.&mt('Successfully stored grades for [quant,_1,student].',$storecount).      $result.='<br />'.&mt('Successfully stored grades for [quant,_1,student].',$storecount).
              '</td>'.               '</td>'.
              &Apache::loncommon::end_data_table_row().               &Apache::loncommon::end_data_table_row().
              &Apache::loncommon::end_data_table()."<br /><br />\n";               &Apache::loncommon::end_data_table();
     return $result.&show_grading_menu_form($symb);      return $result;
 }  }
   
 sub navmap_errormsg {  sub navmap_errormsg {
Line 10606  sub navmap_errormsg { Line 10957  sub navmap_errormsg {
 }  }
   
 sub startpage {  sub startpage {
     my ($r,$symb,$crumbs,$onlyfolderflag,$nodisplayflag,$stuvcurrent,$stuvdisp,$nomenu,$js,$onload) = @_;      my ($r,$symb,$crumbs,$onlyfolderflag,$nodisplayflag,$stuvcurrent,$stuvdisp,$nomenu,$head_extra,$onload,$divforres) = @_;
     my %args;      my %args;
     if ($onload) {      if ($onload) {
          my %loaditems = (           my %loaditems = (
Line 10616  sub startpage { Line 10967  sub startpage {
     }      }
     if ($nomenu) {      if ($nomenu) {
         $args{'only_body'} = 1;          $args{'only_body'} = 1;
         $r->print(&Apache::loncommon::start_page("Student's Version",$js,\%args));          $r->print(&Apache::loncommon::start_page("Student's Version",$head_extra,\%args));
     } else {      } else {
           if ($env{'request.course.id'}) {
               unshift(@$crumbs,{href=>&href_symb_cmd($symb,'gradingmenu'),text=>"Grading"});
           }
         $args{'bread_crumbs'} = $crumbs;          $args{'bread_crumbs'} = $crumbs;
         $r->print(&Apache::loncommon::start_page('Grading',$js,\%args));          $r->print(&Apache::loncommon::start_page('Grading',$head_extra,\%args));
     }      }
     unless ($nodisplayflag) {      unless ($nodisplayflag) {
        $r->print(&Apache::lonhtmlcommon::resource_info_box($symb,$onlyfolderflag,$stuvcurrent,$stuvdisp));         $r->print(&Apache::lonhtmlcommon::resource_info_box($symb,$onlyfolderflag,$stuvcurrent,$stuvdisp,$divforres));
     }      }
 }  }
   
   sub select_problem {
       my ($r)=@_;
       $r->print('<h3>'.&mt('Select the problem or one of the problems you want to grade').'</h3><form action="/adm/grades">');
       $r->print(&Apache::lonstathelpers::problem_selector('.',undef,1,undef,undef,1));
       $r->print('<input type="hidden" name="command" value="gradingmenu" />');
       $r->print('<input type="submit" value="'.&mt('Next').' &rarr;" /></form>');
   }
   
 sub handler {  sub handler {
     my $request=$_[0];      my $request=$_[0];
     &reset_caches();      &reset_caches();
Line 10636  sub handler { Line 10998  sub handler {
     }      }
     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'});      &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'});
   
     my $symb=&get_symb($request,1);  # see what command we need to execute
    
     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];
   
       &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');
           return OK;
       }
       &Apache::loncommon::content_type($request,'text/html');
       $request->send_http_header;
   
     if ($#commands > 0) {      if ($#commands > 0) {
  &Apache::lonnet::logthis("grades got multiple commands ".join(':',@commands));   &Apache::lonnet::logthis("grades got multiple commands ".join(':',@commands));
     }      }
   
   # see what the symb is
   
       my $symb=$env{'form.symb'};
       unless ($symb) {
          (my $url=$env{'form.url'}) =~ s-^https*://($ENV{'SERVER_NAME'}|$ENV{'HTTP_HOST'})--;
          $symb=&Apache::lonnet::symbread($url);
       }
       &Apache::lonenc::check_decrypt(\$symb);
   
     $ssi_error = 0;      $ssi_error = 0;
     my $brcrum = [{href=>"/adm/grades",text=>"Grading"}];      if (($symb eq '' || $command eq '') && ($env{'request.course.id'})) {
     my $start_page = &Apache::loncommon::start_page('Grading',undef,  #
                                                     {'bread_crumbs' => $brcrum});  # Not called from a resource, but inside a course
     if ($symb eq '' && $command eq '') {  #
  if ($env{'user.adv'}) {          &startpage($request,undef,[],1,1);
             &Apache::loncommon::content_type($request,'text/html');          &select_problem($request);
             $request->send_http_header;  
             $request->print($start_page);  
     if (($env{'form.codeone'}) && ($env{'form.codetwo'}) &&  
  ($env{'form.codethree'})) {  
  my $token=$env{'form.codeone'}.'*'.$env{'form.codetwo'}.'*'.  
     $env{'form.codethree'};  
  my ($tsymb,$tuname,$tudom,$tcrsid)=  
     &Apache::lonnet::checkin($token);  
  if ($tsymb) {  
     my ($map,$id,$url)=&Apache::lonnet::decode_symb($tsymb);  
     if (&Apache::lonnet::allowed('mgr',$tcrsid)) {  
  $request->print(&ssi_with_retries('/res/'.$url, $ssi_retries,  
   ('grade_username' => $tuname,  
    'grade_domain' => $tudom,  
    'grade_courseid' => $tcrsid,  
    'grade_symb' => $tsymb)));  
     } else {  
  $request->print('<h3>Not authorized: '.$token.'</h3>');  
     }  
  } else {  
     $request->print('<h3>Not a valid DocID: '.$token.'</h3>');  
  }  
     } else {  
  $request->print(&Apache::lonxml::tokeninputfield());  
     }  
         } elsif ($env{'request.course.id'}) {  
             &init_perm();   
             if (!%perm) {  
                 $request->internal_redirect('/adm/quickgrades');  
                 return OK;  
             } else {  
                 &Apache::loncommon::content_type($request,'text/html');  
                 $request->send_http_header;  
                 $request->print($start_page);  
             }  
         }  
     } else {      } else {
         &init_perm();          if ($command eq 'submission' && $perm{'vgr'}) {
         if (!$env{'request.course.id'}) {              my ($stuvcurrent,$stuvdisp,$versionform,$js,$onload);
             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;  
         if (($command eq 'scantron_selectphase' && $perm{'mgr'}) ||   
             (($command eq 'scantronupload') &&  
              (&Apache::lonnet::allowed('usc',$env{'request.role.domain'}) ||  
               &Apache::lonnet::allowed('usc',$env{'request.course.id'})))) {  
             &startpage($request,$symb,[{href=>'/adm/grades', text=>"Grading"}],1,1,  
                        undef,undef,undef,undef,'toggleScantab(document.rules);');  
         } else {  
             unless ((($command eq 'submission' || $command eq 'versionsub')) && ($perm{'vgr'})) {  
                 $request->print($start_page);   
             }  
         }  
  if ($command eq 'submission' && $perm{'vgr'}) {  
             my ($stuvcurrent,$stuvdisp,$versionform,$js);  
             if (($env{'form.student'} ne '') && ($env{'form.userdom'} ne '')) {              if (($env{'form.student'} ne '') && ($env{'form.userdom'} ne '')) {
                 ($stuvcurrent,$stuvdisp,$versionform,$js) =                  ($stuvcurrent,$stuvdisp,$versionform,$js) =
                     &choose_task_version_form($symb,$env{'form.student'},                      &choose_task_version_form($symb,$env{'form.student'},
                                               $env{'form.userdom'});                                                $env{'form.userdom'});
             }              }
             &startpage($request,$symb,[{href=>"", text=>"Student Submissions"}],undef,undef,$stuvcurrent,$stuvdisp,undef,$js);              my $divforres;
               if ($env{'form.student'} eq '') {
                   $js .= &part_selector_js();
                   $onload = "toggleParts('gradesub');";
               } else {
                   $divforres = 1;
               }
               my $head_extra = $js;
               unless ($env{'form.vProb'} eq 'no') {
                   my $csslinks = &Apache::loncommon::css_links($symb);
                   if ($csslinks) {
                       $head_extra .= "\n$csslinks";
                   }
               }
               &startpage($request,$symb,[{href=>"", text=>"Student Submissions"}],undef,undef,
                          $stuvcurrent,$stuvdisp,undef,$head_extra,$onload,$divforres);
             if ($versionform) {              if ($versionform) {
                   if ($divforres) {
                       $request->print('<div style="padding:0;clear:both;margin:0;border:0"></div>');
                   }
                 $request->print($versionform);                  $request->print($versionform);
             }              }
             $request->print('<br clear="all" />');              ($env{'form.student'} eq '' ? &listStudents($request,$symb,'',$divforres) : &submission($request,0,0,$symb,$divforres,$command));
     ($env{'form.student'} eq '' ? &listStudents($request) : &submission($request,0,0));  
         } elsif ($command eq 'versionsub' && $perm{'vgr'}) {          } elsif ($command eq 'versionsub' && $perm{'vgr'}) {
             my ($stuvcurrent,$stuvdisp,$versionform,$js) =              my ($stuvcurrent,$stuvdisp,$versionform,$js) =
                 &choose_task_version_form($symb,$env{'form.student'},                  &choose_task_version_form($symb,$env{'form.student'},
                                           $env{'form.userdom'},                                            $env{'form.userdom'},
                                           $env{'form.inhibitmenu'});                                            $env{'form.inhibitmenu'});
             &startpage($request,$symb,[{href=>"", text=>"Previous Student Version"}],undef,undef,$stuvcurrent,$stuvdisp,$env{'form.inhibitmenu'},$js);              my $head_extra = $js;
               unless ($env{'form.vProb'} eq 'no') {
                   my $csslinks = &Apache::loncommon::css_links($symb);
                   if ($csslinks) {
                       $head_extra .= "\n$csslinks";
                   }
               }
               &startpage($request,$symb,[{href=>"", text=>"Previous Student Version"}],undef,undef,
                          $stuvcurrent,$stuvdisp,$env{'form.inhibitmenu'},$head_extra);
             if ($versionform) {              if ($versionform) {
                 $request->print($versionform);                  $request->print($versionform);
             }              }
             $request->print('<br clear="all" />');              $request->print('<br clear="all" />');
             $request->print(&show_previous_task_version($request,$symb));              $request->print(&show_previous_task_version($request,$symb));
  } elsif ($command eq 'pickStudentPage' && $perm{'vgr'}) {          } elsif ($command eq 'pickStudentPage' && $perm{'vgr'}) {
     &pickStudentPage($request);              &startpage($request,$symb,[{href=>&href_symb_cmd($symb,'all_for_one'),text=>'Grade page/folder for one student'},
  } elsif ($command eq 'displayPage' && $perm{'vgr'}) {                                         {href=>'',text=>'Select student'}],1,1);
     &displayPage($request);              &pickStudentPage($request,$symb);
  } elsif ($command eq 'gradeByPage' && $perm{'mgr'}) {          } elsif ($command eq 'displayPage' && $perm{'vgr'}) {
     &updateGradeByPage($request);              my $csslinks;
  } elsif ($command eq 'processGroup' && $perm{'vgr'}) {              unless ($env{'form.vProb'} eq 'no') {
     &processGroup($request);                  $csslinks = &Apache::loncommon::css_links($symb,'map');
  } elsif ($command eq 'gradingmenu' && $perm{'vgr'}) {              }
     $request->print(&grading_menu($request));              &startpage($request,$symb,
  } elsif ($command eq 'submit_options' && $perm{'vgr'}) {                                        [{href=>&href_symb_cmd($symb,'all_for_one'),text=>'Grade page/folder for one student'},
     $request->print(&submit_options($request));                                         {href=>'',text=>'Select student'},
  } elsif ($command eq 'viewgrades' && $perm{'vgr'}) {                                         {href=>'',text=>'Grade student'}],1,1,undef,undef,undef,$csslinks);
     $request->print(&viewgrades($request));              &displayPage($request,$symb);
  } elsif ($command eq 'handgrade' && $perm{'mgr'}) {          } elsif ($command eq 'gradeByPage' && $perm{'mgr'}) {
     $request->print(&processHandGrade($request));              &startpage($request,$symb,[{href=>&href_symb_cmd($symb,'all_for_one'),text=>'Grade page/folder for one student'},
  } elsif ($command eq 'editgrades' && $perm{'mgr'}) {                                         {href=>'',text=>'Select student'},
     $request->print(&editgrades($request));                                         {href=>'',text=>'Grade student'},
  } elsif ($command eq 'verify' && $perm{'vgr'}) {                                         {href=>'',text=>'Store grades'}],1,1);
     $request->print(&verifyreceipt($request));              &updateGradeByPage($request,$symb);
           } elsif ($command eq 'processGroup' && $perm{'vgr'}) {
               my $csslinks;
               unless ($env{'form.vProb'} eq 'no') {
                   $csslinks = &Apache::loncommon::css_links($symb);
               }
               &startpage($request,$symb,[{href=>'',text=>'...'},
                                          {href=>'',text=>'Modify grades'}],undef,undef,undef,undef,undef,$csslinks,undef,1);
               &processGroup($request,$symb);
           } elsif ($command eq 'gradingmenu' && $perm{'vgr'}) {
               &startpage($request,$symb);
               $request->print(&grading_menu($request,$symb));
           } elsif ($command eq 'individual' && $perm{'vgr'}) {
               &startpage($request,$symb,[{href=>'',text=>'Select individual students to grade'}]);
               $request->print(&submit_options($request,$symb));
           } elsif ($command eq 'ungraded' && $perm{'vgr'}) {
               my $js = &part_selector_js();
               my $onload = "toggleParts('gradesub');";
               &startpage($request,$symb,[{href=>'',text=>'Grade ungraded submissions'}],
                          undef,undef,undef,undef,undef,$js,$onload);
               $request->print(&listStudents($request,$symb,'graded'));
           } elsif ($command eq 'table' && $perm{'vgr'}) {
               &startpage($request,$symb,[{href=>"", text=>"Grading table"}]);
               $request->print(&submit_options_table($request,$symb));
           } elsif ($command eq 'all_for_one' && $perm{'vgr'}) {
               &startpage($request,$symb,[{href=>'',text=>'Grade page/folder for one student'}],1,1);
               $request->print(&submit_options_sequence($request,$symb));
           } elsif ($command eq 'viewgrades' && $perm{'vgr'}) {
               &startpage($request,$symb,[{href=>&href_symb_cmd($symb,"table"), text=>"Grading table"},{href=>'', text=>"Modify grades"}]);
               $request->print(&viewgrades($request,$symb));
           } elsif ($command eq 'handgrade' && $perm{'mgr'}) {
               &startpage($request,$symb,[{href=>'',text=>'...'},
                                          {href=>'',text=>'Store grades'}]);
               $request->print(&processHandGrade($request,$symb));
           } elsif ($command eq 'editgrades' && $perm{'mgr'}) {
               &startpage($request,$symb,[{href=>&href_symb_cmd($symb,"table"), text=>"Grading table"},
                                          {href=>&href_symb_cmd($symb,'viewgrades').'&group=all&section=all&Status=Active',
                                                                                text=>"Modify grades"},
                                          {href=>'', text=>"Store grades"}]);
               $request->print(&editgrades($request,$symb));
           } elsif ($command eq 'initialverifyreceipt' && $perm{'vgr'}) {
               &startpage($request,$symb,[{href=>'',text=>'Verify Receipt Number'}]);
               $request->print(&initialverifyreceipt($request,$symb));
           } elsif ($command eq 'verify' && $perm{'vgr'}) {
               &startpage($request,$symb,[{href=>&href_symb_cmd($symb,"initialverifyreceipt"),text=>'Verify Receipt Number'},
                                          {href=>'',text=>'Verification Result'}]);
               $request->print(&verifyreceipt($request,$symb));
         } elsif ($command eq 'processclicker' && $perm{'mgr'}) {          } elsif ($command eq 'processclicker' && $perm{'mgr'}) {
             $request->print(&process_clicker($request));              &startpage($request,$symb,[{href=>'', text=>'Process clicker'}]);
               $request->print(&process_clicker($request,$symb));
         } elsif ($command eq 'processclickerfile' && $perm{'mgr'}) {          } elsif ($command eq 'processclickerfile' && $perm{'mgr'}) {
             $request->print(&process_clicker_file($request));              &startpage($request,$symb,[{href=>&href_symb_cmd($symb,'processclicker'), text=>'Process clicker'},
                                          {href=>'', text=>'Process clicker file'}]);
               $request->print(&process_clicker_file($request,$symb));
         } elsif ($command eq 'assignclickergrades' && $perm{'mgr'}) {          } elsif ($command eq 'assignclickergrades' && $perm{'mgr'}) {
             $request->print(&assign_clicker_grades($request));              &startpage($request,$symb,[{href=>&href_symb_cmd($symb,'processclicker'), text=>'Process clicker'},
  } elsif ($command eq 'csvform' && $perm{'mgr'}) {                                         {href=>'', text=>'Process clicker file'},
     $request->print(&upcsvScores_form($request));                                         {href=>'', text=>'Store grades'}]);
  } elsif ($command eq 'csvupload' && $perm{'mgr'}) {              $request->print(&assign_clicker_grades($request,$symb));
     $request->print(&csvupload($request));          } elsif ($command eq 'csvform' && $perm{'mgr'}) {
  } elsif ($command eq 'csvuploadmap' && $perm{'mgr'} ) {              &startpage($request,$symb,[{href=>'', text=>'Upload Scores'}],1,1);
     $request->print(&csvuploadmap($request));              $request->print(&upcsvScores_form($request,$symb));
  } elsif ($command eq 'csvuploadoptions' && $perm{'mgr'}) {          } elsif ($command eq 'csvupload' && $perm{'mgr'}) {
     if ($env{'form.associate'} ne 'Reverse Association') {              &startpage($request,$symb,[{href=>'', text=>'Upload Scores'}],1,1);
  $request->print(&csvuploadoptions($request));              $request->print(&csvupload($request,$symb));
     } else {          } elsif ($command eq 'csvuploadmap' && $perm{'mgr'} ) {
  if ( $env{'form.upfile_associate'} ne 'reverse' ) {              &startpage($request,$symb,[{href=>'', text=>'Upload Scores'}],1,1);
     $env{'form.upfile_associate'} = 'reverse';              $request->print(&csvuploadmap($request,$symb));
  } else {          } elsif ($command eq 'csvuploadoptions' && $perm{'mgr'}) {
     $env{'form.upfile_associate'} = 'forward';              if ($env{'form.associate'} ne 'Reverse Association') {
  }                  &startpage($request,$symb,[{href=>'', text=>'Upload Scores'}],1,1);
  $request->print(&csvuploadmap($request));                  $request->print(&csvuploadoptions($request,$symb));
     }              } else {
  } elsif ($command eq 'csvuploadassign' && $perm{'mgr'} ) {                  if ( $env{'form.upfile_associate'} ne 'reverse' ) {
     $request->print(&csvuploadassign($request));                      $env{'form.upfile_associate'} = 'reverse';
  } elsif ($command eq 'scantron_selectphase' && $perm{'mgr'}) {                  } else {
     $request->print(&scantron_selectphase($request));                      $env{'form.upfile_associate'} = 'forward';
   } elsif ($command eq 'scantron_warning' && $perm{'mgr'}) {                  }
      $request->print(&scantron_do_warning($request));                  &startpage($request,$symb,[{href=>'', text=>'Upload Scores'}],1,1);
  } elsif ($command eq 'scantron_validate' && $perm{'mgr'}) {                  $request->print(&csvuploadmap($request,$symb));
     $request->print(&scantron_validate_file($request));              }
  } elsif ($command eq 'scantron_process' && $perm{'mgr'}) {          } elsif ($command eq 'csvuploadassign' && $perm{'mgr'} ) {
     $request->print(&scantron_process_students($request));              &startpage($request,$symb,[{href=>'', text=>'Upload Scores'}],1,1);
   } elsif ($command eq 'scantronupload' &&               $request->print(&csvuploadassign($request,$symb));
   (&Apache::lonnet::allowed('usc',$env{'request.role.domain'})||          } elsif ($command eq 'scantron_selectphase' && $perm{'mgr'}) {
   &Apache::lonnet::allowed('usc',$env{'request.course.id'}))) {              &startpage($request,$symb,[{href=>'', text=>'Grade/Manage/Review Bubblesheets'}],1,1,
      $request->print(&scantron_upload_scantron_data($request));                          undef,undef,undef,undef,'toggleScantab(document.rules);');
   } elsif ($command eq 'scantronupload_save' &&              $request->print(&scantron_selectphase($request,undef,$symb));
   (&Apache::lonnet::allowed('usc',$env{'request.role.domain'})||          } elsif ($command eq 'scantron_warning' && $perm{'mgr'}) {
   &Apache::lonnet::allowed('usc',$env{'request.course.id'}))) {              &startpage($request,$symb,[{href=>'', text=>'Grade/Manage/Review Bubblesheets'}],1,1);
      $request->print(&scantron_upload_scantron_data_save($request));              $request->print(&scantron_do_warning($request,$symb));
   } elsif ($command eq 'scantron_download' &&          } elsif ($command eq 'scantron_validate' && $perm{'mgr'}) {
  &Apache::lonnet::allowed('usc',$env{'request.course.id'})) {              &startpage($request,$symb,[{href=>'', text=>'Grade/Manage/Review Bubblesheets'}],1,1);
      $request->print(&scantron_download_scantron_data($request));              $request->print(&scantron_validate_file($request,$symb));
           } elsif ($command eq 'scantron_process' && $perm{'mgr'}) {
               &startpage($request,$symb,[{href=>'', text=>'Grade/Manage/Review Bubblesheets'}],1,1);
               $request->print(&scantron_process_students($request,$symb));
           } elsif ($command eq 'scantronupload' &&
                    (&Apache::lonnet::allowed('usc',$env{'request.role.domain'})||
                     &Apache::lonnet::allowed('usc',$env{'request.course.id'}))) {
               &startpage($request,$symb,[{href=>'', text=>'Grade/Manage/Review Bubblesheets'}],1,1,
                          undef,undef,undef,undef,'toggleScantab(document.rules);');
               $request->print(&scantron_upload_scantron_data($request,$symb));
           } elsif ($command eq 'scantronupload_save' &&
                    (&Apache::lonnet::allowed('usc',$env{'request.role.domain'})||
                     &Apache::lonnet::allowed('usc',$env{'request.course.id'}))) {
               &startpage($request,$symb,[{href=>'', text=>'Grade/Manage/Review Bubblesheets'}],1,1);
               $request->print(&scantron_upload_scantron_data_save($request,$symb));
           } elsif ($command eq 'scantron_download' &&
                    &Apache::lonnet::allowed('usc',$env{'request.course.id'})) {
               &startpage($request,$symb,[{href=>'', text=>'Grade/Manage/Review Bubblesheets'}],1,1);
               $request->print(&scantron_download_scantron_data($request,$symb));
         } elsif ($command eq 'checksubmissions' && $perm{'vgr'}) {          } elsif ($command eq 'checksubmissions' && $perm{'vgr'}) {
             $request->print(&checkscantron_results($request));                   &startpage($request,$symb,[{href=>'', text=>'Grade/Manage/Review Bubblesheets'}],1,1);
  } elsif ($command) {              $request->print(&checkscantron_results($request,$symb));
     $request->print('<p class="LC_error">'.&mt('Access Denied ([_1])',$command).'</p>');          } elsif ($command eq 'downloadfilesselect' && $perm{'vgr'}) {
  }              my $js = &part_selector_js();
               my $onload = "toggleParts('gradingMenu');";
               &startpage($request,$symb,[{href=>'', text=>'Select which submissions to download'}],
                          undef,undef,undef,undef,undef,$js,$onload);
               $request->print(&submit_options_download($request,$symb));
            } elsif ($command eq 'downloadfileslink' && $perm{'vgr'}) {
               &startpage($request,$symb,
      [{href=>&href_symb_cmd($symb,'downloadfilesselect'), text=>'Select which submissions to download'},
       {href=>'', text=>'Download submitted files'}],
                  undef,undef,undef,undef,undef,undef,undef,1);
               $request->print('<div style="padding:0;clear:both;margin:0;border:0"></div>');
               &submit_download_link($request,$symb);
           } elsif ($command) {
               &startpage($request,$symb,[{href=>'', text=>'Access denied'}]);
               $request->print('<p class="LC_error">'.&mt('Access Denied ([_1])',$command).'</p>');
           }
     }      }
     if ($ssi_error) {      if ($ssi_error) {
  &ssi_print_error($request);   &ssi_print_error($request);
Line 10906  ssi_with_retries() Line 11340  ssi_with_retries()
          - missingbubble - array ref of the bubble lines that have missing           - missingbubble - array ref of the bubble lines that have missing
                            bubble errors                             bubble errors
   
    $randomorder - True if exam folder has randomorder set     $randomorder - True if exam folder (or a sub-folder) has randomorder set
    $randompick  - True if exam folder has randompick set     $randompick  - True if exam folder (or a sub-folder) has randompick set
    $respnumlookup - Reference to HASH mapping question numbers in bubble lines     $respnumlookup - Reference to HASH mapping question numbers in bubble lines
                      for current line to question number used for same question                       for current line to question number used for same question
                      in "Master Seqence" (as seen by Course Coordinator).                       in "Master Seqence" (as seen by Course Coordinator).

Removed from v.1.596.2.12.2.41.2.4  
changed lines
  Added in v.1.596.2.12.2.60


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