Diff for /loncom/homework/grades.pm between versions 1.596.2.12.2.22 and 1.719

version 1.596.2.12.2.22, 2013/08/29 12:52:04 version 1.719, 2014/02/05 15:09:30
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::lonquickgrades;
 use Apache::bridgetask();  use Apache::bridgetask();
 use String::Similarity;  use String::Similarity;
 use LONCAPA;  use LONCAPA;
Line 98  sub ssi_print_error { Line 100  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 127  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 141  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. ---
   #--- 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 212  sub get_display_part { Line 200  sub get_display_part {
     return $display;      return $display;
 }  }
   
 #--- Show resource title  
 #--- and parts and response type  
 sub showResourceInfo {  
     my ($symb,$probTitle,$checkboxes,$res_error) = @_;  
     my $result = '<h3>'.&mt('Current Resource').': '.$probTitle.'</h3>'."\n";  
     my ($partlist,$handgrade,$responseType) = &response_type($symb,$res_error);  
     if (ref($res_error)) {  
         if ($$res_error) {  
             return;  
         }  
     }  
     $result.=&Apache::loncommon::start_data_table()  
             .&Apache::loncommon::start_data_table_header_row();  
     if ($checkboxes) {  
         $result.='<th>&nbsp;</th>';  
     }  
     $result.='<th>'.&mt('Problem Part').'</th>'  
             .'<th>'.&mt('Res. ID').'</th>'  
             .'<th>'.&mt('Type').'</th>'  
             .&Apache::loncommon::end_data_table_header_row();  
     my %resptype = ();  
     my $hdgrade='no';  
     my %partsseen;  
     foreach my $partID (sort(keys(%$responseType))) {  
         foreach my $resID (sort(keys(%{ $responseType->{$partID} }))) {  
             my $handgrade=$$handgrade{$partID.'_'.$resID};  
             my $responsetype = $responseType->{$partID}->{$resID};  
             $hdgrade = $handgrade if ($handgrade eq 'yes');  
             $result.=&Apache::loncommon::start_data_table_row();  
             if ($checkboxes) {  
                 if (exists($partsseen{$partID})) {  
                     $result.="<td>&nbsp;</td>";  
                 } else {  
                     $result.="<td><input type='checkbox' name='vPart' value='$partID' checked='checked' /></td>";  
                 }  
                 $partsseen{$partID}=1;  
             }  
             my $display_part=&get_display_part($partID,$symb);  
             $result.='<td>'.$display_part.'</td>'  
                     .'<td>'.'<span class="LC_internal_info">'.$resID.'</span></td>'  
                     .'<td>'.&mt($responsetype).'</td>'  
 #                   .'<td><b>'.&mt('Handgrade: [_1]',$handgrade).'</b></td>'  
                     .&Apache::loncommon::end_data_table_row();  
         }  
     }  
     $result.=&Apache::loncommon::end_data_table();  
     return $result,$responseType,$hdgrade,$partlist,$handgrade;  
 }  
   
 sub reset_caches {  sub reset_caches {
     &reset_analyze_cache();      &reset_analyze_cache();
     &reset_perm();      &reset_perm();
Line 362  sub reset_caches { Line 301  sub reset_caches {
             if ($check_for_randomlist) {              if ($check_for_randomlist) {
                 $add_to_form = { 'check_parts_withrandomlist' => 1,};                  $add_to_form = { 'check_parts_withrandomlist' => 1,};
             }              }
             my $analyze =              my $analyze = 
                 &get_analyze($symb,$uname,$udom,undef,$add_to_form,                  &get_analyze($symb,$uname,$udom,undef,$add_to_form,
                              undef,undef,undef,$bubbles_per_row);                               undef,undef,undef,$bubbles_per_row);
             if (ref($analyze) eq 'HASH') {              if (ref($analyze) eq 'HASH') {
Line 498  sub cleanRecord { Line 437  sub cleanRecord {
     $result.='</ul>';      $result.='</ul>';
     return $result;      return $result;
  }   }
     } elsif ( $response =~ m/(?:numerical|formula)/) {      } elsif ( $response =~ m/(?:numerical|formula|custom)/) {
           # Respect multiple input fields, see Bug #5409
  $answer =    $answer = 
     &Apache::loncommon::format_previous_attempt_value('submission',      &Apache::loncommon::format_previous_attempt_value('submission',
       $answer);        $answer);
Line 509  sub cleanRecord { Line 449  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 538  sub commonJSfunctions { Line 477  sub commonJSfunctions {
     return selectOne.value;      return selectOne.value;
  }   }
     }      }
 </script>  
 COMMONJSFUNCTIONS  COMMONJSFUNCTIONS
 }  }
   
Line 693  sub student_gradeStatus { Line 631  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 797  sub most_similar { Line 733  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 882  sub verifyreceipt { Line 827  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 890  sub verifyreceipt { Line 835  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) = @_;
   
     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='<h3><span class="LC_info">&nbsp;'  
  .&mt("$viewgrade Submissions for a Student or a Group of Students")  
  .'</span></h3>';  
   
     my ($table,undef,$hdgrade,$partlist,$handgrade) = &showResourceInfo($symb,$env{'form.probTitle'},($env{'form.showgrading'} eq 'yes'));      my $result='';
       my $res_error;
       my ($partlist,$handgrade,$responseType) = &response_type($symb,\$res_error);
   
     my %lt = &Apache::lonlocal::texthash (      my %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.',
      );       );
     $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 942  sub listStudents { Line 882  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";
   
     $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'))
Line 966  LISTJAVASCRIPT Line 903  LISTJAVASCRIPT
                   .&Apache::lonhtmlcommon::row_closure();                    .&Apache::lonhtmlcommon::row_closure();
   
     my $submission_options;      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.=      $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".          &mt('last submission').' </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".          &mt('last submission with details').' </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".          &mt('all submissions').'</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>';          &mt('all submissions with details').'</label></span>';
     $gradeTable .= &Apache::lonhtmlcommon::row_title(&mt('Submissions'))      $gradeTable .= &Apache::lonhtmlcommon::row_title(&mt('View Submissions'))
                   .$submission_options                    .$submission_options
                   .&Apache::lonhtmlcommon::row_closure();                    .&Apache::lonhtmlcommon::row_closure();
   
Line 1002  LISTJAVASCRIPT Line 935  LISTJAVASCRIPT
     $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.gradingMenu'}) && exists($env{'form.Status'})) {      if (exists($env{'form.Status'})) {
  $gradeTable .= '<input type="hidden" name="Status" value="'.$stu_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_title(&mt('Student Status'))
Line 1024  LISTJAVASCRIPT Line 953  LISTJAVASCRIPT
                   .&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 1041  LISTJAVASCRIPT Line 970  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 1079  LISTJAVASCRIPT Line 1006  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 1122  LISTJAVASCRIPT Line 1047  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 1136  LISTJAVASCRIPT Line 1061  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 1162  LISTJAVASCRIPT Line 1085  LISTJAVASCRIPT
     if ($submitonly eq 'graded'   ) { $submissions = 'ungraded submissions'; }      if ($submitonly eq 'graded'   ) { $submissions = 'ungraded submissions'; }
     if ($submitonly eq 'queued'   ) { $submissions = 'queued submissions'; }      if ($submitonly eq 'queued'   ) { $submissions = 'queued submissions'; }
     $gradeTable='<br />&nbsp;<span class="LC_warning">'.      $gradeTable='<br />&nbsp;<span class="LC_warning">'.
  &mt('No '.$submissions.' found for this resource for any students. ([_1] students checked for '.$submissions.')',   &mt('No '.$submissions.' found for this resource for any students. ([quant,_1,student] checked for '.$submissions.')',
     $num_students).      $num_students).
  '</span><br />';   '</span><br />';
  }   }
     } 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 1178  LISTJAVASCRIPT Line 1100  LISTJAVASCRIPT
   
 sub check_script {  sub check_script {
     my ($form, $type)=@_;      my ($form, $type)=@_;
     my $chkallscript='<script type="text/javascript">      my $chkallscript= &Apache::lonhtmlcommon::scripttag('
     function checkall() {      function checkall() {
         for (i=0; i<document.forms.'.$form.'.elements.length; i++) {          for (i=0; i<document.forms.'.$form.'.elements.length; i++) {
             ele = document.forms.'.$form.'.elements[i];              ele = document.forms.'.$form.'.elements[i];
Line 1209  sub check_script { Line 1131  sub check_script {
         }          }
     }      }
   
 </script>'."\n";  '."\n");
     return $chkallscript;      return $chkallscript;
 }  }
   
Line 1223  sub check_buttons { Line 1145  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 1233  sub processGroup { Line 1155  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 1248  sub processGroup { Line 1170  sub processGroup {
 sub sub_page_js {  sub sub_page_js {
     my $request = shift;      my $request = shift;
     my $alertmsg = &mt('A number equal or greater than 0 is expected. Entered value = ');      my $alertmsg = &mt('A number equal or greater than 0 is expected. Entered value = ');
     $request->print(<<SUBJAVASCRIPT);      $request->print(&Apache::lonhtmlcommon::scripttag(<<SUBJAVASCRIPT));
 <script type="text/javascript" language="javascript">  
     function updateRadio(formname,id,weight) {      function updateRadio(formname,id,weight) {
  var gradeBox = formname["GD_BOX"+id];   var gradeBox = formname["GD_BOX"+id];
  var radioButton = formname["RADVAL"+id];   var radioButton = formname["RADVAL"+id];
Line 1371  sub sub_page_js { Line 1292  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 1417  sub sub_page_js { Line 1331  sub sub_page_js {
   
  formname.submit();   formname.submit();
     }      }
 </script>  
 SUBJAVASCRIPT  SUBJAVASCRIPT
 }  }
   
Line 1427  sub sub_page_kw_js { Line 1340  sub sub_page_kw_js {
     my $iconpath = $request->dir_config('lonIconsURL');      my $iconpath = $request->dir_config('lonIconsURL');
     &commonJSfunctions($request);      &commonJSfunctions($request);
   
     my $inner_js_msg_central=<<INNERJS;      my $inner_js_msg_central= (<<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 1465  sub sub_page_kw_js { Line 1378  sub sub_page_kw_js {
       self.close()        self.close()
   
     }      }
     </script>  </script>
 INNERJS  INNERJS
   
     my $inner_js_highlight_central=<<INNERJS;      my $inner_js_highlight_central= (<<INNERJS);
  <script type="text/javascript">  <script type="text/javascript">
     function updateChoice(flag) {      function updateChoice(flag) {
       opener.document.SCORE.kwclr.value = opener.radioSelection(document.hlCenter.kwdclr);        opener.document.SCORE.kwclr.value = opener.radioSelection(document.hlCenter.kwdclr);
       opener.document.SCORE.kwsize.value = opener.radioSelection(document.hlCenter.kwdsize);        opener.document.SCORE.kwsize.value = opener.radioSelection(document.hlCenter.kwdsize);
Line 1519  INNERJS Line 1432  INNERJS
                 txtc => 'Text Color',                  txtc => 'Text Color',
                 font => 'Font Size',                  font => 'Font Size',
                 fnst => 'Font Style',                  fnst => 'Font Style',
                   col1 => 'red',
                   col2 => 'green',
                   col3 => 'blue',
                   siz1 => 'normal',
                   siz2 => '+1',
                   siz3 => '+2',
                   sty1 => 'normal',
                   sty2 => 'italic',
                   sty3 => 'bold',
              );               );
     $request->print(<<SUBJAVASCRIPT);      $request->print(&Apache::lonhtmlcommon::scripttag(<<SUBJAVASCRIPT));
 <script type="text/javascript" language="javascript">  
   
 //===================== Show list of keywords ====================  //===================== Show list of keywords ====================
   function keywords(formname) {    function keywords(formname) {
Line 1635  INNERJS Line 1556  INNERJS
   
     pDoc.write("<form action=\\"inactive\\" name=\\"msgcenter\\">");      pDoc.write("<form action=\\"inactive\\" name=\\"msgcenter\\">");
     pDoc.write("<input value=\\""+usrctr+"\\" name=\\"usrctr\\" type=\\"hidden\\">");      pDoc.write("<input value=\\""+usrctr+"\\" name=\\"usrctr\\" type=\\"hidden\\">");
     pDoc.write("<h3><span class=\\"LC_info\\">&nbsp;$lt{'comp'}\"+fullname+\"<\\/span><\\/h3><br /><br />");      pDoc.write("<h1>&nbsp;$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>$lt{'incl'}<\\/b><\\/td><td><b>$lt{'type'}<\\/b><\\/td><td><b>$lt{'mesa'}<\\/td><\\/tr>");
     pDoc.write("<td><b>$lt{'type'}<\\/b><\\/td><td><b>$lt{'incl'}<\\/b><\\/td><td><b>$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>$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>$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\\">$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\\">$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("<\\/table>");
     pDoc.write("<\\/td><\\/tr><\\/table>&nbsp;");      pDoc.write("<\\/td><\\/tr><\\/table>&nbsp;");
     pDoc.write("<input type=\\"button\\" value=\\"$lt{'save'}\\" onclick=\\"javascript:checkInput()\\">&nbsp;&nbsp;");      pDoc.write("<input type=\\"button\\" value=\\"$lt{'save'}\\" onclick=\\"javascript:checkInput()\\">&nbsp;&nbsp;");
     pDoc.write("<input type=\\"button\\" value=\\"$lt{'canc'}\\" onclick=\\"self.close()\\"><br /><br />");      pDoc.write("<input type=\\"button\\" value=\\"$lt{'canc'}\\" onclick=\\"self.close()\\"><br /><br />");
Line 1684  INNERJS Line 1604  INNERJS
     var redsel = "";      var redsel = "";
     var grnsel = "";      var grnsel = "";
     var blusel = "";      var blusel = "";
     if (kwclr=="red")   {var redsel="checked"};      var txtcol1 = "$lt{'col1'}";
     if (kwclr=="green") {var grnsel="checked"};      var txtcol2 = "$lt{'col2'}";
     if (kwclr=="blue")  {var blusel="checked"};      var txtcol3 = "$lt{'col3'}";
       var txtsiz1 = "$lt{'siz1'}";
       var txtsiz2 = "$lt{'siz2'}";
       var txtsiz3 = "$lt{'siz3'}";
       var txtsty1 = "$lt{'sty1'}";
       var txtsty2 = "$lt{'sty2'}";
       var txtsty3 = "$lt{'sty3'}";
       if (kwclr=="red")   {var redsel="checked='checked'"};
       if (kwclr=="green") {var grnsel="checked='checked'"};
       if (kwclr=="blue")  {var blusel="checked='checked'"};
     var sznsel = "";      var sznsel = "";
     var sz1sel = "";      var sz1sel = "";
     var sz2sel = "";      var sz2sel = "";
     if (kwsize=="0")  {var sznsel="checked"};      if (kwsize=="0")  {var sznsel="checked='checked'"};
     if (kwsize=="+1") {var sz1sel="checked"};      if (kwsize=="+1") {var sz1sel="checked='checked'"};
     if (kwsize=="+2") {var sz2sel="checked"};      if (kwsize=="+2") {var sz2sel="checked='checked'"};
     var synsel = "";      var synsel = "";
     var syisel = "";      var syisel = "";
     var sybsel = "";      var sybsel = "";
     if (kwstyle=="")    {var synsel="checked"};      if (kwstyle=="")    {var synsel="checked='checked'"};
     if (kwstyle=="<i>") {var syisel="checked"};      if (kwstyle=="<i>") {var syisel="checked='checked'"};
     if (kwstyle=="<b>") {var sybsel="checked"};      if (kwstyle=="<b>") {var sybsel="checked='checked'"};
     highlightCentral();      highlightCentral();
     highlightbody('red','red',redsel,'0','normal',sznsel,'','normal',synsel);      highlightbody('red',txtcol1,redsel,'0',txtsiz1,sznsel,'',txtsty1,synsel);
     highlightbody('green','green',grnsel,'+1','+1',sz1sel,'<i>','italic',syisel);      highlightbody('green',txtcol2,grnsel,'+1',txtsiz2,sz1sel,'<i>',txtsty2,syisel);
     highlightbody('blue','blue',blusel,'+2','+2',sz2sel,'<b>','bold',sybsel);      highlightbody('blue',txtcol3,blusel,'+2',txtsiz3,sz2sel,'<b>',txtsty3,sybsel);
     highlightend();      highlightend();
     return;      return;
   }    }
Line 1720  INNERJS Line 1649  INNERJS
     hDoc.$docopen;      hDoc.$docopen;
     hDoc.write('$start_page_highlight_central');      hDoc.write('$start_page_highlight_central');
     hDoc.write("<form action=\\"inactive\\" name=\\"hlCenter\\">");      hDoc.write("<form action=\\"inactive\\" name=\\"hlCenter\\">");
     hDoc.write("<h3><span class=\\"LC_info\\">&nbsp;$lt{'kehi'}<\\/span><\\/h3><br /><br />");      hDoc.write("<h1>$lt{'kehi'}<\\/h1>");
   
     hDoc.write('<table border="0" width="100%"><tr><td bgcolor="#777777">');      hDoc.write('<table border="0" width="100%"><tr style="background-color:#A1D676">');
     hDoc.write('<table border="0" width="100%"><tr bgcolor="#DDFFFF">');      hDoc.write("<th>$lt{'txtc'}<\\/th><th>$lt{'font'}<\\/th><th>$lt{'fnst'}<\\/th><\\/tr>");
     hDoc.write("<td><b>$lt{'txtc'}<\\/b><\\/td><td><b>$lt{'font'}<\\/b><\\/td><td><b>$lt{'fnst'}<\\/td><\\/tr>");  
   }    }
   
   function highlightbody(clrval,clrtxt,clrsel,szval,sztxt,szsel,syval,sytxt,sysel) {     function highlightbody(clrval,clrtxt,clrsel,szval,sztxt,szsel,syval,sytxt,sysel) { 
     var hDoc = hwdWin.document;      var hDoc = hwdWin.document;
     hDoc.write("<tr bgcolor=\\"#ffffdd\\">");      hDoc.write("<tr>");
     hDoc.write("<td align=\\"left\\">");      hDoc.write("<td align=\\"left\\">");
     hDoc.write("<input name=\\"kwdclr\\" type=\\"radio\\" value=\\""+clrval+"\\" "+clrsel+">&nbsp;"+clrtxt+"<\\/td>");      hDoc.write("<input name=\\"kwdclr\\" type=\\"radio\\" value=\\""+clrval+"\\" "+clrsel+" \\/>&nbsp;"+clrtxt+"<\\/td>");
     hDoc.write("<td align=\\"left\\">");      hDoc.write("<td align=\\"left\\">");
     hDoc.write("<input name=\\"kwdsize\\" type=\\"radio\\" value=\\""+szval+"\\" "+szsel+">&nbsp;"+sztxt+"<\\/td>");      hDoc.write("<input name=\\"kwdsize\\" type=\\"radio\\" value=\\""+szval+"\\" "+szsel+" \\/>&nbsp;"+sztxt+"<\\/td>");
     hDoc.write("<td align=\\"left\\">");      hDoc.write("<td align=\\"left\\">");
     hDoc.write("<input name=\\"kwdstyle\\" type=\\"radio\\" value=\\""+syval+"\\" "+sysel+">&nbsp;"+sytxt+"<\\/td>");      hDoc.write("<input name=\\"kwdstyle\\" type=\\"radio\\" value=\\""+syval+"\\" "+sysel+" \\/>&nbsp;"+sytxt+"<\\/td>");
     hDoc.write("<\\/tr>");      hDoc.write("<\\/tr>");
   }    }
   
   function highlightend() {     function highlightend() { 
     var hDoc = hwdWin.document;      var hDoc = hwdWin.document;
     hDoc.write("<\\/table>");      hDoc.write("<\\/table><br \\/>");
     hDoc.write("<\\/td><\\/tr><\\/table>&nbsp;");      hDoc.write("<input type=\\"button\\" value=\\"$lt{'save'}\\" onclick=\\"javascript:updateChoice(1)\\" \\/>&nbsp;&nbsp;");
     hDoc.write("<input type=\\"button\\" value=\\"$lt{'save'}\\" onclick=\\"javascript:updateChoice(1)\\">&nbsp;&nbsp;");      hDoc.write("<input type=\\"button\\" value=\\"$lt{'canc'}\\" onclick=\\"self.close()\\" \\/><br /><br />");
     hDoc.write("<input type=\\"button\\" value=\\"$lt{'canc'}\\" onclick=\\"self.close()\\"><br /><br />");  
     hDoc.write("<\\/form>");      hDoc.write("<\\/form>");
     hDoc.write('$end_page_highlight_central');      hDoc.write('$end_page_highlight_central');
     hDoc.close();      hDoc.close();
   }    }
   
 </script>  
 SUBJAVASCRIPT  SUBJAVASCRIPT
 }  }
   
Line 1839  sub gradeBox { Line 1765  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 1858  sub gradeBox { Line 1785  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) = &response_type($symb,$res_error_pointer);
     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 1980  sub files_exist { Line 1907  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 1992  sub download_all_link { Line 1924  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 ''; }
   #FIXME: Figure out which type of problem this is and provide appropriate download
       &download_all_link($request,$symb);
 }  }
   
 sub build_section_inputs {  sub build_section_inputs {
Line 2010  sub build_section_inputs { Line 1949  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) = @_;
     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);   
       my $probtitle=&Apache::lonnet::gettitle($symb); 
     if ($symb eq '') { $request->print("Unable to handle ambiguous references:."); return ''; }      if ($symb eq '') { $request->print("Unable to handle ambiguous references:."); return ''; }
   
     if (!&canview($usec)) {      if (!&canview($usec)) {
  $request->print('<span class="LC_warning">Unable to view requested student.('.          $request->print(
  $uname.':'.$udom.' in section '.$usec.' in course id '.              '<span class="LC_warning">'.
  $env{'request.course.id'}.')</span>');              &mt('Unable to view requested student.').
  $request->print(&show_grading_menu_form($symb));              ' '.&mt('([_1] in section [_2] in course id [_3])',
                           $uname.':'.$udom,$usec,$env{'request.course.id'}).
               '</span>');
  return;   return;
     }      }
   
Line 2037  sub submission { Line 1979  sub submission {
     # header info      # header info
     if ($counter == 0) {      if ($counter == 0) {
  &sub_page_js($request);   &sub_page_js($request);
  &sub_page_kw_js($request) if ($env{'form.handgrade'} eq 'yes');   &sub_page_kw_js($request);
  $env{'form.probTitle'} = $env{'form.probTitle'} eq '' ?   
     &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 2064  sub submission { Line 1999  sub submission {
  # kwclr is the only variable that is guaranteed not to be blank    # kwclr is the only variable that is guaranteed not to be blank 
         # if this subroutine has been called once.          # 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 '' && $env{'form.handgrade'} eq 'yes') {
           if (1) {
     %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'});
Line 2075  sub submission { Line 2011  sub submission {
     $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 '' ?       $env{'form.msgsub'}   = $keyhash{$symb.'_subject'} ne '' ? 
  $keyhash{$symb.'_subject'} : $env{'form.probTitle'};   $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".
  &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.handgrade'} eq 'yes') {
           if (1) {
     $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".
Line 2124  sub submission { Line 2057  sub submission {
  }   }
  $request->print($prnmsg);   $request->print($prnmsg);
   
  if ($env{'form.handgrade'} eq 'yes' && $env{'form.showgrading'} eq 'yes') {  # if ($env{'form.handgrade'} eq 'yes') {
           if (1) {
   
             my %lt = &Apache::lonlocal::texthash(              my %lt = &Apache::lonlocal::texthash(
                             keyh => 'Keyword Highlighting for Essays',
                           keyw => 'Keyword Options',                            keyw => 'Keyword Options',
                           list => 'List',                            list => 'List',
                           past => 'Paste Selection to List',                            past => 'Paste Selection to List',
                           high => 'Highlight Attribute',                            high => 'Highlight Attribute',
                      );                       );    
 #  #
 # Print out the keyword options line  # Print out the keyword options line
 #  #
     $request->print(<<KEYWORDS);      $request->print(
 &nbsp;<b>$lt{'keyw'}:</b>&nbsp;                  '<div class="LC_columnSection">'
 <a href="javascript:keywords(document.SCORE);" target="_self">$lt{'list'}</a>&nbsp; &nbsp;                 .'<fieldset><legend>'.$lt{'keyh'}.'</legend>'
 <a href="#" onmousedown="javascript:getSel(); return false"                 .&Apache::lonhtmlcommon::funclist_from_array(
  class="page">$lt{'past'}</a>&nbsp; &nbsp;                      ['<a href="javascript:keywords(document.SCORE);" target="_self">'.$lt{'list'}.'</a>',
 <a href="javascript:kwhighlight();" target="_self">$lt{'high'}</a><br /><br />                       '<a href="#" onmousedown="javascript:getSel(); return false"
 KEYWORDS   class="page">'.$lt{'past'}.'</a>',
                        '<a href="javascript:kwhighlight();" target="_self">'.$lt{'high'}.'</a>'],
                       {legend => $lt{'keyw'}})
                  .'</fieldset></div>'
               );
   
 #  #
 # Load the other essays for similarity check  # Load the other essays for similarity check
 #  #
Line 2166  KEYWORDS Line 2106  KEYWORDS
     if ($perm{'vgr'}) {      if ($perm{'vgr'}) {
         $request->print(          $request->print(
             &Apache::loncommon::track_student_link(              &Apache::loncommon::track_student_link(
                 &mt('View recent activity'),                  'View recent activity',
                 $uname,$udom,'check')                  $uname,$udom,'check')
            .' '             .' '
         );          );
Line 2207  KEYWORDS Line 2147  KEYWORDS
               .'<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 ($env{'form.handgrade'} eq 'no') {
       if (1) {
         $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";
Line 2216  KEYWORDS Line 2157  KEYWORDS
     # If any part of the problem is an essay-response (handgraded), then check for collaborators      # If any part of the problem is an essay-response (handgraded), then check for collaborators
     my $fullname;      my $fullname;
     my $col_fullnames = [];      my $col_fullnames = [];
     if ($env{'form.handgrade'} eq 'yes') {  #    if ($env{'form.handgrade'} eq 'yes') {
       if (1) {
  (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);
  $result.=$sub_result;   $result.=$sub_result;
     }      }
     $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) Handgraded submission only
     #             (2) Last submission, includes submission that is not handgraded       #             (2) Last submission, includes submission that is not handgraded 
     #                  (for multi-response type part)      #                  (for multi-response type part)
     #             (3) Last submission plus the parts info      #             (3) Last submission plus the parts info
     #             (4) The whole record for this student      #             (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) {
  next if ($env{'form.lastSub'} eq 'hdgrade'       next if ($env{'form.lastSub'} eq 'hdgrade' 
  && $$handgrade{$$part[0].'_'.$$part[1]} ne 'yes');   && $$handgrade{$$part[0].'_'.$$part[1]} ne 'yes');
   
  my ($partid,$respid) = @{ $part };      my ($partid,$respid) = @{ $part };
  my $display_part=&get_display_part($partid,$symb);      my $display_part=&get_display_part($partid,$symb);
  if ($env{"form.$uname:$udom:$partid:submitted_by"}) {      if ($env{"form.$uname:$udom:$partid:submitted_by"}) {
     if (exists($seenparts{$partid})) { next; }   if (exists($seenparts{$partid})) { next; }
     $seenparts{$partid}=1;   $seenparts{$partid}=1;
                     $request->print(                  $request->print(
                         '<b>'.&mt('Part: [_1]',$display_part).'</b>'.                      '<b>'.&mt('Part: [_1]',$display_part).'</b>'.
                         ' <b>'.&mt('Collaborative submission by: [_1]',                      ' <b>'.&mt('Collaborative submission by: [_1]',
                                    '<a href="javascript:viewSubmitter(\''.                                 '<a href="javascript:viewSubmitter(\''.
                                    $env{"form.$uname:$udom:$partid:submitted_by"}.                                 $env{"form.$uname:$udom:$partid:submitted_by"}.
                                    '\');" target="_self">'.                                 '\');" target="_self">'.
                                    $$fullname{$env{"form.$uname:$udom:$partid:submitted_by"}}.'</a>').                                 $$fullname{$env{"form.$uname:$udom:$partid:submitted_by"}}.'</a>').
                         '<br />');                      '<br />');
     next;   next;
  }   }
  my $responsetype = $responseType->{$partid}->{$respid};      my $responsetype = $responseType->{$partid}->{$respid};
  if (!exists($record{"resource.$partid.$respid.submission"})) {      if (!exists($record{"resource.$partid.$respid.submission"})) {
                     $lastsubonly.="\n".'<div class="LC_grade_submission_part">'.                  $lastsubonly.="\n".'<div class="LC_grade_submission_part">'.
                         '<b>'.&mt('Part: [_1]',$display_part).'</b>'.                      '<b>'.&mt('Part: [_1]',$display_part).'</b>'.
                         ' <span class="LC_internal_info">'.                      ' <span class="LC_internal_info">'.
                         '('.&mt('Response ID: [_1]',$respid).')'.                      '('.&mt('Response ID: [_1]',$respid).')'.
                         '</span>&nbsp; &nbsp;'.                      '</span>&nbsp; &nbsp;'.
  '<span class="LC_warning">'.&mt('Nothing submitted - no attempts.').'</span><br /><br /></div>';            '<span class="LC_warning">'.&mt('Nothing submitted - no attempts.').'</span><br /><br /></div>';
     next;   next;
  }      }
  foreach my $submission (@$string) {      foreach my $submission (@$string) {
     my ($partid,$respid) = ($submission =~ /^resource\.([^\.]*)\.([^\.]*)\.submission/);   my ($partid,$respid) = ($submission =~ /^resource\.([^\.]*)\.([^\.]*)\.submission/);
     if (join('_',@{$part}) ne ($partid.'_'.$respid)) { next; }   if (join('_',@{$part}) ne ($partid.'_'.$respid)) { next; }
     my ($ressub,$hide,$subval) = split(/:/,$submission,3);   my ($ressub,$hide,$subval) = split(/:/,$submission,3);
     # Similarity check   # Similarity check
     my $similar='';                  my $similar='';
                     my ($type,$trial,$rndseed);                  my ($type,$trial,$rndseed);
                     if ($hide eq 'rand') {                  if ($hide eq 'rand') {
                         $type = 'randomizetry';                      $type = 'randomizetry';
                         $trial = $record{"resource.$partid.tries"};                      $trial = $record{"resource.$partid.tries"};
                         $rndseed = $record{"resource.$partid.rndseed"};                      $rndseed = $record{"resource.$partid.rndseed"};
                     }                  }
     if ($env{'form.checkPlag'}) {          if ($env{'form.checkPlag'}) {
  my ($oname,$odom,$ocrsid,$oessay,$osim)=         my ($oname,$odom,$ocrsid,$oessay,$osim)=
     &most_similar($uname,$udom,$symb,$subval);          &most_similar($uname,$udom,$symb,$subval);
  if ($osim) {      if ($osim) {
     $osim=int($osim*100.0);   $osim=int($osim*100.0);
     my %old_course_desc =    my %old_course_desc = 
  &Apache::lonnet::coursedescription($ocrsid,      &Apache::lonnet::coursedescription($ocrsid,
    {'one_time' => 1});   {'one_time' => 1});
   
                             if ($hide eq 'anon') {                          if ($hide eq 'anon') {
                                 $similar='<hr /><span class="LC_warning">'.&mt("Essay was found to be similar to another essay submitted for this assignment.").'<br />'.                              $similar='<hr /><span class="LC_warning">'.&mt("Essay was found to be similar to another essay submitted for this assignment.").'<br />'.
                                          &mt('As the current submission is for an anonymous survey, no other details are available.').'</span><hr />';                                       &mt('As the current submission is for an anonymous survey, no other details are available.').'</span><hr />';
                             } else {                          } else {
         $similar="<hr /><h3><span class=\"LC_warning\">".      $similar="<hr /><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><blockquote><i>'.
     &keywords_highlight($oessay).      &keywords_highlight($oessay).
     '</i></blockquote><hr />';      '</i></blockquote><hr />';
                             }                          }
  }              }
     }   }
     my $order=&get_order($partid,$respid,$symb,$uname,$udom,   my $order=&get_order($partid,$respid,$symb,$uname,$udom,
                                          undef,$type,$trial,$rndseed);                                       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' &&                  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')) {   $$handgrade{$$part[0].'_'.$$part[1]} eq 'yes')) {
  my $display_part=&get_display_part($partid,$symb);      my $display_part=&get_display_part($partid,$symb);
                         $lastsubonly.='<div class="LC_grade_submission_part">'.                      $lastsubonly.='<div class="LC_grade_submission_part">'.
                             '<b>'.&mt('Part: [_1]',$display_part).'</b>'.                          '<b>'.&mt('Part: [_1]',$display_part).'</b>'.
                             ' <span class="LC_internal_info">'.                          ' <span class="LC_internal_info">'.
                             '('.&mt('Response ID: [_1]',$respid).')'.                          '('.&mt('Response ID: [_1]',$respid).')'.
                             '</span>&nbsp; &nbsp;';                          '</span>&nbsp; &nbsp;';
  my $files=&get_submitted_files($udom,$uname,$partid,$respid,\%record);      my $files=&get_submitted_files($udom,$uname,$partid,$respid,\%record);
  if (@$files) {                          
                             if ($hide eq 'anon') {      if (@$files) {
                                 $lastsubonly.='<br />'.&mt('[quant,_1,file] uploaded to this anonymous survey',scalar(@{$files}));  
                             } else {  
                                 $lastsubonly.='<br /><br />'.'<b>'.&mt('Submitted Files:').'</b>'  
                                             .'<br /><span class="LC_warning">';  
                                 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!');  
                                 }  
                                 $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 />';  
  }  
                         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>'
         &cleanRecord($subval,$responsetype,$symb,$partid,                                          .'<br /><span class="LC_warning">';
      $respid,\%record,$order,undef,$uname,$udom,$type,$trial,$rndseed);                              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!');
                               }
                               $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>';
                               }
                         }                          }
  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>'.
       &cleanRecord($subval,$responsetype,$symb,$partid,
    $respid,\%record,$order,undef,$uname,$udom,$type,$trial,$rndseed);
                       }
               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(&displaySubByDates($symb,\%record,$parts,$responseType,$checkIcon,$uname,$udom));  
     }      }
       $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));
       } 
     if ($env{'form.lastSub'} =~ /^(last|all)$/) {      if ($env{'form.lastSub'} =~ /^(last|all)$/) {
  $request->print(&Apache::loncommon::get_previous_attempt($symb,$uname,$udom,          $request->print(&Apache::loncommon::get_previous_attempt($symb,$uname,$udom,
  $env{'request.course.id'},   $env{'request.course.id'},
  $last,'.submission',   $last,'.submission',
  'Apache::grades::keywords_highlight'));   'Apache::grades::keywords_highlight'));
     }      }
   
     $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\',\''  
     .$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;   return;
     } else {      } else {
  $request->print('</div>'."\n");   $request->print('</div>'."\n");
     }      }
   
     # essay grading message center      # essay grading message center
     if ($env{'form.handgrade'} eq 'yes') {  #    if ($env{'form.handgrade'} eq 'yes') {
       if (1) {
  my $result='<div class="LC_grade_message_center">';   my $result='<div class="LC_grade_message_center">';
           
  $result.='<div class="LC_grade_message_center_header">'.   $result.='<div class="LC_grade_message_center_header">'.
Line 2406  KEYWORDS Line 2340  KEYWORDS
     &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>';   $result.='</div></div>';
Line 2479  KEYWORDS Line 2413  KEYWORDS
         $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 2603  sub get_last_submission { Line 2536  sub get_last_submission {
             }              }
     my ($partid,$foo) = split(/submission$/,$key);      my ($partid,$foo) = split(/submission$/,$key);
     my $draft  = $lasthash{$partid.'awarddetail'} eq 'DRAFT' ?      my $draft  = $lasthash{$partid.'awarddetail'} eq 'DRAFT' ?
  '<span class="LC_warning">Draft Copy</span> ' : '';   '<span class="LC_warning">'.&mt('Draft Copy').'</span> ' : '';
     push(@string, join(':', $key, $hide, $draft.$lasthash{$key}));      #push(@string, join(':', $key, $hide, $draft.$lasthash{$key}));
               push(@string, join(':', $key, $hide, $draft.(
                   ref($lasthash{$key}) eq 'ARRAY' ?
                       join(',', @{$lasthash{$key}}) : $lasthash{$key}) ));
  }   }
     }      }
     if (!@string) {      if (!@string) {
Line 2632  sub keywords_highlight { Line 2568  sub keywords_highlight {
 sub show_previous_task_version {  sub show_previous_task_version {
     my ($request,$symb) = @_;      my ($request,$symb) = @_;
     if ($symb eq '') {      if ($symb eq '') {
         $request->print("Unable to handle ambiguous references.");          $request->print(
               '<span class="LC_error">'.
               &mt('Unable to handle ambiguous references.').
               '</span>');
         return '';          return '';
     }      }
     my ($uname,$udom) = ($env{'form.student'},$env{'form.userdom'});      my ($uname,$udom) = ($env{'form.student'},$env{'form.userdom'});
     my $usec = &Apache::lonnet::getsection($udom,$uname,$env{'request.course.id'});      my $usec = &Apache::lonnet::getsection($udom,$uname,$env{'request.course.id'});
     if (!&canview($usec)) {      if (!&canview($usec)) {
         $request->print('<span class="LC_warning">Unable to view previous version for requested student.('.          $request->print(
                         $uname.':'.$udom.' in section '.$usec.' in course id '.              '<span class="LC_warning">'.
                         $env{'request.course.id'}.')</span>');              &mt('Unable to view previous version for requested student.').
               ' '.&mt('([_1] in section [_2] in course id [_3])',
                       $uname.':'.$udom,$usec,$env{'request.course.id'}).
               '</span>');
         return;          return;
     }      }
     my $mode = 'both';      my $mode = 'both';
Line 2806  ENDJS Line 2747  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'};
Line 2847  sub processHandGrade { Line 2787  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 2875  sub processHandGrade { Line 2815  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 2887  sub processHandGrade { Line 2827  sub processHandGrade {
  }   }
     }      }
   
     if ($env{'form.handgrade'} eq 'yes') {  #    if ($env{'form.handgrade'} eq 'yes') {
       if (1) {
  # 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 = ();   my %keyhash = ();
Line 2940  sub processHandGrade { Line 2881  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 2975  sub processHandGrade { Line 2906  sub processHandGrade {
  }   }
  return $a cmp $b;   return $a cmp $b;
      } (keys(%$fullname))) {       } (keys(%$fullname))) {
   # FIXME: this is fishy, looks like the button label
  if ($nextflg == 1 && $button =~ /Next$/) {   if ($nextflg == 1 && $button =~ /Next$/) {
     push(@parsedlist,$item);      push(@parsedlist,$item);
  }   }
Line 2985  sub processHandGrade { Line 2917  sub processHandGrade {
  }   }
     }      }
     $ctr = 0;      $ctr = 0;
   # FIXME: this is fishy, looks like the button label
     @parsedlist = reverse @parsedlist if ($button eq 'Previous');      @parsedlist = reverse @parsedlist if ($button eq 'Previous');
     my $res_error;      my $res_error;
     my ($partlist) = &response_type($symb,\$res_error);      my ($partlist) = &response_type($symb,\$res_error);
Line 3037  sub processHandGrade { Line 2970  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 3203  sub handback_files { Line 3133  sub handback_files {
  my $part_resp = join('_',@{ $part_response_id });   my $part_resp = join('_',@{ $part_response_id });
         if (($env{'form.'.$newflg.'_'.$part_resp.'_countreturndoc'} =~ /^\d+$/) & ($new_part eq $part_id)) {          if (($env{'form.'.$newflg.'_'.$part_resp.'_countreturndoc'} =~ /^\d+$/) & ($new_part eq $part_id)) {
             for (my $counter=1; $counter<=$env{'form.'.$newflg.'_'.$part_resp.'_countreturndoc'}; $counter++) {              for (my $counter=1; $counter<=$env{'form.'.$newflg.'_'.$part_resp.'_countreturndoc'}; $counter++) {
                 # if multiple files are uploaded names will be 'returndoc2','returndoc3'                  # if multiple files are uploaded names will be 'returndoc2','returndoc3' 
  if ($env{'form.'.$newflg.'_'.$part_resp.'_returndoc'.$counter}) {                  if ($env{'form.'.$newflg.'_'.$part_resp.'_returndoc'.$counter}) {
                     my $fname=$env{'form.'.$newflg.'_'.$part_resp.'_returndoc'.$counter.'.filename'};                      my $fname=$env{'form.'.$newflg.'_'.$part_resp.'_returndoc'.$counter.'.filename'};
                     my ($directory,$answer_file) =                       my ($directory,$answer_file) = 
                         ($env{'form.'.$newflg.'_'.$part_resp.'_origdoc'.$counter} =~ /^(.*?)([^\/]*)$/);                          ($env{'form.'.$newflg.'_'.$part_resp.'_origdoc'.$counter} =~ /^(.*?)([^\/]*)$/);
Line 3212  sub handback_files { Line 3142  sub handback_files {
         &file_name_version_ext($answer_file);          &file_name_version_ext($answer_file);
     my ($portfolio_path) = ($directory =~ /^.+$stuname\/portfolio(.*)/);      my ($portfolio_path) = ($directory =~ /^.+$stuname\/portfolio(.*)/);
                     my $getpropath = 1;                      my $getpropath = 1;
                     my ($dir_list,$listerror) =                      my ($dir_list,$listerror) = 
                         &Apache::lonnet::dirlist($portfolio_root.$portfolio_path,                          &Apache::lonnet::dirlist($portfolio_root.$portfolio_path,
                                                  $domain,$stuname,$getpropath);                                                   $domain,$stuname,$getpropath);
     my $version = &get_next_version($answer_name,$answer_ext,$dir_list);      my $version = &get_next_version($answer_name,$answer_ext,$dir_list);
Line 3233  sub handback_files { Line 3163  sub handback_files {
     $$newrecord{"resource.$new_part.$resp_id.handback"}.=',';      $$newrecord{"resource.$new_part.$resp_id.handback"}.=',';
  }   }
                         $$newrecord{"resource.$new_part.$resp_id.handback"} .= $save_file_name;                          $$newrecord{"resource.$new_part.$resp_id.handback"} .= $save_file_name;
  $file_msg.='<span class="LC_filename"><a href="/uploaded/'."$domain/$stuname/".$save_file_name.'">'.$save_file_name."</a></span> <br />";   $file_msg.= '<span class="LC_filename"><a href="/uploaded/'."$domain/$stuname/".$save_file_name.'">'.$save_file_name."</a></span> <br />";
   
                     }                      }
                     $request->print('<br />'.&mt('[_1] will be the uploaded filename [_2]','<span class="LC_info">'.$fname.'</span>','<span class="LC_filename">'.$env{'form.'.$newflg.'_'.$part_resp.'_origdoc'.$counter}.'</span>'));                      $request->print('<br />'.&mt('[_1] will be the uploaded filename [_2]','<span class="LC_info">'.$fname.'</span>','<span class="LC_filename">'.$env{'form.'.$newflg.'_'.$part_resp.'_origdoc'.$counter}.'</span>'));
                 }                  }
Line 3245  sub handback_files { Line 3174  sub handback_files {
         $request->print('<br />');          $request->print('<br />');
         my @what = ($symb,$env{'request.course.id'},'handback');          my @what = ($symb,$env{'request.course.id'},'handback');
         &Apache::lonnet::mark_as_readonly($domain,$stuname,\@handedback,\@what);          &Apache::lonnet::mark_as_readonly($domain,$stuname,\@handedback,\@what);
         my $user_lh = &Apache::loncommon::user_lang($stuname,$domain,$env{'request.course.id'});          my $user_lh = &Apache::loncommon::user_lang($stuname,$domain,$env{'request.course.id'});    
         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 3375  sub version_portfiles { Line 3305  sub version_portfiles {
                 my ($directory,$answer_file) =($file =~ /^(.*?)([^\/]*)$/);                  my ($directory,$answer_file) =($file =~ /^(.*?)([^\/]*)$/);
  my ($answer_name,$answer_ver,$answer_ext) =   my ($answer_name,$answer_ver,$answer_ext) =
     &file_name_version_ext($answer_file);      &file_name_version_ext($answer_file);
                 my $getpropath = 1;                  my $getpropath = 1;    
                 my ($dir_list,$listerror) =                  my ($dir_list,$listerror) = 
                     &Apache::lonnet::dirlist($portfolio_root.$directory,$domain,                      &Apache::lonnet::dirlist($portfolio_root.$directory,$domain,
                                              $stu_name,$getpropath);                                               $stu_name,$getpropath);
                 my $version = &get_next_version($answer_name,$answer_ext,$dir_list);                  my $version = &get_next_version($answer_name,$answer_ext,$dir_list);
Line 3405  sub get_next_version { Line 3335  sub get_next_version {
         &file_name_version_ext($file);          &file_name_version_ext($file);
             if (($file_name eq $answer_name) &&               if (($file_name eq $answer_name) && 
         ($file_ext eq $answer_ext)) {          ($file_ext eq $answer_ext)) {
                 # gets here if filename and extension match,                        # gets here if filename and extension match, 
                 # regardless of version                       # regardless of version
                 if ($file_version ne '') {                  if ($file_version ne '') {
                     # a versioned file is found  so save it for later                      # a versioned file is found  so save it for later
                     if ($file_version > $version) {                      if ($file_version > $version) {
         $version = $file_version;          $version = $file_version;
                     }              }
         }                  }
             }              }
         }          }
     }      }
Line 3462  sub viewgrades_js { Line 3392  sub viewgrades_js {
     my ($request) = shift;      my ($request) = shift;
   
     my $alertmsg = &mt('A number equal or greater than 0 is expected. Entered value = ');      my $alertmsg = &mt('A number equal or greater than 0 is expected. Entered value = ');
     $request->print(<<VIEWJAVASCRIPT);      $request->print(&Apache::lonhtmlcommon::scripttag(<<VIEWJAVASCRIPT));
 <script type="text/javascript" language="javascript">  
    function writePoint(partid,weight,point) {     function writePoint(partid,weight,point) {
  var radioButton = document.classgrade["RADVAL_"+partid];   var radioButton = document.classgrade["RADVAL_"+partid];
  var textbox = document.classgrade["TEXTVAL_"+partid];   var textbox = document.classgrade["TEXTVAL_"+partid];
Line 3624  sub viewgrades_js { Line 3553  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 3642  sub viewgrades { Line 3569  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 3653  sub viewgrades { Line 3579  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";  
   
     my ($common_header,$specific_header);      my ($common_header,$specific_header);
     if ($env{'form.section'} eq 'all') {      if ($env{'form.section'} eq 'all') {
Line 3705  sub viewgrades { Line 3629  sub viewgrades {
     $partid.'" size="4" '.'onchange="javascript:writePoint(\''.      $partid.'" size="4" '.'onchange="javascript:writePoint(\''.
  $partid.'\','.$weight{$partid}.',\'textval\')" /> /'.   $partid.'\','.$weight{$partid}.',\'textval\')" /> /'.
     $weight{$partid}.' '.&mt('(problem weight)').'</td>'."\n";      $weight{$partid}.' '.&mt('(problem weight)').'</td>'."\n";
  $line.= '<td><b>'.&mt('Grade Status').':</b>'.          $line.= '<td><b>'.&mt('Grade Status').':</b>'.
                 '<select name="SELVAL_'.$partid.'" '.              '<select name="SELVAL_'.$partid.'" '.
         'onchange="javascript:writeRadText(\''.$partid.'\','.              'onchange="javascript:writeRadText(\''.$partid.'\','.
  $weight{$partid}.')"> '.                  $weight{$partid}.')"> '.
     '<option selected="selected"> </option>'.      '<option selected="selected"> </option>'.
     '<option value="excused">'.&mt('excused').'</option>'.      '<option value="excused">'.&mt('excused').'</option>'.
     '<option value="reset status">'.&mt('reset status').'</option>'.      '<option value="reset status">'.&mt('reset status').'</option>'.
Line 3751  sub viewgrades { Line 3675  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>'.
                 &mt('Score Part: [_1][_2](weight = [_3])',   &mt('Score Part: [_1][_2](weight = [_3])',
                     $display_part,'<br />',$weight{$partid}).'</th>'."\n";      $display_part,'<br />',$weight{$partid}).'</th>'."\n";
     next;      next;
           
  } else {   } else {
Line 3802  sub viewgrades { Line 3729  sub viewgrades {
         $section_display, $stu_status).          $section_display, $stu_status).
     '</span>';      '</span>';
     }      }
     $result.=&show_grading_menu_form($symb);  
     return $result;      return $result;
 }  }
   
Line 3874  sub viewstudentgrade { Line 3800  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>'.&mt('<b>Section: </b>[_1]',$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().
  &Apache::loncommon::start_data_table_header_row().   &Apache::loncommon::start_data_table_header_row().
Line 4087  sub editgrades { Line 4011  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 4201  sub csvuploadmap_header { Line 4124  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 $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>  
 <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" />
 <input type="hidden" name="datatoken"  value="$datatoken" />  <input type="hidden" name="datatoken"  value="$datatoken" />
Line 4224  to this page if the data selected is ins Line 4140  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 4277  ENDPICK Line 4189  ENDPICK
   
 sub checkforfile_js {  sub checkforfile_js {
     my $alertmsg = &mt('Please use the browse button to select a file from your local directory.');      my $alertmsg = &mt('Please use the browse button to select a file from your local directory.');
     my $result =<<CSVFORMJS;      my $result = &Apache::lonhtmlcommon::scripttag(<<CSVFORMJS);
 <script type="text/javascript" language="javascript">  
     function checkUpload(formname) {      function checkUpload(formname) {
  if (formname.upfile.value == "") {   if (formname.upfile.value == "") {
     alert("$alertmsg");      alert("$alertmsg");
Line 4286  sub checkforfile_js { Line 4197  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 4312  sub upcsvScores_form { Line 4218  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>  
 </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 4341  sub csvuploadmap { Line 4243  sub csvuploadmap {
  &Apache::loncommon::load_tmp_file($request);   &Apache::loncommon::load_tmp_file($request);
     }      }
     my @records=&Apache::loncommon::upfile_record_sep();      my @records=&Apache::loncommon::upfile_record_sep();
     if ($env{'form.noFirstLine'}) { shift(@records); }  
     &csvuploadmap_header($request,$symb,$datatoken,$#records+1);      &csvuploadmap_header($request,$symb,$datatoken,$#records+1);
     my ($i,$keyfields);      my ($i,$keyfields);
     if (@records) {      if (@records) {
Line 4371  sub csvuploadmap { Line 4272  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 $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 4416  ENDPICK Line 4305  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 4438  sub get_fields { Line 4326  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 = '';
     &Apache::loncommon::load_tmp_file($request);      &Apache::loncommon::load_tmp_file($request);
     my @gradedata = &Apache::loncommon::upfile_record_sep();      my @gradedata = &Apache::loncommon::upfile_record_sep();
     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 4501  sub csvuploadassign { Line 4386  sub csvuploadassign {
                     my $award=($pcr == 0) ? 'incorrect_by_override'                      my $award=($pcr == 0) ? 'incorrect_by_override'
                                           : 'correct_by_override';                                            : 'correct_by_override';
                     if ($pcr>1) {                      if ($pcr>1) {
                         push(@warnings,&mt("[_1]: point value larger than weight","$username:$domain"));                         push(@warnings,&mt("[_1]: point value larger than weight","$username:$domain"));
                     }                      }
                     $grades{"resource.$part.awarded"}=$pcr;                      $grades{"resource.$part.awarded"}=$pcr;
                     $grades{"resource.$part.solved"}=$award;                      $grades{"resource.$part.solved"}=$award;
Line 4530  sub csvuploadassign { Line 4415  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,
                                              $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'},
                                              $domain,$username);                                               $domain,$username);
    } else {                $countdone++;
              } else {
       $request->print("<p><span class=\"LC_error\">".        $request->print("<p><span class=\"LC_error\">".
                               &mt("Failed to save data for student [_1]. Message when trying to save was: [_2]",                                &mt("Failed to save data for student [_1]. Message when trying to save was: [_2]",
                                   "$username:$domain",$result)."</span></p>");                                    "$username:$domain",$result)."</span></p>");
    }     }
    $request->rflush();     $request->rflush();
    $countdone++;  
         }          }
     }      }
     $request->print('<br />'.&Apache::lonhtmlcommon::confirm_success(&mt("Saved scores for [quant,_1,student]",$countdone),$countdone==0));      $request->print('<br />'.&Apache::lonhtmlcommon::confirm_success(&mt("Saved scores for [quant,_1,student]",$countdone),$countdone==0));
Line 4559  sub csvuploadassign { Line 4445  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 4570  sub csvuploadassign { Line 4455  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.');
     $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 4587  function checkPickOne(formname) { Line 4471  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'};
Line 4608  LISTJAVASCRIPT Line 4491  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";  
       # Collection of hidden fields
     my $ctr=0;      my $ctr=0;
     foreach (@$titles) {      foreach (@$titles) {
  my ($minder,$showtitle) = ($_ =~ /(\d+)\.(.*)/);          my ($minder,$showtitle) = ($_ =~ /(\d+)\.(.*)/);
  $select.='<option value="'.$ctr.'" '.          $result.='<input type="hidden" name="page'.$ctr.'" value="'.$$symbx{$_}.'" />'."\n";
     ($$symbx{$_} =~ /$curpage$/ ? 'selected="selected"' : '').          $result.='<input type="hidden" name="title'.$ctr.'" value="'.$showtitle.'" />'."\n";
     '>'.$showtitle.'</option>'."\n";          $ctr++;
  $ctr++;  
     }      }
     $select.= '</select>';      $result.='<input type="hidden" name="page" />'."\n".
     $result.='&nbsp;<b>'.&mt('Problems from').':</b> '.$select."<br />\n";          '<input type="hidden" name="title" />'."\n";
   
       $result.=&build_section_inputs();
       my $stu_status = join(':',&Apache::loncommon::get_env_multiple('form.Status'));
       $result.='<input type="hidden" name="Status"  value="'.$stu_status.'" />'."\n".
    '<input type="hidden" name="command" value="displayPage" />'."\n".
    '<input type="hidden" name="symb"    value="'.&Apache::lonenc::check_encrypt($symb).'" />'."\n";
   
       # Show grading options
       $result.=&Apache::lonhtmlcommon::start_pick_box();
       my $select = '<select name="selectpage">'."\n";
     $ctr=0;      $ctr=0;
     foreach (@$titles) {      foreach (@$titles) {
  my ($minder,$showtitle) = ($_ =~ /(\d+)\.(.*)/);   my ($minder,$showtitle) = ($_ =~ /(\d+)\.(.*)/);
  $result.='<input type="hidden" name="page'.$ctr.'" value="'.$$symbx{$_}.'" />'."\n";   $select.='<option value="'.$ctr.'"'.
  $result.='<input type="hidden" name="title'.$ctr.'" value="'.$showtitle.'" />'."\n";      ($$symbx{$_} =~ /$curpage$/ ? ' selected="selected"' : '').
       '>'.$showtitle.'</option>'."\n";
  $ctr++;   $ctr++;
     }      }
     $result.='<input type="hidden" name="page" />'."\n".      $select.= '</select>';
  '<input type="hidden" name="title" />'."\n";  
   
     my $options =      $result.=
  '<label><input type="radio" name="vProb" value="no" checked="checked" /> '.&mt('no').' </label>'."\n".          &Apache::lonhtmlcommon::row_title(&mt('Problems from'))
  '<label><input type="radio" name="vProb" value="yes" /> '.&mt('yes').' </label>'."<br />\n";         .$select
     $result.='&nbsp;<b>'.&mt('View Problem Text').': </b>'.$options;         .&Apache::lonhtmlcommon::row_closure();
   
     $options =      $result.=
  '<label><input type="radio" name="lastSub" value="none" /> '.&mt('none').' </label>'."\n".          &Apache::lonhtmlcommon::row_title(&mt('View Problem Text'))
  '<label><input type="radio" name="lastSub" value="datesub" checked="checked" /> '.&mt('by dates and submissions').'</label>'."\n".         .'<label><input type="radio" name="vProb" value="no"'
  '<label><input type="radio" name="lastSub" value="all" /> '.&mt('all details').' </label>'."\n";             .' checked="checked" /> '.&mt('no').' </label>'."\n"
     $result.='&nbsp;<b>'.&mt('Submissions').': </b>'.$options;         .'<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.=&build_section_inputs();      $result.=
     my $stu_status = join(':',&Apache::loncommon::get_env_multiple('form.Status'));          &Apache::lonhtmlcommon::row_title(&mt('Use CODE'))
     $result.='<input type="hidden" name="Status"  value="'.$stu_status.'" />'."\n".         .'<input type="text" name="CODE" value="" />'
  '<input type="hidden" name="command" value="displayPage" />'."\n".         .&Apache::lonhtmlcommon::row_closure(1)
  '<input type="hidden" name="symb"    value="'.&Apache::lonenc::check_encrypt($symb).'" />'."\n".         .&Apache::lonhtmlcommon::end_pick_box();
  '<input type="hidden" name="saveState" value="'.$env{'form.saveState'}.'" />'."<br />\n";  
   
     $result.='&nbsp;<b>'.&mt('Use CODE').': </b> <input type="text" name="CODE" value="" /> <br />'."\n";      # Show list of students to select for grading
       $result.='<br /><input type="button" '.
     $result.='&nbsp;<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 4692  LISTJAVASCRIPT Line 4594  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 4729  sub getSymbMap { Line 4630  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 4748  sub displayPage { Line 4647  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">'.&mt('Unable to view requested student. ([_1])',$env{'form.student'}).'</span>');          $request->print(
  $request->print(&show_grading_menu_form($symb));              '<span class="LC_warning">'.
  return;              &mt('Unable to view requested student. ([_1])',
                       $env{'form.student'}).
               '</span>');
           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>';
     $result.='<h3>&nbsp;'.&mt('Student: [_1]',&nameUserString(undef,$$fullname{$env{'form.student'}},$uname,$udom)).      $result.='<h3>&nbsp;'.&mt('Student: [_1]',&nameUserString(undef,$$fullname{$env{'form.student'}},$uname,$udom)).
Line 4767  sub displayPage { Line 4669  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 4787  sub displayPage { Line 4687  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 4802  sub displayPage { Line 4701  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 4890  sub displayPage { Line 4789  sub displayPage {
         '<input type="button" value="'.&mt('Save').'" '.          '<input type="button" value="'.&mt('Save').'" '.
         '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 4982  sub displaySubByDates { Line 4880  sub displaySubByDates {
                                     $newvariation = '&nbsp;('.&mt('New variation this try').')';                                      $newvariation = '&nbsp;('.&mt('New variation this try').')';
                                 }                                  }
                             }                              }
                               $lastrndseed{$partid} = $rndseed;
         }          }
         my $responseType=($isTask ? 'Task'          my $responseType=($isTask ? 'Task'
                                               : $responseType->{$partid}->{$responseId});                                                : $responseType->{$partid}->{$responseId});
Line 5034  sub displaySubByDates { Line 4933  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 5045  sub updateGradeByPage { Line 4944  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 5064  sub updateGradeByPage { Line 4962  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 5191  sub updateGradeByPage { Line 5087  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));    $changeflag));
Line 5269  the homework problem. Line 5164  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 5553  sub scantron_CODEunique { Line 5446  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 5563  sub scantron_selectphase { Line 5455  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 5575  sub scantron_selectphase { Line 5466  sub scantron_selectphase {
     if (&Apache::lonnet::allowed('usc',$env{'request.role.domain'}) ||      if (&Apache::lonnet::allowed('usc',$env{'request.role.domain'}) ||
         &Apache::lonnet::allowed('usc',$env{'request.course.id'})) {          &Apache::lonnet::allowed('usc',$env{'request.course.id'})) {
   
         # Chunk of form to prompt for a scantron file upload.   # Chunk of form to prompt for a scantron file upload.
   
         $r->print('          $r->print('
     <br />      <br />
Line 5588  sub scantron_selectphase { Line 5479  sub scantron_selectphase {
        '.&Apache::loncommon::start_data_table_row().'         '.&Apache::loncommon::start_data_table_row().'
             <td>              <td>
 ');  ');
     my $default_form_data=&defaultFormData(&get_symb($r,1));      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'};
     $r->print('      $r->print(&Apache::lonhtmlcommon::scripttag('
               <script type="text/javascript" language="javascript">  
     function checkUpload(formname) {      function checkUpload(formname) {
         if (formname.upfile.value == "") {   if (formname.upfile.value == "") {
             alert("'.&mt('Please use the browse button to select a file from your local directory.').'");      alert("'.&mt('Please use the browse button to select a file from your local directory.').'");
             return false;      return false;
         }   }
         formname.submit();   formname.submit();
     }      }'));
               </script>      $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 5667  sub scantron_selectphase { Line 5556  sub scantron_selectphase {
         
     $r->print($result);      $r->print($result);
   
   
   
     # Chunk of the form that prompts to view a scoring office file,      # Chunk of the form that prompts to view a scoring office file,
     # corrected file, skipped records in a file.      # corrected file, skipped records in a file.
   
Line 5725  sub scantron_selectphase { Line 5616  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 5733  sub scantron_selectphase { Line 5623  sub scantron_selectphase {
   
 =item get_scantron_config  =item get_scantron_config
   
    Parse and return the scantron configuration line selected as a     Parse and return the bubblesheet configuration line selected as a
    hash of configuration file fields.     hash of configuration file fields.
   
  Arguments:   Arguments:
Line 5783  sub scantron_selectphase { Line 5673  sub scantron_selectphase {
     
       LastName    - column that the last name starts in        LastName    - column that the last name starts in
       LastNameLength - number of columns that the last name spans        LastNameLength - number of columns that the last name spans
       BubblesPerRow - number of bubbles available in each row used to        BubblesPerRow - number of bubbles available in each row used to 
                       bubble an answer. (If not specified, 10 assumed).                        bubble an answer. (If not specified, 10 assumed).
   
 =cut  =cut
Line 6017  sub digits_to_letters { Line 5907  sub digits_to_letters {
   
 =item scantron_parse_scanline  =item scantron_parse_scanline
   
   Decodes a scanline from the selected scantron file    Decodes a scanline from the selected bubblesheet file
   
  Arguments:   Arguments:
     line             - The text of the scantron file line to process      line             - The text of the bubblesheet file line to process
     whichline        - Line number      whichline        - Line number
     scantron_config  - Hash describing the format of the scantron lines.      scantron_config  - Hash describing the format of the bubblesheet lines.
     scan_data        - Hash of extra information about the scanline      scan_data        - Hash of extra information about the scanline
                        (see scantron_getfile for more information)                         (see scantron_getfile for more information)
     just_header      - True if should not process question answers but only      just_header      - True if should not process question answers but only
Line 6047  sub digits_to_letters { Line 5937  sub digits_to_letters {
     totalref         - Ref of scalar used to score total number of bubble      totalref         - Ref of scalar used to score total number of bubble
                        lines needed for responses in a scan line (used when                         lines needed for responses in a scan line (used when
                        randompick in use.                          randompick in use. 
       
  Returns:   Returns:
    Hash containing the result of parsing the scanline     Hash containing the result of parsing the scanline
   
Line 6140  sub scantron_parse_scanline { Line 6030  sub scantron_parse_scanline {
                                          $partids_by_symb,$orderedforcode,                                           $partids_by_symb,$orderedforcode,
                                          $respnumlookup,$startline);                                           $respnumlookup,$startline);
         if ($total) {          if ($total) {
             $lastpos = $total*$$scantron_config{'Qlength'};              $lastpos = $total*$$scantron_config{'Qlength'}; 
         }          }
         if (ref($totalref)) {          if (ref($totalref)) {
             $$totalref = $total;              $$totalref = $total;
Line 6154  sub scantron_parse_scanline { Line 6044  sub scantron_parse_scanline {
         if (($randompick || $randomorder) && (ref($respnumlookup) eq 'HASH')) {          if (($randompick || $randomorder) && (ref($respnumlookup) eq 'HASH')) {
             $answers_needed = $bubble_lines_per_response{$respnumlookup->{$questnum}};              $answers_needed = $bubble_lines_per_response{$respnumlookup->{$questnum}};
         } else {          } else {
             $answers_needed = $bubble_lines_per_response{$questnum};      $answers_needed = $bubble_lines_per_response{$questnum};
         }          }
         my $answer_length  = ($$scantron_config{'Qlength'} * $answers_needed)          my $answer_length  = ($$scantron_config{'Qlength'} * $answers_needed)
                              || 1;                               || 1;
Line 6215  sub scantron_parse_scanline { Line 6105  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) = @_;
     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'));
     my $resource_error;      my $resource_error;
     foreach my $resource (@{$resources}) {      foreach my $resource (@{$resources}) {
Line 6293  sub scantron_validator_lettnum { Line 6183  sub scantron_validator_lettnum {
     my $occurrences = 0;      my $occurrences = 0;
     my $responsenum = $questnum-1;      my $responsenum = $questnum-1;
     if (($randompick || $randomorder) && (ref($respnumlookup) eq 'HASH')) {      if (($randompick || $randomorder) && (ref($respnumlookup) eq 'HASH')) {
        $responsenum = $respnumlookup->{$questnum-1}         $responsenum = $respnumlookup->{$questnum-1} 
     }      }
     if (($responsetype_per_response{$responsenum} eq 'essayresponse') ||      if (($responsetype_per_response{$responsenum} eq 'essayresponse') ||
         ($responsetype_per_response{$responsenum} eq 'formularesponse') ||          ($responsetype_per_response{$responsenum} eq 'formularesponse') ||
Line 6589  sub scantron_process_corrections { Line 6479  sub scantron_process_corrections {
  }   }
     }      }
     if ($err) {      if ($err) {
  $r->print(          $r->print(
             '<p class="LC_error">'              '<p class="LC_error">'
            .&mt('Unable to accept last correction, an error occurred: [_1]',             .&mt('Unable to accept last correction, an error occurred: [_1]',
                 $errmsg)                  $errmsg)
Line 6707  sub check_for_error { Line 6597  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=&get_scantron_config($env{'form.scantron_format'});      my %scantron_config=&get_scantron_config($env{'form.scantron_format'});
     my $CODElist;      my $CODElist;
Line 6729  sub scantron_warning_screen { Line 6619  sub scantron_warning_screen {
     return ('      return ('
 <p>  <p>
 <span class="LC_warning">  <span class="LC_warning">
 '.&mt('Please double check the information below before clicking on \'[_1]\'',&mt($button_text)).'</span>  '.&mt("Please double check the information below before clicking on '[_1]'",&mt($button_text)).'</span>
 </p>  </p>
 <table>  <table>
 <tr><td><b>'.&mt('Sequence to be Graded:').'</b></td><td>'.$title.'</td></tr>  <tr><td><b>'.&mt('Sequence to be Graded:').'</b></td><td>'.$title.'</td></tr>
 <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 6754  sub scantron_warning_screen { Line 6643  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 6773  sub scantron_do_warning { Line 6661  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 6781  sub scantron_do_warning { Line 6669  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 6839  SCANTRONFORM Line 6727  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 6895  sub scantron_validate_file { Line 6782  sub scantron_validate_file {
     while (!$stop && $currentphase < scalar(@validate_phases)) {      while (!$stop && $currentphase < scalar(@validate_phases)) {
  $r->print(&mt('Validating '.$validate_phases[$currentphase]).'<br />');   $r->print(&mt('Validating '.$validate_phases[$currentphase]).'<br />');
  $r->rflush();   $r->rflush();
        
  my $which="scantron_validate_".$validate_phases[$currentphase];   my $which="scantron_validate_".$validate_phases[$currentphase];
  {   {
     no strict 'refs';      no strict 'refs';
Line 6903  sub scantron_validate_file { Line 6790  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 6913  sub scantron_validate_file { Line 6800  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 6925  sub scantron_validate_file { Line 6812  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 6937  sub scantron_validate_file { Line 6824  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 7304  sub scantron_validate_sequence { Line 7191  sub scantron_validate_sequence {
  my @resources=   my @resources=
     $navmap->retrieveResources($map,\&scantron_filter_not_exam,1,0);      $navmap->retrieveResources($map,\&scantron_filter_not_exam,1,0);
  if (@resources) {   if (@resources) {
     $r->print('<p class="LC_warning">'      $r->print(
                   '<p class="LC_warning">'
                .&mt('Some resources in the sequence currently are not set to'                 .&mt('Some resources in the sequence currently are not set to'
                    .' exam mode. Grading these resources currently may not'                     .' bubblesheet exam mode. Grading these resources currently may not'
                    .' work correctly.')                     .' work correctly.')
                .'</p>'                 .'</p>'
             );              );
Line 7428  sub scantron_get_correction { Line 7316  sub scantron_get_correction {
   
     if ($error =~ /ID$/) {      if ($error =~ /ID$/) {
  if ($error eq 'incorrectID') {   if ($error eq 'incorrectID') {
     $r->print('<p class="LC_warning">'.&mt("The encoded ID is not in the classlist").              $r->print('<p class="LC_warning">'.&mt("The encoded ID is not in the classlist").
       "</p>\n");        "</p>\n");
  } elsif ($error eq 'duplicateID') {   } elsif ($error eq 'duplicateID') {
     $r->print('<p class="LC_warning">'.&mt("The encoded ID has also been used by a previous paper [_1]",$arg)."</p>\n");              $r->print('<p class="LC_warning">'.&mt("The encoded ID has also been used by a previous paper [_1]",$arg)."</p>\n");
  }   }
  $r->print($message);   $r->print($message);
  $r->print("<p>".&mt("How should I handle this?")." <br /> \n");   $r->print("<p>".&mt("How should I handle this?")." <br /> \n");
Line 7451  sub scantron_get_correction { Line 7339  sub scantron_get_correction {
  } elsif ($error eq 'duplicateCODE') {   } elsif ($error eq 'duplicateCODE') {
     $r->print('<p class="LC_warning">'.&mt("The encoded CODE has also been used by a previous paper [_1], and CODEs are supposed to be unique.",join(', ',@{$arg}))."</p>\n");      $r->print('<p class="LC_warning">'.&mt("The encoded CODE has also been used by a previous paper [_1], and CODEs are supposed to be unique.",join(', ',@{$arg}))."</p>\n");
  }   }
         $r->print("<p>".&mt('The CODE on the form is [_1]',   $r->print("<p>".&mt('The CODE on the form is [_1]',
                             "<tt>'$$scan_record{'scantron.CODE'}'</tt>")      "<tt>'$$scan_record{'scantron.CODE'}'</tt>")
                  ."</p>\n");                   ."</p>\n");
  $r->print($message);   $r->print($message);
  $r->print("<p>".&mt("How should I handle this?")."</p>\n");   $r->print("<p>".&mt("How should I handle this?")."</p>\n");
Line 7488  sub scantron_get_correction { Line 7376  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 7497  function change_radio(field) { Line 7384  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 7551  ENDSCRIPT Line 7437  ENDSCRIPT
  # The form field scantron_questions is actually a list of line numbers not   # The form field scantron_questions is actually a list of line numbers not
  # a list of question numbers. Therefore:   # a list of question numbers. Therefore:
  #   #
   
  my $line_list = &questions_to_line_list($arg,$randomorder,$randompick,   my $line_list = &questions_to_line_list($arg,$randomorder,$randompick,
                                                 $respnumlookup,$startline);                                                  $respnumlookup,$startline);
   
Line 7575  sub verify_bubbles_checked { Line 7461  sub verify_bubbles_checked {
     my (@ansnums) = @_;      my (@ansnums) = @_;
     my $ansnumstr = join('","',@ansnums);      my $ansnumstr = join('","',@ansnums);
     my $warning = &mt("A bubble or 'No bubble' selection has not been made for one or more lines.");      my $warning = &mt("A bubble or 'No bubble' selection has not been made for one or more lines.");
     my $output = (<<ENDSCRIPT);      my $output = &Apache::lonhtmlcommon::scripttag((<<ENDSCRIPT));
 <script type="text/javascript">  
 function verify_bubble_radio(form) {  function verify_bubble_radio(form) {
     var ansnumArray = new Array ("$ansnumstr");      var ansnumArray = new Array ("$ansnumstr");
     var need_bubble_count = 0;      var need_bubble_count = 0;
Line 7599  function verify_bubble_radio(form) { Line 7484  function verify_bubble_radio(form) {
     }      }
     form.submit();       form.submit(); 
 }  }
 </script>  
 ENDSCRIPT  ENDSCRIPT
     return $output;      return $output;
 }  }
Line 7662  sub questions_to_line_list { Line 7546  sub questions_to_line_list {
             } else {              } else {
                 $first = $first_bubble_line{$responsenum} + 1;                  $first = $first_bubble_line{$responsenum} + 1;
             }              }
             $count   = $bubble_lines_per_response{$responsenum};      $count   = $bubble_lines_per_response{$responsenum};
         }          }
         $last = $first+$count-1;          $last = $first+$count-1;
         push(@lines, ($first..$last));          push(@lines, ($first..$last));
Line 7693  for multi and missing bubble cases). Line 7577  for multi and missing bubble cases).
                   and value is number of first bubble line for current student                    and value is number of first bubble line for current student
                   or code-based randompick and/or randomorder.                    or code-based randompick and/or randomorder.
   
   
  Implicit inputs:   Implicit inputs:
    %bubble_lines_per_response   - Starting line numbers for each question.     %bubble_lines_per_response   - Starting line numbers for each question.
                                   Numbered from 0 (but question numbers are from                                    Numbered from 0 (but question numbers are from
Line 7732  sub prompt_for_corrections { Line 7617  sub prompt_for_corrections {
             }              }
         } else {          } else {
             $responsenum = $question-1;              $responsenum = $question-1;
             $first = $first_bubble_line{$responsenum} + 1;              $first = $first_bubble_line{$responsenum};
         }          }
         $current_line = $first + 1 ;          $current_line = $first + 1 ;
         my @subans = split(/,/,$subdivided_bubble_lines{$responsenum});          my @subans = split(/,/,$subdivided_bubble_lines{$responsenum});
Line 7745  sub prompt_for_corrections { Line 7630  sub prompt_for_corrections {
     } else {      } else {
         if (($randomorder || $randompick) && (ref($respnumlookup) eq 'HASH')) {          if (($randomorder || $randompick) && (ref($respnumlookup) eq 'HASH')) {
             $responsenum = $respnumlookup->{$question-1};              $responsenum = $respnumlookup->{$question-1};
             if (ref($startline) eq 'HASH') {              if (ref($startline) eq 'HASH') { 
                 $first = $startline->{$question-1};                  $first = $startline->{$question-1};
             }              }
         } else {          } else {
Line 7763  sub prompt_for_corrections { Line 7648  sub prompt_for_corrections {
             ($responsetype_per_response{$responsenum} eq 'imageresponse') ||              ($responsetype_per_response{$responsenum} eq 'imageresponse') ||
             ($responsetype_per_response{$responsenum} eq 'reactionresponse') ||              ($responsetype_per_response{$responsenum} eq 'reactionresponse') ||
             ($responsetype_per_response{$responsenum} eq 'organicresponse')) {              ($responsetype_per_response{$responsenum} eq 'organicresponse')) {
             $r->print(&mt("Although this particular question type requires handgrading, the instructions for this question in the bubblesheet exam directed students to leave [quant,_1,line] blank on their bubblesheets.",$lines).'<br /><br />'.&mt('A non-zero score can be assigned to the student during bubblesheet grading by selecting a bubble in at least one line.').'<br />'.&mt('The score for this question will be a sum of the numeric values for the selected bubbles from each line, where A=1 point, B=2 points etc.').'<br />'.&mt("To assign a score of zero for this question, mark all lines as 'No bubble'.").'<br /><br />');              $r->print(
                   &mt("Although this particular question type requires handgrading, the instructions for this question in the bubblesheet exam directed students to leave [quant,_1,line] blank on their bubblesheets.",$lines)
                  .'<br /><br />'
                  .&mt('A non-zero score can be assigned to the student during bubblesheet grading by selecting a bubble in at least one line.')
                  .'<br />'
                  .&mt('The score for this question will be a sum of the numeric values for the selected bubbles from each line, where A=1 point, B=2 points etc.')
                  .'<br />'
                  .&mt("To assign a score of zero for this question, mark all lines as 'No bubble'.")
                  .'<br /><br />'
               );
         } else {          } else {
             $r->print(&mt("Select at most one bubble in a single line and select 'No Bubble' in all the other lines. ")."<br />");              $r->print(&mt("Select at most one bubble in a single line and select 'No Bubble' in all the other lines. ")."<br />");
         }          }
Line 7803  sub scantron_bubble_selector { Line 7697  sub scantron_bubble_selector {
     my $max=$$scan_config{'Qlength'};      my $max=$$scan_config{'Qlength'};
   
     my $scmode=$$scan_config{'Qon'};      my $scmode=$$scan_config{'Qon'};
     if ($scmode eq 'number' || $scmode eq 'letter') {      if ($scmode eq 'number' || $scmode eq 'letter') { 
         if (($$scan_config{'BubblesPerRow'} =~ /^\d+$/) &&          if (($$scan_config{'BubblesPerRow'} =~ /^\d+$/) &&
             ($$scan_config{'BubblesPerRow'} > 0)) {              ($$scan_config{'BubblesPerRow'} > 0)) {
             $max=$$scan_config{'BubblesPerRow'};              $max=$$scan_config{'BubblesPerRow'};
Line 8122  sub scantron_get_maxbubble { Line 8016  sub scantron_get_maxbubble {
     my $response_number = 0;      my $response_number = 0;
     my $bubble_line     = 0;      my $bubble_line     = 0;
     foreach my $resource (@resources) {      foreach my $resource (@resources) {
         my $resid = $resource->id();          my $resid = $resource->id(); 
         my ($analysis,$parts) = &scantron_partids_tograde($resource,$cid,$uname,          my ($analysis,$parts) = &scantron_partids_tograde($resource,$cid,$uname,
                                                           $udom,undef,$bubbles_per_row);                                                            $udom,undef,$bubbles_per_row);
         if ((ref($analysis) eq 'HASH') && (ref($parts) eq 'ARRAY')) {          if ((ref($analysis) eq 'HASH') && (ref($parts) eq 'ARRAY')) {
Line 8173  sub scantron_get_maxbubble { Line 8067  sub scantron_get_maxbubble {
         $bubble_lines_per_response{$response_number} = $lines;          $bubble_lines_per_response{$response_number} = $lines;
                 $responsetype_per_response{$response_number} =                   $responsetype_per_response{$response_number} = 
                     $analysis->{$part_id.'.type'};                      $analysis->{$part_id.'.type'};
                 $masterseq_id_responsenum{$resid.'_'.$part_id} = $response_number;                  $masterseq_id_responsenum{$resid.'_'.$part_id} = $response_number;  
         $response_number++;          $response_number++;
   
         $bubble_line +=  $lines;          $bubble_line +=  $lines;
Line 8254  sub scantron_validate_missingbubbles { Line 8148  sub scantron_validate_missingbubbles {
     for (my $i=0;$i<=$scanlines->{'count'};$i++) {      for (my $i=0;$i<=$scanlines->{'count'};$i++) {
  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; }
         my $scan_record =   my $scan_record =
             &scantron_parse_scanline($line,$i,\%scantron_config,$scan_data,undef,\%idmap,              &scantron_parse_scanline($line,$i,\%scantron_config,$scan_data,undef,\%idmap,
                                      $randomorder,$randompick,$sequence,\@master_seq,       $randomorder,$randompick,$sequence,\@master_seq,
                                      \%symb_to_resource,\%grader_partids_by_symb,                                       \%symb_to_resource,\%grader_partids_by_symb,
                                      \%orderedforcode,\%respnumlookup,\%startline);                                       \%orderedforcode,\%respnumlookup,\%startline);
  if (!defined($$scan_record{'scantron.missingerror'})) { next; }   if (!defined($$scan_record{'scantron.missingerror'})) { next; }
Line 8267  sub scantron_validate_missingbubbles { Line 8161  sub scantron_validate_missingbubbles {
  foreach my $missing (@{$$scan_record{'scantron.missingerror'}}) {   foreach my $missing (@{$$scan_record{'scantron.missingerror'}}) {
             my $lastbubble;              my $lastbubble;
             if ($missing =~ /^(\d+)\.(\d+)$/) {              if ($missing =~ /^(\d+)\.(\d+)$/) {
                 my $question = $1;                 my $question = $1;
                 my $subquestion = $2;                 my $subquestion = $2;
                 my ($first,$responsenum);                 my ($first,$responsenum);
                 if ($randomorder || $randompick) {                 if ($randomorder || $randompick) {
                     $responsenum = $respnumlookup{$question-1};                     $responsenum = $respnumlookup{$question-1};
                     $first = $startline{$question-1};                     $first = $startline{$question-1};
                 } else {                 } else {
                     $responsenum = $question-1;                     $responsenum = $question-1; 
                     $first = $first_bubble_line{$responsenum};                     $first = $first_bubble_line{$responsenum};
                 }                 }
                 if (!defined($first)) { next; }                 if (!defined($first)) { next; }
                 my @subans = split(/,/,$subdivided_bubble_lines{$responsenum});                 my @subans = split(/,/,$subdivided_bubble_lines{$responsenum});
                 my $subcount = 1;                 my $subcount = 1;
                 while ($subcount<$subquestion) {                 while ($subcount<$subquestion) {
                     $first += $subans[$subcount-1];                     $first += $subans[$subcount-1];
                     $subcount ++;                     $subcount ++;
                 }                 }
                 my $count = $subans[$subquestion-1];                 my $count = $subans[$subquestion-1];
                 $lastbubble = $first + $count;                 $lastbubble = $first + $count;
             } else {              } else {
                 my ($first,$responsenum);                 my ($first,$responsenum);
                 if ($randomorder || $randompick) {                 if ($randomorder || $randompick) {
                     $responsenum = $respnumlookup{$missing-1};                     $responsenum = $respnumlookup{$missing-1};
                     $first = $startline{$missing-1};                     $first = $startline{$missing-1};
                 } else {                 } else {
                     $responsenum = $missing-1;                     $responsenum = $missing-1;
                     $first = $first_bubble_line{$responsenum};                     $first = $first_bubble_line{$responsenum};
                 }                 }
                 if (!defined($first)) { next; }                 if (!defined($first)) { next; }
                 $lastbubble = $first + $bubble_lines_per_response{$responsenum};                 $lastbubble = $first + $bubble_lines_per_response{$responsenum};
             }              }
             if ($lastbubble > $max_bubble) { next; }              if ($lastbubble > $max_bubble) { next; }
     push(@to_correct,$missing);      push(@to_correct,$missing);
Line 8350  sub hand_bubble_option { Line 8244  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 '';
     }      }
     my $default_form_data=&defaultFormData($symb);      my $default_form_data=&defaultFormData($symb);
   
     my %scantron_config=&get_scantron_config($env{'form.scantron_format'});      my %scantron_config=&get_scantron_config($env{'form.scantron_format'});
     my $bubbles_per_row = &bubblesheet_bubbles_per_row(\%scantron_config);      my $bubbles_per_row = &bubblesheet_bubbles_per_row(\%scantron_config); 
     my ($scanlines,$scan_data)=&scantron_getfile();      my ($scanlines,$scan_data)=&scantron_getfile();
     my $classlist=&Apache::loncoursedata::get_classlist();      my $classlist=&Apache::loncoursedata::get_classlist();
     my %idmap=&username_to_idmap($classlist);      my %idmap=&username_to_idmap($classlist);
Line 8381  sub scantron_process_students { Line 8274  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);
     my (%grader_partids_by_symb,%grader_randomlists_by_symb,%ordered);  
     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 8406  SCANTRONFORM Line 8298  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 8425  SCANTRONFORM Line 8316  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 8440  SCANTRONFORM Line 8330  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 = ();
         my %startline = ();          my %startline = ();
         my $total;          my $total;
   my $scan_record=&scantron_parse_scanline($line,$i,\%scantron_config,    my $scan_record=&scantron_parse_scanline($line,$i,\%scantron_config,
   $scan_data,undef,\%idmap,$randomorder,                                                   $scan_data,undef,\%idmap,$randomorder,
                                                  $randompick,$sequence,\@master_seq,                                                   $randompick,$sequence,\@master_seq,
                                                  \%symb_to_resource,\%grader_partids_by_symb,                                                   \%symb_to_resource,\%grader_partids_by_symb,
                                                  \%orderedforcode,\%respnumlookup,\%startline,                                                   \%orderedforcode,\%respnumlookup,\%startline,
Line 8478  SCANTRONFORM Line 8367  SCANTRONFORM
   
         my @mapresources = @resources;          my @mapresources = @resources;
         if ($randomorder || $randompick) {          if ($randomorder || $randompick) {
             @mapresources =              @mapresources = 
                 &users_order($user,$scancode,$sequence,\@master_seq,\%symb_to_resource,                  &users_order($user,$scancode,$sequence,\@master_seq,\%symb_to_resource,
                              \%orderedforcode);                               \%orderedforcode);
         }          }
Line 8523  SCANTRONFORM Line 8412  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.
         }          }
Line 8563  SCANTRONFORM Line 8451  SCANTRONFORM
                 if (&grade_student_bubbles($r,$uname,$udom,$scan_record,$scancode,                  if (&grade_student_bubbles($r,$uname,$udom,$scan_record,$scancode,
                                            \@mapresources,\%partids_by_symb,                                             \@mapresources,\%partids_by_symb,
                                            $bubbles_per_row,$randomorder,$randompick,                                             $bubbles_per_row,$randomorder,$randompick,
                                            \%respnumlookup,\%startline)                                             \%respnumlookup,\%startline) 
                     eq 'ssi_error') {                      eq 'ssi_error') {
                     $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 8600  SCANTRONFORM Line 8487  SCANTRONFORM
                               &Apache::loncommon::end_data_table_header_row()."\n".                                &Apache::loncommon::end_data_table_header_row()."\n".
                               &Apache::loncommon::start_data_table_row().                                &Apache::loncommon::start_data_table_row().
                               '<td>'.&mt('Bubblesheet').'</td>'.                                '<td>'.&mt('Bubblesheet').'</td>'.
                               '<td><span class="LC_nobreak">'.$studentdata.'</span></td>'.                                '<td><span class="LC_nobreak" style="white-space: pre;"><tt>'.$studentdata.'</tt></span></td>'.
                               &Apache::loncommon::end_data_table_row().                                &Apache::loncommon::end_data_table_row().
                               &Apache::loncommon::start_data_table_row().                                &Apache::loncommon::start_data_table_row().
                               '<td>'.&mt('Stored submissions').'</td>'.                                '<td>'.&mt('Stored submissions').'</td>'.
                               '<td><span class="LC_nobreak">'.$studentrecord.'</span></td>'."\n".                                '<td><span class="LC_nobreak" style="white-space: pre;"><tt>'.$studentrecord.'</tt></span></td>'."\n".
                               &Apache::loncommon::end_data_table_row().                                &Apache::loncommon::end_data_table_row().
                               &Apache::loncommon::end_data_table().'</p>');                                &Apache::loncommon::end_data_table().'</p>');
                 } else {                  } else {
Line 8626  SCANTRONFORM Line 8513  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 8658  sub graders_resources_pass { Line 8544  sub graders_resources_pass {
 =item users_order  =item users_order
   
   Returns array of resources in current map, ordered based on either CODE,    Returns array of resources in current map, ordered based on either CODE,
   if this is a CODEd exam, or based on student's identity if this is a    if this is a CODEd exam, or based on student's identity if this is a 
   "NAMEd" exam.    "NAMEd" exam.
   
   Should be used when randomorder and/or randompick applied when the     Should be used when randomorder and/or randompick applied when the 
Line 8685  sub users_order  { Line 8571  sub users_order  {
             if (ref($actual_seq) eq 'ARRAY') {              if (ref($actual_seq) eq 'ARRAY') {
                 @mapresources = map { $symb_to_resource->{$_}; } @{$actual_seq};                  @mapresources = map { $symb_to_resource->{$_}; } @{$actual_seq};
                 if (ref($orderedforcode) eq 'HASH') {                  if (ref($orderedforcode) eq 'HASH') {
                     if (@mapresources > 0) {                      if (@mapresources > 0) { 
                         $orderedforcode->{$scancode} = \@mapresources;                          $orderedforcode->{$scancode} = \@mapresources;
                     }                      }
                 }                  }
Line 8698  sub users_order  { Line 8584  sub users_order  {
                                                            $master_seq,                                                             $master_seq,
                                                            $user,undef,1);                                                             $user,undef,1);
         if (ref($actual_seq) eq 'ARRAY') {          if (ref($actual_seq) eq 'ARRAY') {
             @mapresources =              @mapresources = 
                 map { $symb_to_resource->{$_}; } @{$actual_seq};                  map { $symb_to_resource->{$_}; } @{$actual_seq};
         }          }
     }      }
Line 8754  sub grade_student_bubbles { Line 8640  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 $domdesc = &Apache::lonnet::domain($dom,'description');      my $domdesc = &Apache::lonnet::domain($dom,'description');
     $r->print(&Apache::loncommon::coursebrowser_javascript($dom));      $r->print(&Apache::loncommon::coursebrowser_javascript($dom));
Line 8762  sub scantron_upload_scantron_data { Line 8648  sub scantron_upload_scantron_data {
   'domainid',    'domainid',
   '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.');
     my $nocourseid_alert = &mt("Please use the 'Select Course' link to open a separate window where you can search for a course to which a file can be uploaded.");      my $nocourseid_alert = &mt("Please use the 'Select Course' link to open a separate window where you can search for a course to which a file can be uploaded.");
     $r->print('      $r->print(&Apache::lonhtmlcommon::scripttag('
 <script type="text/javascript" language="javascript">  
     function checkUpload(formname) {      function checkUpload(formname) {
  if (formname.upfile.value == "") {   if (formname.upfile.value == "") {
     alert("'.$nofile_alert.'");      alert("'.$nofile_alert.'");
Line 8795  sub scantron_upload_scantron_data { Line 8679  sub scantron_upload_scantron_data {
         return;          return;
     }      }
   
 </script>  '));
       $r->print('
 <h3>'.&mt('Send bubblesheet data to a course').'</h3>  <h3>'.&mt('Send bubblesheet data to a course').'</h3>
   
 <form enctype="multipart/form-data" action="/adm/grades" name="rules" method="post">  <form enctype="multipart/form-data" action="/adm/grades" name="rules" method="post">
Line 8825  sub scantron_upload_scantron_data { Line 8709  sub scantron_upload_scantron_data {
   
   
 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 8836  sub scantron_upload_scantron_data_save { Line 8719  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 '';
     }      }
     my %coursedata=&Apache::lonnet::coursedescription($env{'form.domainid'}.'_'.$env{'form.courseid'});      my %coursedata=&Apache::lonnet::coursedescription($env{'form.domainid'}.'_'.$env{'form.courseid'});
     my $uploadedfile;      my $uploadedfile;
     $r->print('<h3>'.&mt("Uploading file to [_1]",$coursedata{'description'}).'</h3>');      $r->print('<p>'.&mt('Uploading file to [_1]','"'.$coursedata{'description'}.'"').'</p>');
     if (length($env{'form.upfile'}) < 2) {      if (length($env{'form.upfile'}) < 2) {
         $r->print(&mt('[_1]Error:[_2] The file you attempted to upload, [_3] contained no information. Please check that you entered the correct filename.','<span class="LC_error">','</span>','<span class="LC_filename">'.&HTML::Entities::encode($env{'form.upfile.filename'},'<>&"').'</span>'));          $r->print(
               &Apache::lonhtmlcommon::confirm_success(
                   &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));
     } else {      } else {
         my $result =           my $result = 
             &Apache::lonnet::userfileupload('upfile','','scantron','','','',              &Apache::lonnet::userfileupload('upfile','','scantron','','','',
                                             $env{'form.courseid'},$env{'form.domainid'});                                              $env{'form.courseid'},$env{'form.domainid'});
  if ($result =~ m{^/uploaded/}) {          if ($result =~ m{^/uploaded/}) {
     $r->print(&mt('[_1]Success:[_2] Successfully uploaded [_3] bytes of data into location: [_4]',              $r->print(
                           '<span class="LC_success">','</span>',(length($env{'form.upfile'})-1),                  &Apache::lonhtmlcommon::confirm_success(&mt('Upload successful')).'<br />'.
   '<span class="LC_filename">'.$result.'</span>'));                  &mt('Uploaded [_1] bytes of data into location: [_2]',
                           (length($env{'form.upfile'})-1),
                           '<span class="LC_filename">'.$result.'</span>'));
             ($uploadedfile) = ($result =~ m{/([^/]+)$});              ($uploadedfile) = ($result =~ m{/([^/]+)$});
             $r->print(&validate_uploaded_scantron_file($env{'form.domainid'},              $r->print(&validate_uploaded_scantron_file($env{'form.domainid'},
                                                        $env{'form.courseid'},$uploadedfile));                                                         $env{'form.courseid'},$uploadedfile));
  } else {          } else {
     $r->print(&mt('[_1]Error:[_2] An error ([_3]) occurred when attempting to upload the file, [_4]',              $r->print(
                           '<span class="LC_error">','</span>',$result,                  &Apache::lonhtmlcommon::confirm_success(&mt('Upload failed'),1).'<br />'.
                       &mt('An error ([_1]) occurred when attempting to upload the file: [_2]',
                             $result,
   '<span class="LC_filename">'.&HTML::Entities::encode($env{'form.upfile.filename'},'<>&"').'</span>'));    '<span class="LC_filename">'.&HTML::Entities::encode($env{'form.upfile.filename'},'<>&"').'</span>'));
  }   }
     }      }
     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 8883  sub validate_uploaded_scantron_file { Line 8771  sub validate_uploaded_scantron_file {
     my $output;      my $output;
     if (@lines) {      if (@lines) {
         my (%counts,$max_match_format);          my (%counts,$max_match_format);
         my ($max_match_count,$max_match_pct) = (0,0);          my ($found_match_count,$max_match_count,$max_match_pct) = (0,0,0);
         my $classlist = &Apache::loncoursedata::get_classlist($cdom,$cname);          my $classlist = &Apache::loncoursedata::get_classlist($cdom,$cname);
         my %idmap = &username_to_idmap($classlist);          my %idmap = &username_to_idmap($classlist);
         foreach my $key (keys(%idmap)) {          foreach my $key (keys(%idmap)) {
Line 8926  sub validate_uploaded_scantron_file { Line 8814  sub validate_uploaded_scantron_file {
                 if (($max_match_format eq '') || ($percent_match > $max_match_pct)) {                  if (($max_match_format eq '') || ($percent_match > $max_match_pct)) {
                     $max_match_pct = $percent_match;                      $max_match_pct = $percent_match;
                     $max_match_format = $key;                      $max_match_format = $key;
                       $found_match_count = $counts{$key}{'found'};
                     $max_match_count = $counts{$key}{'total'};                      $max_match_count = $counts{$key}{'total'};
                 }                  }
             }              }
Line 8944  sub validate_uploaded_scantron_file { Line 8833  sub validate_uploaded_scantron_file {
                 }                  }
             }              }
             my $showpct = sprintf("%.0f",$max_match_pct).'%';              my $showpct = sprintf("%.0f",$max_match_pct).'%';
             $output .= '<br />'.&mt('Comparison of student IDs in the uploaded file with the course roster found matches for [_1] of the [_2] entries in the file (for the format defined for [_3]).','<b>'.$showpct.'</b>','<b>'.$max_match_count.'</b>',$format_descs).              $output .= '<br />';
                        '<br />'.&mt('A low percentage of matches results from one of the following:').'<ul>'.              if ($found_match_count == $max_match_count) {
                        '<li>'.&mt('The file was uploaded to the wrong course').'</li>'.                  # 100% matching entries
                        '<li>'.&mt('The data are not in the format expected for the domain: [_1]',                  $output .= &Apache::lonhtmlcommon::confirm_success(
                                   '<i>'.$cdom.'</i>').'</li>'.                       &mt('Comparison of student IDs: [_1] matching ([quant,_2,entry,entries])',
                        '<li>'.&mt('Students did not bubble their IDs, or mis-bubbled them').'</li>'.                              '<b>'.$showpct.'</b>',$found_match_count)).'<br />'.
                        '<li>'.&mt('The course roster is not up to date').'</li>'.                  &mt('Comparison of student IDs in the uploaded file with'.
                        '</ul>';                      ' the course roster found matches for [_1] of the [_2] entries'.
                       ' in the file (for the format defined for [_3]).',
                           '<b>'.$showpct.'</b>','<b>'.$max_match_count.'</b>',$format_descs);
               } else {
                   # Not all entries matching? -> Show warning and additional info
                   $output .=
                       &Apache::lonhtmlcommon::confirm_success(
                           &mt('Comparison of student IDs: [_1] matching ([_2]/[quant,_3,entry,entries])',
                                   '<b>'.$showpct.'</b>',$found_match_count,$max_match_count).'<br />'.
                           &mt('Not all entries could be matched!'),1).'<br />'.
                       &mt('Comparison of student IDs in the uploaded file with'.
                           ' the course roster found matches for [_1] of the [_2] entries'.
                           ' in the file (for the format defined for [_3]).',
                               '<b>'.$showpct.'</b>','<b>'.$max_match_count.'</b>',$format_descs).
                       '<p class="LC_info">'.
                       &mt('A low percentage of matches results from one of the following:').
                       '</p><ul>'.
                       '<li>'.&mt('The file was uploaded to the wrong course.').'</li>'.
                       '<li>'.&mt('The data is not in the format expected for the domain: [_1]',
                                  '<i>'.$cdom.'</i>').'</li>'.
                       '<li>'.&mt('Students did not bubble their IDs, or mis-bubbled them').'</li>'.
                       '<li>'.&mt('The course roster is not up to date.').'</li>'.
                       '</ul>';
               }
         }          }
     } else {      } else {
         $output = '<span class="LC_warning">'.&mt('Uploaded file contained no data').'</span>';          $output = '<p class="LC_warning">'.&mt('Uploaded file contained no data').'</p>';
     }      }
     return $output;      return $output;
 }  }
Line 8968  sub valid_file { Line 8880  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 8980  sub scantron_download_scantron_data { Line 8891  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 8991  sub scantron_download_scantron_data { Line 8901  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 the scantron office.',   '.&mt('[_1]Original[_2] file as uploaded by the bubblesheet office.',
       '<a href="'.$orig.'">','</a>').'        '<a href="'.$orig.'">','</a>').'
     </p>      </p>
     <p>      <p>
Line 9003  sub scantron_download_scantron_data { Line 8913  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 = &letter_to_digits();      my %lettdig = &letter_to_digits();
     my $numletts = scalar(keys(%lettdig));      my $numletts = scalar(keys(%lettdig));
Line 9033  sub checkscantron_results { Line 8940  sub checkscantron_results {
     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,%orderedforcode);          %grader_randomlists_by_symb,%orderedforcode);
     if (ref($map)) {      if (ref($map)) { 
         $randomorder=$map->randomorder();          $randomorder=$map->randomorder();
         $randompick=$map->randompick();          $randompick=$map->randompick();
     }      }
Line 9055  sub checkscantron_results { Line 8962  sub checkscantron_results {
   
     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);
     my ($username,$domain,$started,%ordered);      my ($username,$domain,$started);
     &scantron_get_maxbubble(\$nav_error,\%scantron_config); # Need the bubble lines array to parse.      &scantron_get_maxbubble(\$nav_error,\%scantron_config); # Need the bubble lines array to parse.
     if ($nav_error) {      if ($nav_error) {
         $r->print(&navmap_errormsg());          $r->print(&navmap_errormsg());
         return '';          return '';
     }      }
   
     &Apache::lonhtmlcommon::Update_PrgWin($r,\%prog_state,      &Apache::lonhtmlcommon::Update_PrgWin($r,\%prog_state,'Processing first student');
                                           'Processing first student');  
     my $start=&Time::HiRes::time();      my $start=&Time::HiRes::time();
     my $i=-1;      my $i=-1;
   
Line 9073  sub checkscantron_results { Line 8979  sub checkscantron_results {
         my $line=&Apache::grades::scantron_get_line($scanlines,$scan_data,$i);          my $line=&Apache::grades::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 $scan_record=          my $scan_record=
Line 9182  sub checkscantron_results { Line 9087  sub checkscantron_results {
             }              }
         }          }
     }      }
     $r->print('<p>'.      $r->print(
               &mt('Comparison of bubblesheet data (including corrections) with corresponding submission records (most recent submission) for [_1][quant,_2,student][_3] ([quant,_4,bubblesheet line] per student).',          '<p>'
                   '<b>',         .&mt('Comparison of bubblesheet data (including corrections) with corresponding submission records (most recent submission) for [_1][quant,_2,student][_3] ([quant,_4,bubblesheet line] per student).',
                   $numstudents,              '<b>',
                   '</b>',              $numstudents,
                   $env{'form.scantron_maxbubble'}).              '</b>',
               '</p>'              $env{'form.scantron_maxbubble'})
          .'</p>'
     );      );
     $r->print('<p>'      $r->print('<p>'
              .&mt('Exact matches for [_1][quant,_2,student][_3].','<b>',$passed,'</b>')               .&mt('Exact matches for [_1][quant,_2,student][_3].','<b>',$passed,'</b>')
              .'<br />'               .'<br />'
              .&mt('Discrepancies detected for [_1][quant,_2,student][_3].','<b>',$failed,'</b>')               .&mt('Discrepancies detected for [_1][quant,_2,student][_3].','<b>',$failed,'</b>')
              .'</p>');               .'</p>'
       );
     if ($passed) {      if ($passed) {
         $r->print(&mt('Students with exact correspondence between bubblesheet data and submissions are as follows:').'<br /><br />');          $r->print(&mt('Students with exact correspondence between bubblesheet data and submissions are as follows:').'<br /><br />');
         $r->print(&Apache::loncommon::start_data_table()."\n".          $r->print(&Apache::loncommon::start_data_table()."\n".
Line 9214  sub checkscantron_results { Line 9121  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 9363  sub letter_to_digits { Line 9270  sub letter_to_digits {
   
 #-------------------------- 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 9395  sub href_symb_cmd { Line 9278  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',  
                   'saveState'=>"",  
                   'gradingMenu'=>1,  
                   'showgrading'=>"yes");  
       
     my $url1 = &Apache::lonhtmlcommon::build_url('grades/',\%fields);  
           
       my $url1a = &Apache::lonhtmlcommon::build_url('grades/',\%fields);
   
       $fields{'command'}='ungraded';
       my $url1b=&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 9420  sub grading_menu { Line 9306  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);
   
       $fields{'command'} = 'initialverifyreceipt';
       my $url5 = &Apache::lonhtmlcommon::build_url('grades/',\%fields);
           
     my @menu = ({ categorytitle=>'Course Grading',      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 => 'F',
                     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 => 'F',
                                   icon => 'ungrade_sub.png',
                                   linktitle => 'Grade all submissions that have not been graded yet.'
                           },
   
                           {       linktext => 'Grading table',
                                   url => $url1c,
                                   permission => 'F',
                                   icon => 'grading_table.png',
                                   linktitle => 'Grade current resource for all students.'
                           },
                           {       linktext => 'Grade page/folder for one student',
                                   url => $url1d,
                                   permission => 'F',
                                   icon => 'grade_PageFolder.png',
                                   linktitle => 'Grade all resources in current page/sequence/folder for one student.'
                         },                          },
                           {       linktext => 'Download submissions',
                                   url => $url1e,
                                   permission => 'F',
                                   icon => 'download_sub.png',
                                   linktitle => 'Download all students submissions.'
                           }]},
                            { categorytitle=>'Automated Grading',
                  items =>[
   
                    { linktext => 'Upload Scores',                     { linktext => 'Upload Scores',
                     url => $url2,                      url => $url2,
                     permission => 'F',                      permission => 'F',
Line 9444  sub grading_menu { Line 9361  sub grading_menu {
                    { linktext => 'Grade/Manage/Review Bubblesheets',                     { linktext => 'Grade/Manage/Review Bubblesheets',
                     url => $url4,                      url => $url4,
                     permission => 'F',                      permission => 'F',
                     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 => 'F',
                                   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.");      return $Str;    
     $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;  sub ungraded {
  var checkOpt = false;      my ($request)=@_;
  if (nospace == "OK" && isNaN(receiptNo)) {checkOpt = true;}      &submit_options($request);
  if (nospace == "notOK" && (isNaN(receiptNo) || receiptNo == "")) {checkOpt = true;}  }
  if (checkOpt) {  
     alert("$receiptalert");  sub submit_options_sequence {
     formname.receipt.value = "";      my ($request,$symb) = @_;
     formname.receipt.focus();      if (!$symb) {return '';}
     return false;  
  }  
  return true;  
     }  
 </script>  
 GRADINGMENUJS  
     &commonJSfunctions($request);      &commonJSfunctions($request);
     return $Str;          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(0).
               '<input type="hidden" name="command" value="pickStudentPage" />
               <div>
                 <input type="submit" value="'.&mt('Next').' &rarr;" />
               </div>
           </div>
     </form>';
       return $result;
   }
   
   sub submit_options_table {
       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(0).
               '<input type="hidden" name="command" value="viewgrades" />
               <div>
                 <input type="submit" value="'.&mt('Next').' &rarr;" />
               </div>
           </div>
     </form>';
       return $result;
 }  }
   
   sub submit_options_download {
       my ($request,$symb) = @_;
       if (!$symb) {return '';}
   
       &commonJSfunctions($request);
   
       my $result='<form action="/adm/grades" method="post" name="gradingMenu">'."\n".
           '<input type="hidden" name="symb"        value="'.&Apache::lonenc::check_encrypt($symb).'" />'."\n";
       $result.='
   <h2>
     '.&mt('Select Students for Which to Download Submissions').'
   </h2>'.&selectfield(1).'
                   <input type="hidden" name="command" value="downloadfileslink" /> 
                 <input type="submit" value="'.&mt('Next').' &rarr;" />
               </div>
             </div>
   
   
     </form>';
       return $result;
   }
   
 #--- Displays the submissions first page -------  #--- Displays the submissions first page -------
 sub submit_options {  sub submit_options {
     my ($request) = @_;      my ($request,$symb) = @_;
     my ($symb)=&get_symb($request);  
     if (!$symb) {return '';}      if (!$symb) {return '';}
     my $probTitle = &Apache::lonnet::gettitle($symb);  
   
     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;  
  formname.saveState.value = "saveCmd="+cmdsave+":saveSec="+pullDownSelection(formname.section)+  
     ":saveSub="+pullDownSelection(formname.submitonly)+":saveStatus="+pullDownSelection(formname.Status);  
  if (val < 5) formname.submit();  
  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();  
     my $saveCmd = ($$savedState{'saveCmd'} eq '' ? 'submission' : $$savedState{'saveCmd'});  
     my $saveSec = ($$savedState{'saveSec'} eq '' ? 'all' : $$savedState{'saveSec'});  
     my $saveSub = ($$savedState{'saveSub'} eq '' ? 'all' : $$savedState{'saveSub'});  
     my $saveStatus = ($$savedState{'saveStatus'} eq '' ? 'Active' : $$savedState{'saveStatus'});  
   
     # Preselect sections  
     my $selsec="";  
     if (ref($sections)) {  
         foreach my $section (sort(@$sections)) {  
             $selsec.='<option value="'.$section.'" '.  
                 ($saveSec eq $section ? 'selected="selected"':'').'>'.$section.'</option>'."\n";  
         }  
     }  
   
     $result.='<form action="/adm/grades" method="post" name="gradingMenu">'."\n".      $result.='<form action="/adm/grades" method="post" name="gradingMenu">'."\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="handgrade"   value="'.$hdgrade.'" />'."\n".      $result.=&selectfield(1).'
  '<input type="hidden" name="probTitle"   value="'.$probTitle.'" />'."\n".                  <input type="hidden" name="command" value="submission" /> 
  '<input type="hidden" name="command"     value="" />'."\n".        <input type="submit" value="'.&mt('Next').' &rarr;" />
  '<input type="hidden" name="saveState"   value="" />'."\n".              </div>
  '<input type="hidden" name="gradingMenu" value="1" />'."\n".            </div>
  '<input type="hidden" name="showgrading" value="yes" />'."\n";  
   
     $result.='  
 <h2>  
   '.&mt('Grade Current Resource').'  
 </h2>  
 <div>  
   '.$table.'  
 </div>  
   
 <div class="LC_columnSection">    </form>';
       return $result;
   }
   
   sub selectfield {
      my ($full)=@_;
      my %options = 
             (&Apache::lonlocal::texthash(
                'yes'       => 'with submissions',
                'queued'    => 'in grading queue',
                'graded'    => 'with ungraded submissions',
                'incorrect' => 'with incorrect submissions',
                'all'       => 'with any status'),
                'select_form_order' => ['yes','queued','graded','incorrect','all']);
      my $result='<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>
Line 9619  GRADINGMENUJS Line 9500  GRADINGMENUJS
       <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 9778  sub clicker_grading_parameters { Line 9614  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 9806  sub process_clicker { Line 9638  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 9816  sub process_clicker { Line 9648  sub process_clicker {
     my $pcorrect=&mt("Percentage points for correct solution");      my $pcorrect=&mt("Percentage points for correct solution");
     my $pincorrect=&mt("Percentage points for incorrect solution");      my $pincorrect=&mt("Percentage points for incorrect solution");
     my $selectform=&Apache::loncommon::select_form($env{'form.upfiletype'},'upfiletype',      my $selectform=&Apache::loncommon::select_form($env{'form.upfiletype'},'upfiletype',
                                                    {'iclicker' => 'i>clicker',     {'iclicker' => 'i>clicker',
                                                     'interwrite' => 'interwrite PRS',                                                      'interwrite' => 'interwrite PRS',
                                                     '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 9859  function sanitycheck() { Line 9690  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 9875  function sanitycheck() { Line 9708  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 9947  sub process_clicker_file { Line 9781  sub process_clicker_file {
     $number++;      $number++;
  }   }
         $result.="</p>\n";          $result.="</p>\n";
  if ($number==0) {          if ($number==0) {
     $result.='<span class="LC_error">'.&mt('No IDs found to determine correct answer').'</span>';              $result .=
     return $result.&show_grading_menu_form($symb);                   &Apache::lonhtmlcommon::confirm_success(
  }                       &mt('No IDs found to determine correct answer'),1);
               return $result;
           }
     }      }
     if (length($env{'form.upfile'}) < 2) {      if (length($env{'form.upfile'}) < 2) {
         $result.=&mt('[_1] Error: [_2] The file you attempted to upload, [_3] contained no information. Please check that you entered the correct filename.',          $result .=
      '<span class="LC_error">',              &Apache::lonhtmlcommon::confirm_success(
      '</span>',                  &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>');                          '<span class="LC_filename">'.&HTML::Entities::encode($env{'form.upfile.filename'},'<>&"').'</span>'),1);
         return $result.&show_grading_menu_form($symb);          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 10001  ENDHEADER Line 9836  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 10021  ENDHEADER Line 9856  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 10035  ENDHEADER Line 9872  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").": ".
Line 10061  ENDHEADER Line 9900  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 10150  sub turning_eval { Line 9990  sub turning_eval {
     return ($errormsg,$number);      return ($errormsg,$number);
 }  }
   
   
 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 10163  sub assign_clicker_grades { Line 10003  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 10226  sub assign_clicker_grades { Line 10062  sub assign_clicker_grades {
                       &mt('More than one entry found for [_1]!','<tt>'.$user.'</tt>').                        &mt('More than one entry found for [_1]!','<tt>'.$user.'</tt>').
                       '</span><br />';                        '</span><br />';
           }            }
           $users{$user}=1;            $users{$user}=1; 
           my @answer=split(/\,/,$env{$key});            my @answer=split(/\,/,$env{$key});
           my $sum=0;            my $sum=0;
           my $realnumber=$number;            my $realnumber=$number;
           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 10280  sub assign_clicker_grades { Line 10116  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 10296  sub startpage { Line 10132  sub startpage {
     if ($nomenu) {      if ($nomenu) {
         $r->print(&Apache::loncommon::start_page("Student's Version",$js,{'only_body' => '1'}));          $r->print(&Apache::loncommon::start_page("Student's Version",$js,{'only_body' => '1'}));
     } else {      } else {
           unshift(@$crumbs,{href=>&href_symb_cmd($symb,'gradingmenu'),text=>"Grading"});
         $r->print(&Apache::loncommon::start_page('Grading',$js,          $r->print(&Apache::loncommon::start_page('Grading',$js,
                                                  {'bread_crumbs' => $crumbs}));                                                   {'bread_crumbs' => $crumbs}));
           &Apache::lonquickgrades::startGradeScreen($r,($env{'form.symb'}?'probgrading':'grading'));
     }      }
     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));
     }      }
 }  }
   
   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));
       $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 10314  sub handler { Line 10160  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 (!$env{'request.course.id'}) {  
             unless ((&Apache::lonnet::allowed('usc',$env{'request.role.domain'})) &&  
                     ($command =~ /^scantronupload/)) {  
                 # Not in a course.  
                 $env{'user.error.msg'}="/adm/grades::vgr:0:0:Cannot display grades page outside course context";  
                 return HTTP_NOT_ACCEPTABLE;  
             }  
         } elsif (!%perm) {  
             $request->internal_redirect('/adm/quickgrades');  
         }  
         &Apache::loncommon::content_type($request,'text/html');  
         $request->send_http_header;  
         unless ((($command eq 'submission' || $command eq 'versionsub')) && ($perm{'vgr'})) {  
             $request->print($start_page);   
         }  
  if ($command eq 'submission' && $perm{'vgr'}) {   if ($command eq 'submission' && $perm{'vgr'}) {
             my ($stuvcurrent,$stuvdisp,$versionform,$js);              my ($stuvcurrent,$stuvdisp,$versionform,$js);
             if (($env{'form.student'} ne '') && ($env{'form.userdom'} ne '')) {              if (($env{'form.student'} ne '') && ($env{'form.userdom'} ne '')) {
Line 10394  sub handler { Line 10213  sub handler {
                 $request->print($versionform);                  $request->print($versionform);
             }              }
             $request->print('<br clear="all" />');              $request->print('<br clear="all" />');
     ($env{'form.student'} eq '' ? &listStudents($request) : &submission($request,0,0));      ($env{'form.student'} eq '' ? &listStudents($request,$symb) : &submission($request,0,0,$symb));
         } 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'},
Line 10407  sub handler { Line 10226  sub handler {
             $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'},
                                          {href=>'',text=>'Select student'}],1,1);
       &pickStudentPage($request,$symb);
  } elsif ($command eq 'displayPage' && $perm{'vgr'}) {   } elsif ($command eq 'displayPage' && $perm{'vgr'}) {
     &displayPage($request);              &startpage($request,$symb,
                                         [{href=>&href_symb_cmd($symb,'all_for_one'),text=>'Grade page/folder for one student'},
                                          {href=>'',text=>'Select student'},
                                          {href=>'',text=>'Grade student'}],1,1);
       &displayPage($request,$symb);
  } elsif ($command eq 'gradeByPage' && $perm{'mgr'}) {   } elsif ($command eq 'gradeByPage' && $perm{'mgr'}) {
     &updateGradeByPage($request);              &startpage($request,$symb,[{href=>&href_symb_cmd($symb,'all_for_one'),text=>'Grade page/folder for one student'},
                                          {href=>'',text=>'Select student'},
                                          {href=>'',text=>'Grade student'},
                                          {href=>'',text=>'Store grades'}],1,1);
       &updateGradeByPage($request,$symb);
  } elsif ($command eq 'processGroup' && $perm{'vgr'}) {   } elsif ($command eq 'processGroup' && $perm{'vgr'}) {
     &processGroup($request);              &startpage($request,$symb,[{href=>'',text=>'...'},
                                          {href=>'',text=>'Modify grades'}]);
       &processGroup($request,$symb);
  } elsif ($command eq 'gradingmenu' && $perm{'vgr'}) {   } elsif ($command eq 'gradingmenu' && $perm{'vgr'}) {
     $request->print(&grading_menu($request));              &startpage($request,$symb);
  } elsif ($command eq 'submit_options' && $perm{'vgr'}) {      $request->print(&grading_menu($request,$symb));
     $request->print(&submit_options($request));   } 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'}) {
               &startpage($request,$symb,[{href=>'',text=>'Grade ungraded submissions'}]);
               $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'}) {   } elsif ($command eq 'viewgrades' && $perm{'vgr'}) {
     $request->print(&viewgrades($request));              &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'}) {   } elsif ($command eq 'handgrade' && $perm{'mgr'}) {
     $request->print(&processHandGrade($request));              &startpage($request,$symb,[{href=>'',text=>'...'},
                                          {href=>'',text=>'Store grades'}]);
       $request->print(&processHandGrade($request,$symb));
  } elsif ($command eq 'editgrades' && $perm{'mgr'}) {   } elsif ($command eq 'editgrades' && $perm{'mgr'}) {
     $request->print(&editgrades($request));              &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'}) {   } elsif ($command eq 'verify' && $perm{'vgr'}) {
     $request->print(&verifyreceipt($request));              &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'},
                                          {href=>'', text=>'Process clicker file'},
                                          {href=>'', text=>'Store grades'}]);
               $request->print(&assign_clicker_grades($request,$symb));
  } elsif ($command eq 'csvform' && $perm{'mgr'}) {   } elsif ($command eq 'csvform' && $perm{'mgr'}) {
     $request->print(&upcsvScores_form($request));              &startpage($request,$symb,[{href=>'', text=>'Upload Scores'}],1,1);
       $request->print(&upcsvScores_form($request,$symb));
  } elsif ($command eq 'csvupload' && $perm{'mgr'}) {   } elsif ($command eq 'csvupload' && $perm{'mgr'}) {
     $request->print(&csvupload($request));              &startpage($request,$symb,[{href=>'', text=>'Upload Scores'}],1,1);
       $request->print(&csvupload($request,$symb));
  } elsif ($command eq 'csvuploadmap' && $perm{'mgr'} ) {   } elsif ($command eq 'csvuploadmap' && $perm{'mgr'} ) {
     $request->print(&csvuploadmap($request));              &startpage($request,$symb,[{href=>'', text=>'Upload Scores'}],1,1);
       $request->print(&csvuploadmap($request,$symb));
  } elsif ($command eq 'csvuploadoptions' && $perm{'mgr'}) {   } elsif ($command eq 'csvuploadoptions' && $perm{'mgr'}) {
     if ($env{'form.associate'} ne 'Reverse Association') {      if ($env{'form.associate'} ne 'Reverse Association') {
  $request->print(&csvuploadoptions($request));                  &startpage($request,$symb,[{href=>'', text=>'Upload Scores'}],1,1);
    $request->print(&csvuploadoptions($request,$symb));
     } else {      } else {
  if ( $env{'form.upfile_associate'} ne 'reverse' ) {   if ( $env{'form.upfile_associate'} ne 'reverse' ) {
     $env{'form.upfile_associate'} = 'reverse';      $env{'form.upfile_associate'} = 'reverse';
  } else {   } else {
     $env{'form.upfile_associate'} = 'forward';      $env{'form.upfile_associate'} = 'forward';
  }   }
  $request->print(&csvuploadmap($request));                  &startpage($request,$symb,[{href=>'', text=>'Upload Scores'}],1,1);
    $request->print(&csvuploadmap($request,$symb));
     }      }
  } elsif ($command eq 'csvuploadassign' && $perm{'mgr'} ) {   } elsif ($command eq 'csvuploadassign' && $perm{'mgr'} ) {
     $request->print(&csvuploadassign($request));              &startpage($request,$symb,[{href=>'', text=>'Upload Scores'}],1,1);
       $request->print(&csvuploadassign($request,$symb));
  } elsif ($command eq 'scantron_selectphase' && $perm{'mgr'}) {   } elsif ($command eq 'scantron_selectphase' && $perm{'mgr'}) {
     $request->print(&scantron_selectphase($request));              &startpage($request,$symb,[{href=>'', text=>'Grade/Manage/Review Bubblesheets'}],1,1);
       $request->print(&scantron_selectphase($request,undef,$symb));
   } elsif ($command eq 'scantron_warning' && $perm{'mgr'}) {    } elsif ($command eq 'scantron_warning' && $perm{'mgr'}) {
      $request->print(&scantron_do_warning($request));              &startpage($request,$symb,[{href=>'', text=>'Grade/Manage/Review Bubblesheets'}],1,1);
        $request->print(&scantron_do_warning($request,$symb));
  } elsif ($command eq 'scantron_validate' && $perm{'mgr'}) {   } elsif ($command eq 'scantron_validate' && $perm{'mgr'}) {
     $request->print(&scantron_validate_file($request));              &startpage($request,$symb,[{href=>'', text=>'Grade/Manage/Review Bubblesheets'}],1,1);
       $request->print(&scantron_validate_file($request,$symb));
  } elsif ($command eq 'scantron_process' && $perm{'mgr'}) {   } elsif ($command eq 'scantron_process' && $perm{'mgr'}) {
     $request->print(&scantron_process_students($request));              &startpage($request,$symb,[{href=>'', text=>'Grade/Manage/Review Bubblesheets'}],1,1);
       $request->print(&scantron_process_students($request,$symb));
   } elsif ($command eq 'scantronupload' &&     } elsif ($command eq 'scantronupload' && 
   (&Apache::lonnet::allowed('usc',$env{'request.role.domain'})||    (&Apache::lonnet::allowed('usc',$env{'request.role.domain'})||
   &Apache::lonnet::allowed('usc',$env{'request.course.id'}))) {    &Apache::lonnet::allowed('usc',$env{'request.course.id'}))) {
      $request->print(&scantron_upload_scantron_data($request));               &startpage($request,$symb,[{href=>'', text=>'Grade/Manage/Review Bubblesheets'}],1,1);
        $request->print(&scantron_upload_scantron_data($request,$symb)); 
   } elsif ($command eq 'scantronupload_save' &&    } elsif ($command eq 'scantronupload_save' &&
   (&Apache::lonnet::allowed('usc',$env{'request.role.domain'})||    (&Apache::lonnet::allowed('usc',$env{'request.role.domain'})||
   &Apache::lonnet::allowed('usc',$env{'request.course.id'}))) {    &Apache::lonnet::allowed('usc',$env{'request.course.id'}))) {
      $request->print(&scantron_upload_scantron_data_save($request));              &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' &&    } elsif ($command eq 'scantron_download' &&
  &Apache::lonnet::allowed('usc',$env{'request.course.id'})) {   &Apache::lonnet::allowed('usc',$env{'request.course.id'})) {
      $request->print(&scantron_download_scantron_data($request));              &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);
               $request->print(&checkscantron_results($request,$symb));
           } elsif ($command eq 'downloadfilesselect' && $perm{'vgr'}) {
               &startpage($request,$symb,[{href=>'', text=>'Select which submissions to download'}]);
               $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 submissions'}]);
               &submit_download_link($request,$symb);
  } elsif ($command) {   } elsif ($command) {
               &startpage($request,$symb,[{href=>'', text=>'Access denied'}]);
     $request->print('<p class="LC_error">'.&mt('Access Denied ([_1])',$command).'</p>');      $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);
     }      }
     $request->print(&Apache::loncommon::end_page());      if ($env{'form.inhibitmenu'}) {
           $request->print(&Apache::loncommon::end_page());
       } else {
           &Apache::lonquickgrades::endGradeScreen($request);
       }
     &reset_caches();      &reset_caches();
     return OK;      return OK;
 }  }
Line 10503  described at http://www.lon-capa.org. Line 10390  described at http://www.lon-capa.org.
 =head1 OVERVIEW  =head1 OVERVIEW
   
 Do an ssi with retries:  Do an ssi with retries:
 While I'd love to factor out this with the vesrion in lonprintout,  While I'd love to factor out this with the version in lonprintout,
 that would either require a data coupling between modules, which I refuse to perpetuate (there's quite enough of that already), or would require the invention of another infrastructure  that would either require a data coupling between modules, which I refuse to perpetuate (there's quite enough of that already), or would require the invention of another infrastructure
 I'm not quite ready to invent (e.g. an ssi_with_retry object).  I'm not quite ready to invent (e.g. an ssi_with_retry object).
   
Line 10514  At least the logic that drives this has Line 10401  At least the logic that drives this has
 ssi_with_retries - Does the server side include of a resource.  ssi_with_retries - Does the server side include of a resource.
                      if the ssi call returns an error we'll retry it up to                       if the ssi call returns an error we'll retry it up to
                      the number of times requested by the caller.                       the number of times requested by the caller.
                      If we still have a proble, no text is appended to the                       If we still have a problem, no text is appended to the
                      output and we set some global variables.                       output and we set some global variables.
                      to indicate to the caller an SSI error occurred.                         to indicate to the caller an SSI error occurred.  
                      All of this is supposed to deal with the issues described                       All of this is supposed to deal with the issues described
                      in LonCAPA BZ 5631 see:                       in LON-CAPA BZ 5631 see:
                      http://bugs.lon-capa.org/show_bug.cgi?id=5631                       http://bugs.lon-capa.org/show_bug.cgi?id=5631
                      by informing the user that this happened.                       by informing the user that this happened.
   
Line 10550  ssi_with_retries() Line 10437  ssi_with_retries()
   
 =over  =over
   
   =head1 Routines to display previous version of a Task for a specific student
   
   Tasks are graded pass/fail. Students who have yet to pass a particular Task
   can receive another opportunity. Access to tasks is slot-based. If a slot
   requires a proctor to check-in the student, a new version of the Task will
   be created when the student is checked in to the new opportunity.
   
   If a particular student has tried two or more versions of a particular task,
   the submission screen provides a user with vgr privileges (e.g., a Course
   Coordinator) the ability to display a previous version worked on by the
   student.  By default, the current version is displayed. If a previous version
   has been selected for display, submission data are only shown that pertain
   to that particular version, and the interface to submit grades is not shown.
   
   =over 4
   
   =item show_previous_task_version()
   
   Displays a specified version of a student's Task, as the student sees it.
   
   Inputs: 2
           request - request object
           symb    - unique symb for current instance of resource
   
   Output: None.
   
   Side Effects: calls &show_problem() to print version of Task, with
                 version contained in form item: $env{'form.previousversion'}
   
   =item choose_task_version_form()
   
   Displays a web form used to select which version of a student's view of a
   Task should be displayed.  Either launches a pop-up window, or replaces
   content in existing pop-up, or replaces page in main window.
   
   Inputs: 4
           symb    - unique symb for current instance of resource
           uname   - username of student
           udom    - domain of student
           nomenu  - 1 if display is in a pop-up window, and hence no menu
                     breadcrumbs etc., are displayed
   
   Output: 4
           current   - student's current version
           displayed - student's version being displayed
           result    - scalar containing HTML for web form used to switch to
                       a different version (or a link to close window, if pop-up).
           js        - javascript for processing selection in versions web form
   
   Side Effects: None.
   
   =item previous_display_javascript()
   
   Inputs: 2
           nomenu  - 1 if display is in a pop-up window, and hence no menu
                     breadcrumbs etc., are displayed.
           current - student's current version number.
   
   Output: 1
           js      - javascript for processing selection in versions web form.
   
   Side Effects: None.
   
   =back
   
   =head1 Routines to process bubblesheet data.
   
   =over 4
   
 =item scantron_get_correction() :   =item scantron_get_correction() : 
   
    Builds the interface screen to interact with the operator to fix a     Builds the interface screen to interact with the operator to fix a
Line 10586  ssi_with_retries() Line 10542  ssi_with_retries()
                   or code-based randompick and/or randomorder.                    or code-based randompick and/or randomorder.
   
   
   
 =item  scantron_get_maxbubble() :   =item  scantron_get_maxbubble() : 
   
    Arguments:     Arguments:
Line 10665  ssi_with_retries() Line 10622  ssi_with_retries()
 =item navmap_errormsg() :  =item navmap_errormsg() :
   
    Returns HTML mark-up inside a <div></div> with a link to re-initialize the course.     Returns HTML mark-up inside a <div></div> with a link to re-initialize the course.
    Should be called whenever the request to instantiate a navmap object fails.       Should be called whenever the request to instantiate a navmap object fails.
   
   =back
   
 =back  =back
   

Removed from v.1.596.2.12.2.22  
changed lines
  Added in v.1.719


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