--- loncom/homework/grades.pm	2008/02/05 18:32:34	1.508
+++ loncom/homework/grades.pm	2008/03/03 23:36:30	1.512
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # The LON-CAPA Grading handler
 #
-# $Id: grades.pm,v 1.508 2008/02/05 18:32:34 www Exp $
+# $Id: grades.pm,v 1.512 2008/03/03 23:36:30 www Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -4681,9 +4681,10 @@ my %bubble_lines_per_response;     # no.
 
 my %first_bubble_line;             # First bubble line no. for each bubble.
 
-my %subdivided_bubble_lines;       # no. bubble lines for optionresponse 
-                                   # or matchresponse where an individual 
-                                   # response can have multiple lines
+my %subdivided_bubble_lines;       # no. bubble lines for optionresponse, 
+                                   # matchresponse or rankresponse, where 
+                                   # an individual response can have multiple 
+                                   # lines
 
 my %responsetype_per_response;     # responsetype for each response
 
@@ -5457,7 +5458,10 @@ sub scantron_validator_lettnum {
     my $occurrences = 0;
     if (($responsetype_per_response{$questnum-1} eq 'essayresponse') ||
         ($responsetype_per_response{$questnum-1} eq 'formularesponse') ||
-        ($responsetype_per_response{$questnum-1} eq 'stringresponse')) {
+        ($responsetype_per_response{$questnum-1} eq 'stringresponse') ||
+        ($responsetype_per_response{$questnum-1} eq 'imageresponse') ||
+        ($responsetype_per_response{$questnum-1} eq 'reactionresponse') ||
+        ($responsetype_per_response{$questnum-1} eq 'organicresponse')) {
         my @singlelines = split('',$currquest);
         foreach my $entry (@singlelines) {
             $occurrences = &occurence_count($entry,$matchon);
@@ -5556,7 +5560,10 @@ sub scantron_validator_positional {
         #
         if (($responsetype_per_response{$questnum-1} eq 'essayresponse') ||
             ($responsetype_per_response{$questnum-1} eq 'formularesponse') ||
-            ($responsetype_per_response{$questnum-1} eq 'stringresponse')) {
+            ($responsetype_per_response{$questnum-1} eq 'stringresponse') ||
+            ($responsetype_per_response{$questnum-1} eq 'imageresponse') ||
+            ($responsetype_per_response{$questnum-1} eq 'reactionresponse') ||
+            ($responsetype_per_response{$questnum-1} eq 'organicresponse')) {
             my $doubleerror = 0;
             while (($currquest >= $$scantron_config{'Qlength'}) && 
                    (!$doubleerror)) {
@@ -6030,8 +6037,7 @@ sub scantron_validate_file {
     }
     if (!$stop) {
 	my $warning=&scantron_warning_screen('Start Grading');
-	$r->print('
-<b>'.&mt('Validation process complete.').'<b><br />
+	$r->print(&mt('Validation process complete.').'<br />
 '.$warning.'
 <input type="submit" name="submit" value="'.&mt('Start Grading').'" />
 <input type="hidden" name="command" value="scantron_process" />
@@ -6792,13 +6798,14 @@ for multi and missing bubble cases).
                                   Numbered from 0 (but question numbers are from
                                   1.
    %first_bubble_line           - Starting bubble line for each question.
-   %subdivided_bubble_lines     - optionresponse and matchresponse type
-                                  problems render as separate sub-questions, 
+   %subdivided_bubble_lines     - optionresponse, matchresponse and rankresponse 
+                                  type problems render as separate sub-questions, 
                                   in exam mode. This hash contains a 
                                   comma-separated list of the lines per 
                                   sub-question.
-   %responsetype_per_response   - essayresponse, forumalaresponse, and
-                                  stringresponse type problem parts can have
+   %responsetype_per_response   - essayresponse, formularesponse,
+                                  stringresponse, imageresponse, reactionresponse,
+                                  and organicresponse type problem parts can have
                                   multiple lines per response if the weight
                                   assigned exceeds 10.  In this case, only
                                   one bubble per line is permitted, but more 
@@ -6832,7 +6839,10 @@ sub prompt_for_corrections {
         $r->print(&mt('The group of bubble lines below responds to a single question.').'<br />');
         if (($responsetype_per_response{$question-1} eq 'essayresponse') ||
             ($responsetype_per_response{$question-1} eq 'formularesponse') ||
-            ($responsetype_per_response{$question-1} eq 'stringresponse')) {
+            ($responsetype_per_response{$question-1} eq 'stringresponse') ||
+            ($responsetype_per_response{$question-1} eq 'imageresponse') ||
+            ($responsetype_per_response{$question-1} eq 'reactionresponse') ||
+            ($responsetype_per_response{$question-1} eq 'organicresponse')) {
             $r->print(&mt("Although this particular question type requires handgrading, the instructions for this question in the exam directed students to leave [quant,_1,line] blank on their scantron sheets.",$lines).'<br /><br />'.&mt('A non-zero score can be assigned to the student during scantron 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 {
             $r->print(&mt("Select at most one bubble in a single line and select 'No Bubble' in all the other lines. ")."<br />");
@@ -7113,7 +7123,7 @@ sub scantron_validate_doublebubble {
    which are the total number of bubble, lines, the number of bubble
    lines for response n and number of the first bubble line for response n,
    and a comma separated list of numbers of bubble lines for sub-questions
-   (for optionresponse items only), for response n.  
+   (for optionresponse, matchresponse, and rankresponse items), for response n.  
 
 =cut
 
@@ -7145,8 +7155,9 @@ sub scantron_get_maxbubble {
     my $response_number = 0;
     my $bubble_line     = 0;
     foreach my $resource (@resources) {
-        # Need to retrieve part IDs and response IDs because essayresponse
-        # items are not included in $analysis{'parts'} from lonnet::ssi.  
+        # Need to retrieve part IDs and response IDs because essayresponse,
+        # reactionresponse and organicresponse items are not included in 
+        # $analysis{'parts'} from lonnet::ssi.  
         my %possible_part_ids; 
         if (ref($resource->parts()) eq 'ARRAY') { 
             foreach my $part (@{$resource->parts()}) {
@@ -7174,7 +7185,9 @@ sub scantron_get_maxbubble {
         }
         # Add part_ids for any essayresponse items. 
         foreach my $part_id (keys(%possible_part_ids)) {
-            if ($analysis{$part_id.'.type'} eq 'essayresponse') {
+            if (($analysis{$part_id.'.type'} eq 'essayresponse') ||
+                ($analysis{$part_id.'.type'} eq 'reactionresponse') ||
+                ($analysis{$part_id.'.type'} eq 'organicresponse')) {
                 if (!grep(/^\Q$part_id\E$/,@parts)) {
                     push (@parts,$part_id);
                 }
@@ -7186,10 +7199,11 @@ sub scantron_get_maxbubble {
 
 	    # TODO - make this a persistent hash not an array.
 
-            # optionresponse and matchresponse type items render as
-            # separate sub-questions in exam mode.
+            # optionresponse, matchresponse and rankresponse type items 
+            # render as separate sub-questions in exam mode.
             if (($analysis{$part_id.'.type'} eq 'optionresponse') ||
-                ($analysis{$part_id.'.type'} eq 'matchresponse')) {
+                ($analysis{$part_id.'.type'} eq 'matchresponse') ||
+                ($analysis{$part_id.'.type'} eq 'rankresponse')) {
                 my ($numbub,$numshown);
                 if ($analysis{$part_id.'.type'} eq 'optionresponse') {
                     if (ref($analysis{$part_id.'.options'}) eq 'ARRAY') {
@@ -7199,6 +7213,10 @@ sub scantron_get_maxbubble {
                     if (ref($analysis{$part_id.'.items'}) eq 'ARRAY') {
                         $numbub = scalar(@{$analysis{$part_id.'.items'}});
                     }
+                } elsif ($analysis{$part_id.'.type'} eq 'rankresponse') {
+                    if (ref($analysis{$part_id.'.foils'}) eq 'ARRAY') {
+                        $numbub = scalar(@{$analysis{$part_id.'.foils'}});
+                    }
                 }
                 if (ref($analysis{$part_id.'.shown'}) eq 'ARRAY') {
                     $numshown = scalar(@{$analysis{$part_id.'.shown'}});
@@ -7710,14 +7728,12 @@ sub grading_menu {
                 $menudata->{'url'}.'" >'.
                 $menudata->{'name'}."</a></h3>\n";
         } else {
-            $Str .='    <h3><input type="button" value="'.&mt('Verify Receipt').'" '.
+            $Str .='<hr /><input type="button" value="'.&mt('Verify Receipt').'" '.
                 $menudata->{'jscript'}.
                 ' onClick="javascript:checkChoice(document.forms.gradingMenu,\'5\',\'verify\')" '.
-                ' /></h3>';
-            $Str .= ('&nbsp;'x8).
-		&mt(' receipt: [_1]',
-		    &Apache::lonnet::recprefix($env{'request.course.id'}).
-                    '-<input type="text" name="receipt" size="4" onChange="javascript:checkReceiptNo(this.form,\'OK\')" />');
+                ' /> '.
+		&Apache::lonnet::recprefix($env{'request.course.id'}).
+                    '-<input type="text" name="receipt" size="4" onChange="javascript:checkReceiptNo(this.form,\'OK\')" />';
         }
         $Str .= '    '.('&nbsp;'x8).$menudata->{'short_description'}.
             "\n";