');
hDoc.write('');
- hDoc.write("Text Color<\\/b><\\/td> Font Size<\\/b><\\/td> Font Style<\\/td><\\/tr>");
+ hDoc.write(" $lt{'txtc'}<\\/b><\\/td> $lt{'font'}<\\/b><\\/td> $lt{'fnst'}<\\/td><\\/tr>");
}
function highlightbody(clrval,clrtxt,clrsel,szval,sztxt,szsel,syval,sytxt,sysel) {
@@ -1628,8 +1650,8 @@ INNERJS
var hDoc = hwdWin.document;
hDoc.write("<\\/table>");
hDoc.write("<\\/td><\\/tr><\\/table> ");
- hDoc.write(" ");
- hDoc.write(" ");
+ hDoc.write(" ");
+ hDoc.write(" ");
hDoc.write("<\\/form>");
hDoc.write('$end_page_highlight_central');
hDoc.close();
@@ -1744,7 +1766,7 @@ sub handback_box {
my ($symb,$uname,$udom,$counter,$partid,$record,$res_error_pointer) = @_;
my ($partlist,$handgrade,$responseType) = &response_type($symb,$res_error_pointer);
my (@respids);
- my @part_response_id = &flatten_responseType($responseType);
+ my @part_response_id = &flatten_responseType($responseType);
foreach my $part_response_id (@part_response_id) {
my ($part,$resp) = @{ $part_response_id };
if ($part eq $partid) {
@@ -1756,9 +1778,10 @@ sub handback_box {
my $prefix = $counter.'_'.$partid.'_'.$respid.'_';
my $files=&get_submitted_files($udom,$uname,$partid,$respid,$record);
next if (!@$files);
- my $file_counter = 1;
+ my $file_counter = 0;
foreach my $file (@$files) {
if ($file =~ /\/portfolio\//) {
+ $file_counter++;
my ($file_path, $file_disp) = ($file =~ m|(.+/)(.+)$|);
my ($name,$version,$ext) = &file_name_version_ext($file_disp);
$file_disp = "$name.$ext";
@@ -1766,11 +1789,14 @@ sub handback_box {
$result.=&mt('Return commented version of [_1] to student.',
''.$file_disp.' ');
$result.=' '."\n";
- $result.=' ';
- $result.='('.&mt('File will be uploaded when you click on Save & Next below.').') ';
- $file_counter++;
+ $result.=' '."\n";
}
}
+ if ($file_counter) {
+ $result .= ' '."\n".
+ ''.
+ '('.&mt('File(s) will be uploaded when you click on Save & Next below.',$file_counter).') ';
+ }
}
return $result;
}
@@ -1996,15 +2022,22 @@ sub submission {
# if ($env{'form.handgrade'} eq 'yes') {
if (1) {
+
+ my %lt = &Apache::lonlocal::texthash(
+ keyw => 'Keyword Options',
+ list => 'List',
+ past => 'Paste Selection to List',
+ high => 'Highlight Attribute',
+ );
#
# Print out the keyword options line
#
$request->print(<Keyword Options:
-List
+$lt{'keyw'}:
+$lt{'list'}
Paste Selection to List
-Highlight Attribute
+ CLASS="page">$lt{'past'}
+$lt{'high'}
KEYWORDS
#
# Load the other essays for similarity check
@@ -2526,7 +2559,7 @@ sub processHandGrade {
undef,undef,$showsymb,
$restitle);
$request->print(' '.&mt('Sending message to [_1]',$uname.':'.$udom).': '.
- $msgstatus);
+ $msgstatus.' ');
}
if ($env{'form.collaborator'.$ctr}) {
my @collabstrs=&Apache::loncommon::get_env_multiple("form.collaborator$ctr");
@@ -2704,7 +2737,7 @@ sub processHandGrade {
$ctr++;
}
if ($total < 0) {
- my $the_end.=&mt('Message: No more students for this section or class.').' '."\n";
+ my $the_end.=''.&mt('[_1]Message:[_2] No more students for this section or class.','',' ').'
'."\n";
$request->print($the_end);
}
return '';
@@ -2855,18 +2888,19 @@ sub handback_files {
$request->print(' '.&navmap_errormsg().' ');
return;
}
+ my @handedback;
+ my $file_msg;
my @part_response_id = &flatten_responseType($responseType);
foreach my $part_response_id (@part_response_id) {
my ($part_id,$resp_id) = @{ $part_response_id };
my $part_resp = join('_',@{ $part_response_id });
- if (($env{'form.'.$newflg.'_'.$part_resp.'_returndoc1'}) && ($new_part == $part_id)) {
- # if multiple files are uploaded names will be 'returndoc2','returndoc3'
- my $file_counter = 1;
- my $file_msg;
- while ($env{'form.'.$newflg.'_'.$part_resp.'_returndoc'.$file_counter}) {
- my $fname=$env{'form.'.$newflg.'_'.$part_resp.'_returndoc'.$file_counter.'.filename'};
+ 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++) {
+ # if multiple files are uploaded names will be 'returndoc2','returndoc3'
+ if ($env{'form.'.$newflg.'_'.$part_resp.'_returndoc'.$counter}) {
+ my $fname=$env{'form.'.$newflg.'_'.$part_resp.'_returndoc'.$counter.'.filename'};
my ($directory,$answer_file) =
- ($env{'form.'.$newflg.'_'.$part_resp.'_origdoc'.$file_counter} =~ /^(.*?)([^\/]*)$/);
+ ($env{'form.'.$newflg.'_'.$part_resp.'_origdoc'.$counter} =~ /^(.*?)([^\/]*)$/);
my ($answer_name,$answer_ver,$answer_ext) =
&file_name_version_ext($answer_file);
my ($portfolio_path) = ($directory =~ /^.+$stuname\/portfolio(.*)/);
@@ -2876,43 +2910,55 @@ sub handback_files {
# fix file name
my ($save_file_name) = (($directory.$answer_name.".$version.".$answer_ext) =~ /^.+\/${stuname}\/(.*)/);
my $result=&Apache::lonnet::finishuserfileupload($stuname,$domain,
- $newflg.'_'.$part_resp.'_returndoc'.$file_counter,
+ $newflg.'_'.$part_resp.'_returndoc'.$counter,
$save_file_name);
if ($result !~ m|^/uploaded/|) {
$request->print(''.
&mt('An error occurred ([_1]) while trying to upload [_2].',
- $result,$newflg.'_'.$part_resp.'_returndoc'.$file_counter).
+ $result,$newflg.'_'.$part_resp.'_returndoc'.$counter).
' ');
} else {
# mark the file as read only
- my @files = ($save_file_name);
- my @what = ($symb,$env{'request.course.id'},'handback');
- &Apache::lonnet::mark_as_readonly($domain,$stuname,\@files,\@what);
+ push(@handedback,$save_file_name);
if (exists($$newrecord{"resource.$new_part.$resp_id.handback"})) {
$$newrecord{"resource.$new_part.$resp_id.handback"}.=',';
}
$$newrecord{"resource.$new_part.$resp_id.handback"} .= $save_file_name;
- $file_msg.= "\n".''.$save_file_name." ";
-
+ $file_msg.= ''.$save_file_name." ";
}
- $request->print(" ".$fname." will be the uploaded file name");
- $request->print(" ".$env{'form.'.$newflg.'_'.$part_resp.'_origdoc'.$file_counter});
- $file_counter++;
+ $request->print(' '.&mt('[_1] will be the uploaded file name [_2]',''.$fname.' ',''.$env{'form.'.$newflg.'_'.$part_resp.'_origdoc'.$counter}.' '));
}
- my $subject = "File Handed Back by Instructor ";
- my $message = "A file has been returned that was originally submitted in reponse to: ";
- $message .= "".&Apache::lonnet::gettitle($symb)." ";
- $message .= ' The returned file(s) are named: '. $file_msg;
- $message .= " and can be found in your portfolio space.";
- my ($feedurl,$showsymb) =
- &get_feedurl_and_symb($symb,$domain,$stuname);
- my $restitle = &Apache::lonnet::gettitle($symb);
- my $msgstatus =
- &Apache::lonmsg::user_normal_msg($stuname,$domain,$subject.
- ' (File Returned) ['.$restitle.']',$message,undef,
- $feedurl,undef,undef,undef,$showsymb,$restitle);
}
}
+ }
+ if (@handedback > 0) {
+ $request->print(' ');
+ my @what = ($symb,$env{'request.course.id'},'handback');
+ &Apache::lonnet::mark_as_readonly($domain,$stuname,\@handedback,\@what);
+ my $user_lh = &Apache::loncommon::user_lang($stuname,$domain,$env{'request.course.id'});
+ my ($subject,$message);
+ if (scalar(@handedback) == 1) {
+ $subject = &mt_user($user_lh,'File Handed Back by Instructor');
+ $message = &mt_user($user_lh,'A file has been returned that was originally submitted in response to: ');
+ } else {
+ $subject = &mt_user($user_lh,'Files Handed Back by Instructor');
+ $message = &mt_user($user_lh,'Files have been returned that were originally submitted in response to: ');
+ }
+ $message .= "".&Apache::lonnet::gettitle($symb)."
";
+ $message .= &mt_user($user_lh,'The returned file(s) are named: [_1]'," $file_msg ").
+ &mt_user($user_lh,'The file(s) can be found in your [_1]portfolio[_2].','',' ');
+ my ($feedurl,$showsymb) =
+ &get_feedurl_and_symb($symb,$domain,$stuname);
+ my $restitle = &Apache::lonnet::gettitle($symb);
+ $subject .= ' '.&mt_user($user_lh,'(File Returned)').' ['.$restitle.']';
+ my $msgstatus =
+ &Apache::lonmsg::user_normal_msg($stuname,$domain,$subject,
+ $message,undef,$feedurl,undef,undef,undef,$showsymb,
+ $restitle);
+ if ($msgstatus) {
+ $request->print(&mt('Notification message status: [_1]',''.$msgstatus.' ').' ');
+ }
+ }
return;
}
@@ -4044,6 +4090,7 @@ sub csvuploadassign {
my ($classlist) = &getclasslist('all',0);
my @notallowed;
my @skipped;
+ my @warnings;
my $countdone=0;
foreach my $grade (@gradedata) {
my %entries=&Apache::loncommon::record_sep($grade);
@@ -4093,7 +4140,7 @@ sub csvuploadassign {
my $award=($pcr == 0) ? 'incorrect_by_override'
: 'correct_by_override';
if ($pcr>1) {
- push(@skipped,&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.solved"}=$award;
@@ -4139,6 +4186,10 @@ sub csvuploadassign {
}
}
$request->print(' '.&Apache::lonhtmlcommon::confirm_success(&mt("Saved scores for [quant,_1,student]",$countdone),$countdone==0));
+ if (@warnings) {
+ $request->print(' '.&Apache::lonhtmlcommon::confirm_success(&mt('Warnings generated for the following saved scores:'),1).' ');
+ $request->print(join(', ',@warnings));
+ }
if (@skipped) {
$request->print(' '.&Apache::lonhtmlcommon::confirm_success(&mt('No scores stored for the following username(s):'),1).' ');
$request->print(join(', ',@skipped));
@@ -4786,12 +4837,12 @@ sub updateGradeByPage {
from the file that we are parsing that represents one entire sheet
'bubble line' refers to the data
- representing the line of bubbles that are on the physical bubble sheet
+ representing the line of bubbles that are on the physical bubblesheet
-The overall process is that a scanned in bubble sheet data is uploaded
+The overall process is that a scanned in bubblesheet data is uploaded
into a course. When a user wants to grade, they select a
-sequence/folder of resources, a file of bubble sheet info, and pick
+sequence/folder of resources, a file of bubblesheet info, and pick
one of the predefined configurations for what each scanline looks
like.
@@ -4807,14 +4858,14 @@ username:domain.
During the validation phase the instructor can choose to skip scanlines.
-After the validation phase, there are now 3 bubble sheet files
+After the validation phase, there are now 3 bubblesheet files
scantron_original_filename (unmodified original file)
scantron_corrected_filename (file where the corrected information has replaced the original information)
scantron_skipped_filename (contains the exact text of scanlines that where skipped)
Also there is a separate hash nohist_scantrondata that contains extra
-correction information that isn't representable in the bubble sheet
+correction information that isn't representable in the bubblesheet
file (see &scantron_getfile() for more information)
After all scanlines are either valid, marked as valid or skipped, then
@@ -5109,7 +5160,7 @@ sub scantron_CODEunique {
=item scantron_selectphase
- Generates the initial screen to start the bubble sheet process.
+ Generates the initial screen to start the bubblesheet process.
Allows for - starting a grading run.
- downloading existing scan data (original, corrected
or skipped info)
@@ -5350,7 +5401,8 @@ sub scantron_selectphase {
LastName - column that the last name starts in
LastNameLength - number of columns that the last name spans
-
+ BubblesPerRow - number of bubbles available in each row used to
+ bubble an answer. (If not specified, 10 assumed).
=cut
sub get_scantron_config {
@@ -5380,6 +5432,7 @@ sub get_scantron_config {
$config{'FirstNamelength'}=$config[14];
$config{'LastName'}=$config[15];
$config{'LastNamelength'}=$config[16];
+ $config{'BubblesPerRow'}=$config[17];
last;
}
return %config;
@@ -6129,7 +6182,7 @@ sub remember_current_skipped {
=item check_for_error
Checks if there was an error when attempting to remove a specific
- scantron_.. bubble sheet data file. Prints out an error if
+ scantron_.. bubblesheet data file. Prints out an error if
something went wrong.
=cut
@@ -6151,7 +6204,7 @@ sub check_for_error {
=cut
sub scantron_warning_screen {
- my ($button_text)=@_;
+ my ($button_text,$symb)=@_;
my $title=&Apache::lonnet::gettitle($env{'form.selectpage'});
my %scantron_config=&get_scantron_config($env{'form.scantron_format'});
my $CODElist;
@@ -6174,9 +6227,8 @@ sub scantron_warning_screen {
'.&mt('Data File that will be used:').' '.$env{'form.scantron_selectfile'}.'
'.$CODElist.'
-
- '.&mt('If this information is correct, please click on \'[_1]\'.',&mt($button_text)).'
- '.&mt('If something is incorrect, please click the \'Grading Menu\' button to start over.').'
+ '.&mt('If this information is correct, please click on \'[_1]\'.',&mt($button_text)).'
+'.&mt('If something is incorrect, please return to [_1]Grade/Manage/Review Bubblesheets[_2] to start over.','',' ').'
');
@@ -6210,7 +6262,7 @@ sub scantron_do_warning {
$r->print(''.&mt("You have not selected the format of the student's response data.").'
');
}
} else {
- my $warning=&scantron_warning_screen('Grading: Validate Records');
+ my $warning=&scantron_warning_screen('Grading: Validate Records',$symb);
$r->print('
'.$warning.'
@@ -6264,7 +6316,7 @@ SCANTRONFORM
=item scantron_validate_file
- Dispatch routine for doing validation of a bubble sheet data file.
+ Dispatch routine for doing validation of a bubblesheet data file.
Also processes any necessary information resets that need to
occur before validation begins (ignore previous corrections,
@@ -6301,7 +6353,8 @@ sub scantron_validate_file {
#get the student pick code ready
$r->print(&Apache::loncommon::studentbrowser_javascript());
my $nav_error;
- my $max_bubble=&scantron_get_maxbubble(\$nav_error);
+ my %scantron_config=&get_scantron_config($env{'form.scantron_format'});
+ my $max_bubble=&scantron_get_maxbubble(\$nav_error,\%scantron_config);
if ($nav_error) {
$r->print(&navmap_errormsg());
return '';
@@ -6331,7 +6384,7 @@ sub scantron_validate_file {
}
}
if (!$stop) {
- my $warning=&scantron_warning_screen('Start Grading');
+ my $warning=&scantron_warning_screen('Start Grading',$symb);
$r->print(&mt('Validation process complete.').' '.
$warning.
&mt('Perform verification for each student after storage of submissions?').
@@ -6341,7 +6394,7 @@ sub scantron_validate_file {
' '.&mt('No').
' '.
&mt('Grading will take longer if you use verification.').' '.
- &mt("Alternatively, the 'Review bubblesheet data' utility (see grading menu) can be used for all students after grading is complete.").' '.
+ &mt('Otherwise, Grade/Manage/Review Bubblesheets [_1] Review bubblesheet data can be used once grading is complete.','»').' '.
' '.
' '."\n");
} else {
@@ -6353,7 +6406,7 @@ sub scantron_validate_file {
$r->print(' ');
$r->print(' '.&mt('this error').' ');
- $r->print(" ".&mt("Or click the 'Grading Menu' button to start over.")."
");
+ $r->print(''.&mt('Or return to [_1]Grade/Manage/Review Bubblesheets[_2] to start over.','',' ').'
');
} else {
if ($validate_phases[$currentphase] eq 'doublebubble' || $validate_phases[$currentphase] eq 'missingbubbles') {
$r->print(' ');
@@ -6374,7 +6427,7 @@ sub scantron_validate_file {
=item scantron_remove_file
- Removes the requested bubble sheet data file, makes sure that
+ Removes the requested bubblesheet data file, makes sure that
scantron_original_ is never removed
@@ -6399,7 +6452,7 @@ sub scantron_remove_file {
=item scantron_remove_scan_data
- Removes all scan_data correction for the requested bubble sheet
+ Removes all scan_data correction for the requested bubblesheet
data file. (In the case that both the are doing skipped records we need
to remember the old skipped lines for the time being so that element
persists for a while.)
@@ -6436,7 +6489,7 @@ sub scantron_remove_scan_data {
=item scantron_getfile
- Fetches the requested bubble sheet data file (all 3 versions), and
+ Fetches the requested bubblesheet data file (all 3 versions), and
the scan_data hash
Arguments:
@@ -6536,7 +6589,7 @@ sub lonnet_putfile {
=item scantron_putfile
- Stores the current version of the bubble sheet data files, and the
+ Stores the current version of the bubblesheet data files, and the
scan_data hash. (Does not modify the original version only the
corrected and skipped versions.
@@ -6630,7 +6683,7 @@ sub get_todo_count {
=item scantron_put_line
- Updates the 'corrected' or 'skipped' versions of the bubble sheet
+ Updates the 'corrected' or 'skipped' versions of the bubblesheet
data file.
Arguments:
@@ -6754,7 +6807,7 @@ sub scantron_validate_ID {
my ($scanlines,$scan_data)=&scantron_getfile();
my $nav_error;
- &scantron_get_maxbubble(\$nav_error); # parse needs the bubble_lines.. array.
+ &scantron_get_maxbubble(\$nav_error,\%scantron_config); # parse needs the bubble_lines.. array.
if ($nav_error) {
$r->print(&navmap_errormsg());
return(1,$currentphase);
@@ -6819,19 +6872,28 @@ sub scantron_get_correction {
#the previous one or the current one
if ( $$scan_record{'scantron.PaperID'} =~ /\S/) {
- $r->print("".&mt("An error was detected ($error) ".
- " for PaperID [_1] ",
- $$scan_record{'scantron.PaperID'})."
\n");
+ $r->print(
+ ''
+ .&mt('An error was detected ([_1]) for PaperID [_2]',
+ "$error ",
+ ''.$$scan_record{'scantron.PaperID'}.' ')
+ ."
\n");
} else {
- $r->print("".&mt("An error was detected ($error) ".
- " in scanline [_1]
[_2] ",
- $i,$line)." \n");
- }
- my $message="".&mt("The ID on the form is [_1] ".
- "The name on the paper is [_2],[_3]",
- $$scan_record{'scantron.ID'},
- $$scan_record{'scantron.LastName'},
- $$scan_record{'scantron.FirstName'})."
";
+ $r->print(
+ ''
+ .&mt('An error was detected ([_1]) in scanline [_2] [_3]',
+ "$error ", $i, "
$line ")
+ ." \n");
+ }
+ my $message =
+ ''
+ .&mt('The ID on the form is [_1]',
+ "$$scan_record{'scantron.ID'} ")
+ .' '
+ .&mt('The name on the paper is [_2], [_3]',
+ $$scan_record{'scantron.LastName'},
+ $$scan_record{'scantron.FirstName'})
+ .'
';
$r->print(' '."\n");
$r->print(' '."\n");
@@ -6841,10 +6903,10 @@ sub scantron_get_correction {
if ($error =~ /ID$/) {
if ($error eq 'incorrectID') {
- $r->print("".&mt("The encoded ID is not in the classlist").
+ $r->print('
'.&mt("The encoded ID is not in the classlist").
"
\n");
} elsif ($error eq 'duplicateID') {
- $r->print("".&mt("The encoded ID has also been used by a previous paper [_1]",$arg)."
\n");
+ $r->print(''.&mt("The encoded ID has also been used by a previous paper [_1]",$arg)."
\n");
}
$r->print($message);
$r->print("".&mt("How should I handle this?")." \n");
@@ -6860,14 +6922,15 @@ sub scantron_get_correction {
$r->print('');
} elsif ($error =~ /CODE$/) {
if ($error eq 'incorrectCODE') {
- $r->print("
".&mt("The encoded CODE is not in the list of possible CODEs.")."
\n");
+ $r->print(''.&mt("The encoded CODE is not in the list of possible CODEs.")."
\n");
} elsif ($error eq 'duplicateCODE') {
- $r->print("".&mt("The encoded CODE has also been used by a previous paper [_1], and CODEs are supposed to be unique.",join(', ',@{$arg}))."
\n");
+ $r->print(''.&mt("The encoded CODE has also been used by a previous paper [_1], and CODEs are supposed to be unique.",join(', ',@{$arg}))."
\n");
}
- $r->print("".&mt("The CODE on the form is '[_1]' ",
- $$scan_record{'scantron.CODE'})." \n");
+ $r->print("
".&mt('The CODE on the form is [_1]',
+ "'$$scan_record{'scantron.CODE'}' ")
+ ."
\n");
$r->print($message);
- $r->print("".&mt("How should I handle this?")." \n");
+ $r->print("
".&mt("How should I handle this?")."
\n");
$r->print("\n ");
my $i=0;
if ($error eq 'incorrectCODE'
@@ -6894,7 +6957,7 @@ sub scantron_get_correction {
$r->print("
- ".&mt("Use the CODE [_1] that is was on the paper, ignoring the error.",
+ ".&mt("Use the CODE [_1] that was on the paper, ignoring the error.",
"".$$scan_record{'scantron.CODE'}." ")."
");
$r->print("\n ");
@@ -6932,7 +6995,7 @@ ENDSCRIPT
" "));
$r->print("\n ");
} elsif ($error eq 'doublebubble') {
- $r->print("".&mt("There have been multiple bubbles scanned for some question(s)")."
\n");
+ $r->print(''.&mt("There have been multiple bubbles scanned for some question(s)")."
\n");
# The form field scantron_questions is acutally a list of line numbers.
# represented by this form so:
@@ -6950,7 +7013,7 @@ ENDSCRIPT
}
$r->print(&verify_bubbles_checked(@lines_to_correct));
} elsif ($error eq 'missingbubble') {
- $r->print("".&mt("There have been no bubbles scanned for some question(s)")."
\n");
+ $r->print(''.&mt("There have been [_1]no[_2] bubbles scanned for some question(s)",'',' ')."
\n");
$r->print($message);
$r->print("".&mt("Please indicate which bubble should be used for grading.")."
");
$r->print(&mt("Some questions have no scanned bubbles.")."\n");
@@ -7153,7 +7216,19 @@ sub scantron_bubble_selector {
my $max=$$scan_config{'Qlength'};
my $scmode=$$scan_config{'Qon'};
- if ($scmode eq 'number' || $scmode eq 'letter') { $max=10; }
+ if ($scmode eq 'number' || $scmode eq 'letter') {
+ if (($$scan_config{'BubblesPerRow'} =~ /^\d+$/) &&
+ ($$scan_config{'BubblesPerRow'} > 0)) {
+ $max=$$scan_config{'BubblesPerRow'};
+ if (($scmode eq 'number') && ($max > 10)) {
+ $max = 10;
+ } elsif (($scmode eq 'letter') && $max > 26) {
+ $max = 26;
+ }
+ } else {
+ $max = 10;
+ }
+ }
my @alphabet=('A'..'Z');
$r->print(&Apache::loncommon::start_data_table().
@@ -7308,7 +7383,7 @@ sub scantron_validate_CODE {
my %allcodes=&get_codes();
my $nav_error;
- &scantron_get_maxbubble(\$nav_error); # parse needs the lines per response array.
+ &scantron_get_maxbubble(\$nav_error,\%scantron_config); # parse needs the lines per response array.
if ($nav_error) {
$r->print(&navmap_errormsg());
return(1,$currentphase);
@@ -7367,7 +7442,7 @@ sub scantron_validate_doublebubble {
my %scantron_config=&get_scantron_config($env{'form.scantron_format'});
my ($scanlines,$scan_data)=&scantron_getfile();
my $nav_error;
- &scantron_get_maxbubble(\$nav_error); # parse needs the bubble line array.
+ &scantron_get_maxbubble(\$nav_error,\%scantron_config); # parse needs the bubble line array.
if ($nav_error) {
$r->print(&navmap_errormsg());
return(1,$currentphase);
@@ -7389,7 +7464,7 @@ sub scantron_validate_doublebubble {
sub scantron_get_maxbubble {
- my ($nav_error) = @_;
+ my ($nav_error,$scantron_config) = @_;
if (defined($env{'form.scantron_maxbubble'}) &&
$env{'form.scantron_maxbubble'}) {
&restore_bubble_lines();
@@ -7408,6 +7483,7 @@ sub scantron_get_maxbubble {
}
my $map=$navmap->getResourceByUrl($sequence);
my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0);
+ my $bubbles_per_row = &bubblesheet_bubbles_per_row($scantron_config);
&Apache::lonxml::clear_problem_counter();
@@ -7423,7 +7499,7 @@ sub scantron_get_maxbubble {
my $response_number = 0;
my $bubble_line = 0;
foreach my $resource (@resources) {
- my ($analysis,$parts) = &scantron_partids_tograde($resource,$cid,$uname,$udom);
+ my ($analysis,$parts) = &scantron_partids_tograde($resource,$cid,$uname,$udom,undef,$bubbles_per_row);
if ((ref($analysis) eq 'HASH') && (ref($parts) eq 'ARRAY')) {
foreach my $part_id (@{$parts}) {
my $lines;
@@ -7452,9 +7528,10 @@ sub scantron_get_maxbubble {
if (ref($analysis->{$part_id.'.shown'}) eq 'ARRAY') {
$numshown = scalar(@{$analysis->{$part_id.'.shown'}});
}
- my $bubbles_per_line = 10;
- my $inner_bubble_lines = int($numbub/$bubbles_per_line);
- if (($numbub % $bubbles_per_line) != 0) {
+ my $bubbles_per_row =
+ &bubblesheet_bubbles_per_row($scantron_config);
+ my $inner_bubble_lines = int($numbub/$bubbles_per_row);
+ if (($numbub % $bubbles_per_row) != 0) {
$inner_bubble_lines++;
}
for (my $i=0; $i<$numshown; $i++) {
@@ -7465,7 +7542,7 @@ sub scantron_get_maxbubble {
$lines = $numshown * $inner_bubble_lines;
} else {
$lines = $analysis->{"$part_id.bubble_lines"};
- }
+ }
$first_bubble_line{$response_number} = $bubble_line;
$bubble_lines_per_response{$response_number} = $lines;
@@ -7486,6 +7563,18 @@ sub scantron_get_maxbubble {
return $env{'form.scantron_maxbubble'};
}
+sub bubblesheet_bubbles_per_row {
+ my ($scantron_config) = @_;
+ my $bubbles_per_row;
+ if (ref($scantron_config) eq 'HASH') {
+ $bubbles_per_row = $scantron_config->{'BubblesPerRow'};
+ }
+ if ((!$bubbles_per_row) || ($bubbles_per_row < 1)) {
+ $bubbles_per_row = 10;
+ }
+ return $bubbles_per_row;
+}
+
sub scantron_validate_missingbubbles {
my ($r,$currentphase) = @_;
#get student info
@@ -7496,7 +7585,7 @@ sub scantron_validate_missingbubbles {
my %scantron_config=&get_scantron_config($env{'form.scantron_format'});
my ($scanlines,$scan_data)=&scantron_getfile();
my $nav_error;
- my $max_bubble=&scantron_get_maxbubble(\$nav_error);
+ my $max_bubble=&scantron_get_maxbubble(\$nav_error,\%scantron_config);
if ($nav_error) {
return(1,$currentphase);
}
@@ -7554,6 +7643,8 @@ sub scantron_process_students {
my $default_form_data=&defaultFormData($symb);
my %scantron_config=&get_scantron_config($env{'form.scantron_format'});
+ my $bubbles_per_row =
+ &bubblesheet_bubbles_per_row(\%scantron_config);
my ($scanlines,$scan_data)=&scantron_getfile();
my $classlist=&Apache::loncoursedata::get_classlist();
my %idmap=&username_to_idmap($classlist);
@@ -7566,7 +7657,7 @@ sub scantron_process_students {
my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0);
my (%grader_partids_by_symb,%grader_randomlists_by_symb);
&graders_resources_pass(\@resources,\%grader_partids_by_symb,
- \%grader_randomlists_by_symb);
+ \%grader_randomlists_by_symb,$bubbles_per_row);
my $resource_error;
foreach my $resource (@resources) {
my $ressymb;
@@ -7578,7 +7669,7 @@ sub scantron_process_students {
}
my ($analysis,$parts) =
&scantron_partids_tograde($resource,$env{'request.course.id'},
- $env{'user.name'},$env{'user.domain'},1);
+ $env{'user.name'},$env{'user.domain'},1,$bubbles_per_row);
$grader_partids_by_symb{$ressymb} = $parts;
if (ref($analysis) eq 'HASH') {
if (ref($analysis->{'parts_withrandomlist'}) eq 'ARRAY') {
@@ -7616,7 +7707,7 @@ SCANTRONFORM
my $started;
my $nav_error;
- &scantron_get_maxbubble(\$nav_error); # Need the bubble lines array to parse.
+ &scantron_get_maxbubble(\$nav_error,\%scantron_config); # Need the bubble lines array to parse.
if ($nav_error) {
$r->print(&navmap_errormsg());
return '';
@@ -7672,7 +7763,7 @@ SCANTRONFORM
if ((exists($grader_randomlists_by_symb{$ressymb})) ||
(ref($grader_partids_by_symb{$ressymb}) ne 'ARRAY')) {
my ($analysis,$parts) =
- &scantron_partids_tograde($resource,$env{'request.course.id'},$uname,$udom);
+ &scantron_partids_tograde($resource,$env{'request.course.id'},$uname,$udom,undef,$bubbles_per_row);
$partids_by_symb{$ressymb} = $parts;
} else {
$partids_by_symb{$ressymb} = $grader_partids_by_symb{$ressymb};
@@ -7701,7 +7792,8 @@ SCANTRONFORM
}
if (&grade_student_bubbles($r,$uname,$udom,$scan_record,$scancode,
- \@resources,\%partids_by_symb) eq 'ssi_error') {
+ \@resources,\%partids_by_symb,
+ $bubbles_per_row) eq 'ssi_error') {
$ssi_error = 0; # So end of handler error message does not trigger.
$r->print("");
&ssi_print_error($r);
@@ -7728,7 +7820,8 @@ SCANTRONFORM
if ($studentrecord ne $studentdata) {
&Apache::lonxml::clear_problem_counter();
if (&grade_student_bubbles($r,$uname,$udom,$scan_record,$scancode,
- \@resources,\%partids_by_symb) eq 'ssi_error') {
+ \@resources,\%partids_by_symb,
+ $bubbles_per_row) eq 'ssi_error') {
$ssi_error = 0; # So end of handler error message does not trigger.
$r->print("");
&ssi_print_error($r);
@@ -7747,12 +7840,12 @@ SCANTRONFORM
$studentrecord .= $recording;
}
if ($studentrecord ne $studentdata) {
- $r->print('');
+ $r->print('');
if ($scancode eq '') {
- $r->print(&mt('Mismatch grading bubble sheet for user: [_1] with ID: [_2].',
+ $r->print(&mt('Mismatch grading bubblesheet for user: [_1] with ID: [_2].',
$uname.':'.$udom,$scan_record->{'scantron.ID'}));
} else {
- $r->print(&mt('Mismatch grading bubble sheet for user: [_1] with ID: [_2] and CODE: [_3].',
+ $r->print(&mt('Mismatch grading bubblesheet for user: [_1] with ID: [_2] and CODE: [_3].',
$uname.':'.$udom,$scan_record->{'scantron.ID'},$scancode));
}
$r->print(' '.&Apache::loncommon::start_data_table()."\n".
@@ -7760,12 +7853,12 @@ SCANTRONFORM
'
'.&mt('Source').' '.&mt('Bubbled responses').' '.
&Apache::loncommon::end_data_table_header_row()."\n".
&Apache::loncommon::start_data_table_row().
- ''.&mt('Bubble Sheet').' '.
- ''.$studentdata.' '.
+ ''.&mt('Bubblesheet').' '.
+ ''.$studentdata.' '.
&Apache::loncommon::end_data_table_row().
&Apache::loncommon::start_data_table_row().
- 'Stored submissions '.
- ''.$studentrecord.' '."\n".
+ ''.&mt('Stored submissions').' '.
+ ''.$studentrecord.' '."\n".
&Apache::loncommon::end_data_table_row().
&Apache::loncommon::end_data_table().'');
} else {
@@ -7791,14 +7884,15 @@ SCANTRONFORM
}
sub graders_resources_pass {
- my ($resources,$grader_partids_by_symb,$grader_randomlists_by_symb) = @_;
+ my ($resources,$grader_partids_by_symb,$grader_randomlists_by_symb,
+ $bubbles_per_row) = @_;
if ((ref($resources) eq 'ARRAY') && (ref($grader_partids_by_symb)) &&
(ref($grader_randomlists_by_symb) eq 'HASH')) {
foreach my $resource (@{$resources}) {
my $ressymb = $resource->symb();
my ($analysis,$parts) =
&scantron_partids_tograde($resource,$env{'request.course.id'},
- $env{'user.name'},$env{'user.domain'},1);
+ $env{'user.name'},$env{'user.domain'},1,$bubbles_per_row);
$grader_partids_by_symb->{$ressymb} = $parts;
if (ref($analysis) eq 'HASH') {
if (ref($analysis->{'parts_withrandomlist'}) eq 'ARRAY') {
@@ -7812,7 +7906,8 @@ sub graders_resources_pass {
}
sub grade_student_bubbles {
- my ($r,$uname,$udom,$scan_record,$scancode,$resources,$parts) = @_;
+ my ($r,$uname,$udom,$scan_record,$scancode,$resources,$parts,$bubbles_per_row) = @_;
+# Walk folder as student here to get resources in order student sees.
if (ref($resources) eq 'ARRAY') {
my $count = 0;
foreach my $resource (@{$resources}) {
@@ -7825,6 +7920,9 @@ sub grade_student_bubbles {
'grade_symb' => $ressymb,
'CODE' => $scancode
);
+ if ($bubbles_per_row ne '') {
+ $form{'bubbles_per_row'} = $bubbles_per_row;
+ }
if (ref($parts) eq 'HASH') {
if (ref($parts->{$ressymb}) eq 'ARRAY') {
foreach my $part (@{$parts->{$ressymb}}) {
@@ -7884,7 +7982,7 @@ sub scantron_upload_scantron_data {
'));
$r->print('
-'.&mt('Send scanned bubblesheet data to a course').'
+'.&mt('Send bubblesheet data to a course').'