--- loncom/homework/bridgetask.pm	2007/04/07 00:12:43	1.231
+++ loncom/homework/bridgetask.pm	2012/12/18 16:57:23	1.261
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA 
 # definition of tags that give a structure to a document
 #
-# $Id: bridgetask.pm,v 1.231 2007/04/07 00:12:43 albertel Exp $
+# $Id: bridgetask.pm,v 1.261 2012/12/18 16:57:23 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -37,6 +37,7 @@ use Apache::lonmenu;
 use Apache::lonlocal;
 use Apache::lonxml;
 use Apache::slotrequest();
+use Apache::structuretags();
 use Time::HiRes qw( gettimeofday tv_interval );
 use LONCAPA;
  
@@ -82,7 +83,10 @@ sub proctor_check_auth {
 		}
 	    }
 	    if ($authenticated) {
-		&check_in($type,$user,$domain,$slot_name);
+		my $check = &check_in($type,$user,$domain,$slot_name);
+                if ($check =~ /^error:/) {
+                    return 0;
+                }
 		return 1;
 	    }
 	}
@@ -94,7 +98,10 @@ sub check_in {
     my ($type,$user,$domain,$slot_name) = @_;
     my $useslots = &Apache::lonnet::EXT("resource.0.useslots");
     if ( $useslots eq 'map_map') {
-	&check_in_sequence($user,$domain,$slot_name);
+	my $result = &check_in_sequence($user,$domain,$slot_name);
+        if ($result =~ /^error: /) {
+            return $result;
+        }
     } else {
 	&create_new_version($type,$user,$domain,$slot_name);
 	&Apache::structuretags::finalize_storage();
@@ -105,6 +112,9 @@ sub check_in {
 sub check_in_sequence {
     my ($user,$domain,$slot_name) = @_;
     my $navmap = Apache::lonnavmaps::navmap->new();
+    if (!defined($navmap)) {
+        return 'error: ';
+    }
     my ($symb) = &Apache::lonnet::whichuser();
     my ($map)  = &Apache::lonnet::decode_symb($symb);
     my @resources = 
@@ -189,6 +199,10 @@ sub get_version {
 
 sub add_previous_version_button {
     my ($status)=@_;
+    my (undef,undef,$udom,$uname)=&Apache::lonnet::whichuser();
+    if (($uname ne $env{'user.name'}) || ($udom ne $env{'user.domain'})) {
+        return;
+    }
     my $result;
     if ($Apache::lonhomework::history{'resource.0.version'} eq '') {
 	return '';
@@ -225,7 +239,10 @@ sub add_previous_version_button {
 }
 
 sub add_grading_button {
-    my (undef,$cid)=&Apache::lonnet::whichuser();
+    my (undef,$cid,$udom,$uname)=&Apache::lonnet::whichuser();
+    if (($uname ne $env{'user.name'}) || ($udom ne $env{'user.domain'})) {
+        return;
+    }
     my $cnum=$env{'course.'.$cid.'.num'};
     my $cdom=$env{'course.'.$cid.'.domain'};
     my %sections = &Apache::loncommon::get_sections($cdom,$cnum);
@@ -240,15 +257,28 @@ sub add_grading_button {
 	$sec_select .= "\t<option value=\"$sec\">$sec</option>\n";
     }
     $sec_select .= "\t<option value='none'>none</option>\n</select>\n";
-    
-    my $result="\n\t".'<input type="submit" name="gradeasubmission" value="'.
-	&mt("Get a submission to grade").'" />';
-    $result.="\n\t".'<input type="hidden" name="grade_target" value="webgrade" />';
-    if (&Apache::lonnet::allowed('mgq',$env{'request.course.id'})) {
+
+    my $uri=$env{'request.uri'};
+    if ($env{'request.enc'}) { $uri=&Apache::lonenc::encrypted($uri); }
+    my $result = 
+        '<form name="gradesubmission" method="post" action="'.$uri.'">'.
+        "\n\t".'<input type="submit" name="gradeasubmission" value="'.
+	&mt("Get a submission to grade").'" />'.
+        "\n\t".'<input type="hidden" name="grade_target" value="webgrade" />';
+    my $see_all = &Apache::lonnet::allowed('mgq',$env{'request.course.id'});
+    my $see_sec = &Apache::lonnet::allowed('mgq',$env{'request.course.id'}.
+					   '/'.$env{'request.course.sec'});
+
+    if ($see_all || $see_sec) {
 	my ($entries,$ready,$locks)=&get_queue_counts('gradingqueue');
 	$result.="\n\t".'<table>'."\n\t\t".'<tr>';
-	$result.="\n\t\t\t".'<td rowspan="4">Specify a section: </td>'.
-	    "\n\t\t\t".'<td rowspan="4">'.$sec_select."\n\t\t\t".'</td>';
+	if ($see_all || (!&section_restricted())) {
+	    $result.="\n\t\t\t".'<td rowspan="4">'.&mt('Specify a section:').' </td>'.
+		"\n\t\t\t".'<td rowspan="4">'.$sec_select."\n\t\t\t".'</td>';
+	} else {
+	    $result.="\n\t\t\t".'<td rowspan="4">'.&mt('Grading section:').' </td>'.
+		"\n\t\t\t".'<td rowspan="4">'.$env{'request.course.sec'}."\n\t\t\t".'</td>';
+	}
 	$result.="\n\t\t\t".'<td>'.'<input type="submit" name="reviewagrading" value="'.
 	    &mt("Select an entry from the grading queue:").'" /> ';
 
@@ -280,12 +310,47 @@ sub add_grading_button {
 	$result.=&Apache::loncommon::studentbrowser_javascript();
 	$result.= '</p>'."\n";
     }
+    $result .= '</form>'."\n";
+    return $result;
+}
+
+sub add_slotlist_button {
+    my (undef,$cid,$udom,$uname)=&Apache::lonnet::whichuser();
+    if (($uname ne $env{'user.name'}) || ($udom ne $env{'user.domain'})) {
+        return;
+    }
+    my $symb=&Apache::lonnet::symbread();
+    my $result;
+    if (&Apache::lonnet::allowed('mgq',$env{'request.course.id'}) ||
+        &Apache::lonnet::allowed('mgq',$env{'request.course.id'}.'/'.$env{'request.course.sec'})) {
+        $result = '<form method="post" name="slotrequest" action="/adm/slotrequest">'.
+                  '<input type="hidden" name="symb" value="'.$symb.'" />'.
+                  '<input type="hidden" name="command" value="showslots" />'.
+                  '<input type="submit" name="requestattempt" value="'.
+                  &mt('Show Slot list').'" />'.
+                  '</form>';
+        my $target_id =
+               &Apache::lonstathelpers::make_target_id({symb => $symb,
+                                                             part => '0'});
+        if (!&section_restricted()) {
+            $result.='<form method="post" name="gradingstatus" action="/adm/statistics">'.
+                     '<input type="hidden" name="problemchoice" value="'.$target_id.'" />'.
+                     '<input type="hidden" name="reportSelected" value="grading_analysis" />'.
+                     '<input type="submit" name="grading" value="'.
+                     &mt('Show Grading Status').'" />'.
+                     '</form>';
+        }
+    }
     return $result;
 }
 
 sub add_request_another_attempt_button {
     my ($text)=@_;
-    if (!$text) { $text="Request another attempt"; }
+    my (undef,$cid,$udom,$uname)=&Apache::lonnet::whichuser();
+    if (($uname ne $env{'user.name'}) || ($udom ne $env{'user.domain'})) {
+        return;
+    }
+    if (!$text) { $text=&mt('Request another attempt'); }
     my $result;
     my $symb=&Apache::lonnet::symbread();
     # not a slot access based resource
@@ -297,13 +362,14 @@ sub add_request_another_attempt_button {
     my ($slot_name,$slot)=&Apache::slotrequest::check_for_reservation($symb);
     my $action='get_reservation';
     if ($slot_name) {
-	$text="Change reservation.";
+	$text=&mt('Change reservation');
 	$action='change_reservation';
 	my $description=&Apache::slotrequest::get_description($slot_name,
 							      $slot);
-	$result.=(<<STUFF);
-    <p> Will be next available: $description </p>
-STUFF
+	$result.='<p>'
+                .&mt('Will be next available:')
+                .' '.$description
+                .'</p>';
     }
     
     if ($env{'request.enc'}) { $symb=&Apache::lonenc::encrypted($symb); }
@@ -313,7 +379,7 @@ STUFF
 	'<input type="hidden" name="symb" value="'.$symb.'" />'."\n\t\t".
 	'<input type="hidden" name="command" value="'.$action.'" />'."\n\t\t".
 	'<input type="submit" name="requestattempt" value="'.
-	&mt($text).'" />'."\n\t".
+	$text.'" />'."\n\t".
 	'</form>'."\n";
     return $result;
 }
@@ -361,6 +427,7 @@ sub show_task {
 		       ( $status eq 'BANNED') ||
 		       ( $status eq 'UNAVAILABLE') ||
 		       ( $status eq 'NOT_IN_A_SLOT') ||
+                       ( $status eq 'NOT_YET_VIEWED') ||
 		       ( $status eq 'NEEDS_CHECKIN') ||
 		       ( $status eq 'WAITING_FOR_GRADE') ||
 		       ( $status eq 'INVALID_ACCESS') ||
@@ -463,7 +530,7 @@ sub file_list {
 	my $file=$file_url.$partial_file;
 	$file=~s|/+|/|g;
 	&Apache::lonnet::allowuploaded('/adm/bridgetask',$file);
-	$file_list.='<li><span style="white-space: nowrap;"><a href="'.$file.'?rawmode=1" target="lonGRDs"><img src="'.
+	$file_list.='<li><span class="LC_nobreak"><a href="'.$file.'?rawmode=1" target="lonGRDs"><img src="'.
 	    &Apache::loncommon::icon($file).'" alt="file icon" border="0" /> '.$file.
 	    '</a></span></li>'."\n";
     }
@@ -483,13 +550,13 @@ sub webgrade_standard_info {
 
     my $file_list = &file_list($Apache::lonhomework::history{"resource.$version.0.bridgetask.portfiles"});
 
-    my %lt=('done'   => 'Next Item',
-	    'stop'   => 'Quit Grading',
-	    'fail'   => 'Fail Rest',
-	    'cancel' => 'Cancel',
-	    'submit' => 'Submit Grades',
-	    );
-    %lt=&Apache::lonlocal::texthash(%lt);
+    my %lt = &Apache::lonlocal::texthash(
+        'done'   => 'Next Item',
+        'stop'   => 'Quit Grading',
+        'fail'   => 'Fail Rest',
+        'cancel' => 'Cancel',
+        'submit' => 'Submit Grades',
+    );
 
     my $result=<<INFO;
   <div class="LC_GRADING_maincontrols">
@@ -526,22 +593,36 @@ sub done_screen {
     my $title=&Apache::lonnet::gettitle($env{'request.uri'});
     my @files=split(',',$Apache::lonhomework::history{'resource.'.$version.'.0.bridgetask.portfiles'});
     my (undef,undef,$domain,$user)= &Apache::lonnet::whichuser();
-    my $files = '<ul>';
-    my $msg;
-    foreach my $file (@files) {
-	my $url="/uploaded/$domain/$user/portfolio$file";
-	if (! &Apache::lonnet::stat_file($url)) {
-	    $file = &mt('<span class="LC_error"> Nonexistent file:</span> '.
-			'<span class="LC_filename">[_1]</span>',$file);
-	    $msg .= "<p>Submitted non-existant file $file</p>\n";
-	} else {
-	    $file = '<span class="LC_filename">'.$file.'</span>';
-	    $msg .= "<p>Submitted file $file</p>\n";
-	}
-	$files .= '<li>'.$file.'</li>';
+    my ($msg,$files,$shown);
+    if (@files > 0) {
+        $files = '<ul>';
+        foreach my $file (@files) {
+	    my $url="/uploaded/$domain/$user/portfolio$file";
+	    if (! &Apache::lonnet::stat_file($url)) {
+	        $file = '<span class="LC_error">'
+                       .&mt('[_1]Nonexistent file:[_2]'
+                           ,'<span class="LC_error"> '
+                           ,'</span> <span class="LC_filename">'.$file.'</span>');
+	        $msg .= "<p>".&mt('Submitted non-existent file [_1]',$file)."</p>\n";
+	    } else {
+	        $file = '<span class="LC_filename">'.$file.'</span>';
+	        $msg .= "<p>".&mt('Submitted file [_1]',$file)."</p>\n";
+	    }
+	    $files .= '<li>'.$file.'</li>';
+        }
+        $files.='</ul>';
+        $shown = '<p>'.&mt('Files submitted: [_1]',$files).'</p>'
+                .'<p>'.&mt('You are now done with this Bridge Task').'</p>'
+                .'<hr />'
+                .'<p><a href="/adm/logout">'.&mt('Logout').'</a></p>'
+                .'<p><a href="/adm/roles">'.&mt('Change to a different course').'</a></p>';
+    } else {
+        $msg = &mt("Submission status: no files currently submitted, when 'Done' was indicated.");
+        $shown = '<p class="LC_error">'.
+                 &mt('You did not submit any files.  Please try again.').'</span>'.
+                 '</p><p><a href="javascript:history.go(-1);">'.&mt('Back to Bridge Task').'</a></p><hr />';
     }
-    $files.='</ul>';
-    my $subject = "Submission message for $title";
+    my $subject = &mt('Submission message for [_1]',$title);
     my ($message_status,$comment_status);
     my $setting = $env{'course.'.$env{'request.course.id'}.'.task_messages'};
     $setting =~ s/^\s*(\S*)\s*$/$1/;
@@ -560,17 +641,11 @@ sub done_screen {
 	$comment_status = '<p>'.&mt('Message sent to instructor: [_1]',
 				    $comment_status).' </p>';
     }
-    return <<DONESCREEN;
-<h2>$title</h2>
-<p> Files submitted: $files </p>
-<p> You are now done with this Bridge Task </p>
-<hr />
-<p> <a href="/adm/logout">Logout</a> </p>
-<p> <a href="/adm/roles">Change to a different course</a> </p>
-$message_status
-$comment_status
-DONESCREEN
-
+ 
+    return "<h2>$title</h2>"
+          .$shown
+          .$message_status
+          .$comment_status;
 }
 
 sub start_Task {
@@ -600,32 +675,24 @@ sub start_Task {
 	    &Apache::structuretags::page_start($target,$token,$tagstack,
 					       $parstack,$parser,$safeeval,
 					       $name,&style($target));
+
+    }
+    if ($target eq 'web' || $target eq 'grade' || $target eq 'answer' ||
+        $target eq 'tex') {
+        if ($env{'form.markaccess'}) {
+            my @interval=&Apache::lonnet::EXT("resource.0.interval");
+            &Apache::lonnet::set_first_access($interval[1]);
+        }
     }
 
     if ($target eq 'web' && $env{'request.state'} ne 'construct') {
 	if ($Apache::lonhomework::queuegrade
 	    || $Apache::lonhomework::modifygrades) {
-	    $result.='<form name="gradesubmission" method="post" action="';
-	    my $uri=$env{'request.uri'};
-	    if ($env{'request.enc'}) { $uri=&Apache::lonenc::encrypted($uri); }
-	    $result.=$uri.'">'.&add_grading_button()."</form>\n";
+	    $result .= &add_grading_button();
 	    my $symb=&Apache::lonnet::symbread();
-	    if (&Apache::lonnet::allowed('mgq',$env{'request.course.id'})) {
-		$result.='<form method="post" name="slotrequest" action="/adm/slotrequest">'.
-		    '<input type="hidden" name="symb" value="'.$symb.'" />'.
-		    '<input type="hidden" name="command" value="showslots" />'.
-		    '<input type="submit" name="requestattempt" value="'.
-		    &mt('Show Slot list').'" />'.
-		    '</form>';
-		my $target_id = 
-		    &Apache::lonstathelpers::make_target_id({symb => $symb,
-							     part => '0'});
-		$result.='<form method="post" name="gradingstatus" action="/adm/statistics">'.
-		    '<input type="hidden" name="problemchoice" value="'.$target_id.'" />'.
-		    '<input type="hidden" name="reportSelected" value="grading_analysis" />'.
-		    '<input type="submit" name="grading" value="'.
-		    &mt('Show Grading Status').'" />'.
-		    '</form>';
+	    if (&Apache::lonnet::allowed('mgq',$env{'request.course.id'})
+		|| &Apache::lonnet::allowed('mgq',$env{'request.course.id'}.'/'.$env{'request.course.sec'})) {
+                $result .= &add_slotlist_button(); 
 	    }
 	}
     }
@@ -639,19 +706,34 @@ sub start_Task {
 	my ($version,$previous)=&get_version();
 	($status,$accessmsg,my $slot_name,$slot) = 
 	    &Apache::lonhomework::check_slot_access('0','Task');
-	if ($status eq 'CAN_ANSWER' && $version eq '') {
-	    # CAN_ANSWER mode, and no current version, unproctored access
+	if ((($status eq 'CAN_ANSWER') || ($status eq 'NOT_YET_VIEWED')) && ($version eq '')) {
+	    # CAN_ANSWER or NOT_YET_VIEWED mode, and no current version, unproctored access
 	    # thus self-checkedin
-	    &check_in('Task',undef,undef,$slot_name);
+	    my $check = &check_in('Task',undef,undef,$slot_name);
+            if ($check =~ /^error: /) {
+                my $symb=&Apache::lonnet::symbread();
+                &Apache::lonnet::logthis("Error during self-checkin of version $version of Task (symb: $symb) using slot: $slot_name");   
+            }
 	    &add_to_queue('gradingqueue',{'type' => 'Task',
 					  'time' => time,
 					  'slot' => $slot_name});
 	    ($version,$previous)=&get_version();
 	}
-	
-	my $status_id = 
-	    ($previous || $status eq 'SHOW_ANSWER') ? 'LC_task_feedback'
-	                                            : 'LC_task_take';
+        if (($target eq 'web') && ($version ne '') && ($slot_name ne '')) {
+            if (ref($slot) eq 'HASH') {
+                if ($slot->{'endtime'} > time()) {
+                    $result .=
+                        &Apache::lonhtmlcommon::set_due_date($slot->{'endtime'});
+                }
+            }
+	}
+
+	my $status_id = 'LC_task_take';
+        if ($previous && $target eq 'answer') {
+            $status_id = 'LC_task_answer';
+        } elsif ($previous || $status eq 'SHOW_ANSWER') {
+	    $status_id = 'LC_task_feedback';
+        }
 	$result .= '<div class="LC_task" id="'.$status_id.'">'."\n";
 
 	push(@Apache::inputtags::status,$status);
@@ -669,26 +751,29 @@ sub start_Task {
 		}
 		my $msg;
 		if ($status eq 'UNAVAILABLE') {
-		    $msg.='<h1>'.&mt('Unable to determine if this resource is open due to network problems. Please try again later.').'</h1>';
+		    $msg.='<p class="LC_error">'.&mt('Unable to determine if this resource is open due to network problems. Please try again later.').'</p>';
 		} elsif ($status eq 'NOT_IN_A_SLOT') {
-		    $msg.='<h1>'.&mt('You are not currently signed up to work at this time and/or place.').'</h1>';
-		    $msg.=&add_request_another_attempt_button("Sign up for time to work.");
+		    $msg.='<p class="LC_warning">'.&mt('You are not currently signed up to work at this time and/or place.').'</p>';
+		    $msg.=&add_request_another_attempt_button("Sign up for time to work");
 		} elsif ($status eq 'NEEDS_CHECKIN') {
-		    $msg.='<h1>'.&mt('You need the Proctor to validate you.').
-			'</h1>'.&proctor_validation_screen($slot);
+		    $msg.='<p class="LC_warning">'.&mt('You need the Proctor to validate you.').
+			'</p>'.&proctor_validation_screen($slot);
 		} elsif ($status eq 'WAITING_FOR_GRADE') {
-		    $msg.='<h1>'.&mt('Your submission is in the grading queue.').'</h1>';
+		    $msg.='<p class="LC_info">'.&mt('Your submission is in the grading queue.').'</p>';
 		} elsif ($env{'form.donescreen'}) {
 		    $result .= &done_screen($version);
-		} elsif ($status ne 'NOT_YET_VIEWED') {
-		    $msg.='<h1>'.&mt('Not open to be viewed').'</h1>';
+		} elsif ($status eq 'NOT_YET_VIEWED') {
+                    my $symb=&Apache::lonnet::symbread();
+                    $msg.=&Apache::structuretags::firstaccess_msg($accessmsg,$symb);
+		} else {
+		    $msg.='<p class="LC_warning">'.&mt('Not open to be viewed').'</p>';
 		}
 		if ($status eq 'CLOSED' || $status eq 'INVALID_ACCESS') {
 		    $msg.='The problem '.$accessmsg;
 		}
 		$result.=$msg.'<br />';
 	    } elsif ($target eq 'tex') {
-		$result.='\begin{document}\noindent \vskip 1 mm  \begin{minipage}{\textwidth}\vskip 0 mm';
+		$result.='\noindent \vskip 1 mm  \begin{minipage}{\textwidth}\vskip 0 mm';
 		if ($status eq 'UNAVAILABLE') {
 		    $result.=&mt('Unable to determine if this resource is open due to network problems. Please try again later.').'\vskip 0 mm ';
 		} else {
@@ -758,6 +843,11 @@ sub start_Task {
 		    $result.='<b>'.&mt("Stopped grading.").'</b>'.$back;
 		} elsif ($status_code eq 'cancel') {
 		    $result.='<b>'.&mt("Cancelled grading.").'</b>'.$back;
+                } elsif ($status_code eq 'terminated') {
+                    $result.= '<b>'.&mt('Terminated grading').'</b><br />'.
+                              '<span class="LC_error">'.
+                              &mt('Grading for [_1] has not been saved because of a grading key mismatch.',
+                              '<tt>'.$env{'form.terminated'}.'</tt>').'</span><br />'.$back;
 		} elsif ($status_code eq 'never_versioned') {
 		    $result.='<b>'.
 			&mt("Requested user has never accessed the task.").
@@ -804,9 +894,8 @@ sub start_Task {
 		$result.='<input type="hidden" name="regrade" value="'.
 		    $env{'form.regrade'}.'" />';
 	    }
-	    if ($env{'form.chosensections'}) {
-		my @chosen_sections=
-		    &Apache::loncommon::get_env_multiple('form.chosensections');
+	    if ($env{'form.chosensections'} || &section_restricted()) {
+		my @chosen_sections = &get_allowed_sections();
 		foreach my $sec (@chosen_sections) {
 		    $result.='<input type="hidden" name="chosensections" 
                                value="'.$sec.'" />';
@@ -902,7 +991,14 @@ sub get_key_todo {
 	my $cdom  = $env{'course.'.$cid.'.domain'};
 	my $uname = &LONCAPA::clean_username($env{'form.gradinguser'});
 	my $udom  = &LONCAPA::clean_domain($env{'form.gradingdomain'});
-
+	
+	if (&section_restricted()) {
+	    my $classlist=&get_limited_classlist();
+	    if (!&allow_grade_user($classlist->{$uname.':'.$udom})) {
+		return (undef,'not_allowed',
+			&mt("Requested student ([_1]) is in a section you aren't allowed to grade.",$uname.':'.$udom));
+	    }
+	}
 	my $gradingkey=&encode_queue_key($symb,$udom,$uname);
 
 	my $queue;
@@ -972,6 +1068,8 @@ sub get_key_todo {
 		    return (undef,'stop');
 		} elsif ($env{'form.cancel'}) {
 		    return (undef,'cancel');
+                } elsif ($env{'form.terminated'}) {
+                    return (undef, 'terminated');
 		} elsif ($env{'form.next'}) {
 		    return (undef,'select_user');
 		}
@@ -1017,13 +1115,17 @@ sub get_key_todo {
 
     if ($env{'form.queuemode'} ne 'selected') {
 	# don't get something new from the queue if they hit the stop button
-    	if (!(($env{'form.cancel'} || $env{'form.stop'}) 
+    	if (!(($env{'form.cancel'} || $env{'form.stop'} || $env{'form.terminated'}) 
 	      && $target eq 'webgrade') 
 	    && !$env{'form.gradingaction'}) {
 	    &Apache::lonxml::debug("Getting anew $queue");
 	    return (&get_from_queue($queue));
 	} else {
-	    return (undef,'stop');
+            if ($env{'form.terminated'}) {
+                return (undef,'terminated');
+            } else {
+                return (undef,'stop');
+            }
 	}
     }
     return (undef,undef)
@@ -1053,18 +1155,25 @@ sub end_Task {
 		}
 		if ($status eq 'CAN_ANSWER' && !$previous && 
 		    !$env{'form.donescreen'}) {
-		    $result.="\n".'<table border="1">'.
+                    my ($portheader,$porttext);
+                    if ($Apache::lonhomework::history{"resource.$version.0.bridgetask.portfiles"}) {
+                        $portheader = &mt('Submit Additional Portfolio Files for Grading');
+                        $porttext = &mt('Indicate which additional files from your portfolio are to be evaluated in grading this task.');
+                    } else {
+                        $portheader = &mt('Submit Portfolio Files for Grading');
+                        $porttext = &mt('Indicate the files from your portfolio to be evaluated in grading this task.');
+                    }
+		    $result.="\n".'<div>'.&Apache::lonhtmlcommon::start_pick_box().
 			&Apache::inputtags::file_selector("$version.0",
 							  "bridgetask","*",
 							  'portfolioonly',
-							  '
-<h2>'.&mt('Submit Portfolio Files for Grading').'</h2>
-<p>'.&mt('Indicate the files from your portfolio to be evaluated in grading this task.').'</p>').
-							  "</table>";
+                                                          '<h3>'.$portheader.'</h3><br />'.
+                                                          $porttext.'<br />').
+			&Apache::lonhtmlcommon::end_pick_box().'</div>';
 		}
 		if (!$previous && $status ne 'SHOW_ANSWER' &&
 		    &show_task($status,$previous)) {
-		    $result.=&Apache::inputtags::gradestatus('0');
+		    $result.=&Apache::inputtags::gradestatus('0',$target,1);
 		}
 		
 		$result.='</form>';
@@ -1072,10 +1181,11 @@ sub end_Task {
 		if (!$previous && $status ne 'SHOW_ANSWER' &&
 		    &show_task($status,$previous)) {
 		    my $action = &Apache::lonenc::check_encrypt($env{'request.uri'});
+                    my $donetext = &mt('Done');
 		    $result.=<<DONEBUTTON;
 <form name="done" method="post" action="$action">
    <input type="hidden" name="donescreen" value="1" />
-   <input type="submit" value="Done" />
+   <input type="submit" value="$donetext" />
 </form>
 DONEBUTTON
                 }
@@ -1108,13 +1218,15 @@ DONEBUTTON
 			"</p>\n";
 
 		    if ($bt_status eq 'pass')  {
-			$status.='<h2>You passed the '.$title.' given on '.
-			    $start_time.'</h2>';
+			$status.='<h2>'
+                                .&mt('You passed the [_1] given on [_2].',$title,$start_time)
+                                .'</h2>';
 			$status.=$question_status;
 		    }
 		    if ($bt_status eq 'fail')  {
-			$status.='<h2>You did not pass the '.$title.' given on '.
-			    $start_time.'</h2>';
+			$status.='<h2>'
+                                .&mt('You did not pass the [_1] given on [_2].',$title,$start_time)
+                                .'</h2>';
 			$status.=$question_status;
 			if (!$previous) {
 			    $status.=&add_request_another_attempt_button();
@@ -1140,7 +1252,9 @@ DONEBUTTON
 		}
 		$result.="\n</div>\n".
 		    &Apache::loncommon::end_page({'discussion' => 1});
-	    }
+	    } elsif ($target eq 'answer') {
+                $result.="\n</div>\n";
+            }
 	}
 
 	my $useslots = &Apache::lonnet::EXT("resource.0.useslots");
@@ -1151,13 +1265,16 @@ DONEBUTTON
 	} elsif (defined($Apache::lonhomework::history{"resource.$version.0.checkedin.slot"})) {
 	    $queue_data{'slot'} = $Apache::lonhomework::history{"resource.$version.0.checkedin.slot"};
 	}
-	
+
 
 	if ($target eq 'grade' && !$env{'form.webgrade'} && !$previous
 	    && $status eq 'CAN_ANSWER') {
 	    my $award='SUBMITTED';
+            my $uploadedflag=0;
+            my $totalsize=0;
+            my @deletions = &Apache::loncommon::get_env_multiple('form.HWFILE'.$version.'_0_bridgetask_delete');
 	    &Apache::essayresponse::file_submission("$version.0",'bridgetask',
-						    'portfiles',\$award);
+						    \$award,\$uploadedflag,\$totalsize,\@deletions);
 	    if ($award eq 'SUBMITTED' &&
 		$Apache::lonhomework::results{"resource.$version.0.bridgetask.portfiles"}) {
 		$Apache::lonhomework::results{"resource.0.tries"}=
@@ -1170,7 +1287,9 @@ DONEBUTTON
 		$Apache::lonhomework::results{"resource.0.submission"}=
 		    $Apache::lonhomework::results{"resource.$version.0.submission"}='';
 	    } else {
-		delete($Apache::lonhomework::results{"resource.$version.0.bridgetask.portfiles"});
+                unless($uploadedflag) {
+                    delete($Apache::lonhomework::results{"resource.$version.0.bridgetask.portfiles"});
+                }
 		$award = '';
 	    }
 	    &Apache::lonhomework::showhash(%Apache::lonhomework::results);
@@ -1273,38 +1392,64 @@ DONEBUTTON
 		    $Apache::lonhomework::results{"resource.$version.0.solved"};
 	    }
 	    &minimize_storage();
-	    &Apache::structuretags::finalize_storage();
-	    
-	    # data stored, now handle queue
-	    if ($review) {
-		if ($env{'form.queue'} eq 'reviewqueue') {
-		    &check_queue_unlock($env{'form.queue'});
-		    &Apache::lonxml::debug(" still needs review not changing status.");
-		} else {
-		    if ($env{'form.queue'} ne 'none') {
-			&move_between_queues($env{'form.queue'},'reviewqueue');
+            my ($canstore,$domain,$name,$symb,$courseid);
+            ($symb,$courseid,$domain,$name) = &Apache::lonnet::whichuser();
+
+            if ($env{'form.gradingkey'}) {
+                my $todo=&unescape($env{'form.gradingkey'});
+                my ($keysymb,$uname,$udom)=&decode_queue_key($todo);
+                if ($symb eq $keysymb) {
+                    if (($domain eq $udom) && ($name eq $uname)) {
+                        $canstore = 1;           
+                    }
+                }
+            }
+            if ($canstore) {
+	        &Apache::structuretags::finalize_storage();
+                my @interval = &Apache::lonnet::EXT("resource.0.interval");
+                if ($interval[0] =~ /^\d+$/ && $interval[1] eq 'resource') {
+                    my $key=$courseid."\0".$symb;
+                    my %times=&Apache::lonnet::get('firstaccesstimes',
+                                                   [$key],$domain,$name);
+                    if ($times{$key}) {
+                        my $delresult.=&Apache::lonnet::del('firstaccesstimes',
+                                                            [$key],$domain,$name);
+                    }
+                }
+	        # data stored, now handle queue
+	        if ($review) {
+		    if ($env{'form.queue'} eq 'reviewqueue') {
+		        &check_queue_unlock($env{'form.queue'});
+		        &Apache::lonxml::debug(" still needs review not changing status.");
 		    } else {
-			&add_to_queue('reviewqueue',\%queue_data);
+		        if ($env{'form.queue'} ne 'none') {
+			    &move_between_queues($env{'form.queue'},'reviewqueue');
+		        } else {
+			    &add_to_queue('reviewqueue',\%queue_data);
+		        }
 		    }
-		}
-	    } elsif ($ungraded) {
-		if ($env{'form.queue'} eq 'reviewqueue') {
-		    &Apache::lonxml::debug("moving back.");
-		    &move_between_queues($env{'form.queue'},
-					 'gradingqueue');
-		} elsif ($env{'form.queue'} eq 'none' ) {
-		    &add_to_queue('gradingqueue',\%queue_data);	
-		} else {
-		    &check_queue_unlock($env{'form.queue'});
-		}
-	    } elsif ($mandatory_failed) {
-		&remove_from_queue($env{'form.queue'}); 
-	    } else {
-		&remove_from_queue($env{'form.queue'});
-	    }
-	}
+	        } elsif ($ungraded) {
+		    if ($env{'form.queue'} eq 'reviewqueue') {
+		        &Apache::lonxml::debug("moving back.");
+		        &move_between_queues($env{'form.queue'},
+					     'gradingqueue');
+		    } elsif ($env{'form.queue'} eq 'none' ) {
+		        &add_to_queue('gradingqueue',\%queue_data);	
+		    } else {
+		        &check_queue_unlock($env{'form.queue'});
+		    }
+	        } elsif ($mandatory_failed) {
+		    &remove_from_queue($env{'form.queue'}); 
+	        } else {
+		    &remove_from_queue($env{'form.queue'});
+	        }
+            } else {
+                &check_queue_unlock($env{'form.queue'});
+                $env{'form.terminated'} = $name.':'.$domain;
+            }
+        }
 	if (exists($Apache::lonhomework::results{'INTERNAL_store'})) {
-	    # instance generation occured and hasn't yet been stored
+	    # instance generation occurred and hasn't yet been stored
 	    &Apache::structuretags::finalize_storage();
 	}
     } elsif ($target eq 'webgrade') {
@@ -1360,6 +1505,13 @@ DONEBUTTON
     }
     &Apache::structuretags::reset_problem_globals('Task');
     undef($Apache::lonhomework::parsing_a_task);
+    if ( ($target eq 'grade' && $env{'form.webgrade'}) ||
+          $target eq 'webgrade') {
+        delete($env{'form.grade_symb'});
+        delete($env{'form.grade_domain'});
+        delete($env{'form.grade_username'});
+        delete($env{'form.grade_courseid'});
+    }
     return $result;
 }
 
@@ -1518,11 +1670,11 @@ sub get_limited_classlist {
        	}
     }
 
-    if (ref($sections) && !grep('all',@{ $sections })) {
+    if (ref($sections) && !grep {$_ eq 'all'} (@{ $sections })) {
 	foreach my $student (keys(%$classlist)) {
 	    my $section  = 
 		$classlist->{$student}[&Apache::loncoursedata::CL_SECTION()];
-	    if (! grep($section,@{ $sections })) {
+	    if (! grep {$_ eq $section} (@{ $sections })) {
 		delete($classlist->{$student});
 	    }
 	}
@@ -1538,14 +1690,15 @@ sub show_queue {
     my $cnum=$env{'course.'.$cid.'.num'};
     my $cdom=$env{'course.'.$cid.'.domain'};
 
-    my @chosen_sections=
-	&Apache::loncommon::get_env_multiple('form.chosensections');
+    my @chosen_sections = &get_allowed_sections();
 
     my $classlist = &get_limited_classlist(\@chosen_sections);
 
     if (!(grep(/^all$/,@chosen_sections))) {
-	$result.='<p> Showing only sections <tt>'.join(', ',@chosen_sections).
-	    '</tt>.</p> '."\n";
+	$result.='<p>'
+                .&mt('Showing only sections [_1].'
+                    ,'<tt>'.join(', ',@chosen_sections).'</tt>')
+                ."</p>\n";
     }
 
     my ($view,$view_section);
@@ -1559,27 +1712,33 @@ sub show_queue {
 	}
     }
 
+    $result .= 
+	'<p><a href="/adm/flip?postdata=return:">'.
+	&mt('Return to resource').'</a></p><hr />'.
+	"\n<h3>".&mt('Current Queue - [_1]',$queue)."</h3>";
     my $regexp="^$symb\0";
     my %queue=&Apache::lonnet::dump($queue,$cdom,$cnum,$regexp);
     my ($tmp)=%queue;
     if ($tmp=~/^error: 2 /) {
-	return "\n<h3>Current Queue - $queue</h3>".
+	$result.=
 	    &Apache::loncommon::start_data_table().
 	    &Apache::loncommon::start_data_table_row().
 	    '<td>'.&mt('Empty').'</td>'.
 	    &Apache::loncommon::end_data_table_row().
 	    &Apache::loncommon::end_data_table();
+	return $result;
     }
     my $title=&Apache::lonnet::gettitle($symb);
-    $result.="\n<h3>Current Queue - $title $queue </h3>".
+    $result.=
 	&Apache::loncommon::start_data_table().
 	&Apache::loncommon::start_data_table_header_row();
-    if ($with_selects) { $result.="<th>Status</th><th></th>"; }
-    $result.="<th>user</th><th>data</th>".
+    if ($with_selects) { $result.='<th>'.&mt('Status').'</th><th></th>'; }
+    $result.='<th>'.&mt('User').'</th><th>'.&mt('Data').'</th>'.
 	&Apache::loncommon::end_data_table_header_row();
     foreach my $key (sort(keys(%queue))) {
 	my ($symb,$uname,$udom) = &decode_queue_key($key);
-	if (!defined($classlist->{$uname.':'.$udom})) { next; }
+	next if (!defined($classlist->{$uname.':'.$udom}));
+	next if (!&allow_grade_user($classlist->{$uname.':'.$udom}));
 	
 	my $section = $classlist->{$uname.':'.$udom}[&Apache::loncoursedata::CL_SECTION()];
 
@@ -1621,7 +1780,7 @@ sub show_queue {
 								   'start');
 		    }
 		    my $me=$env{'user.name'}.':'.$env{'user.domain'};
-		    $status=&mt('Locked by <tt>[_1]</tt> [_2]',$locker,$time);
+		    $status=&mt('Locked by [_1] [_2]','<tt>'.$locker.'</tt>',$time);
 		    if ($me eq $locker) {
 			($action,$description)=('resume',&mt('Resume'));
 		    } else {
@@ -1656,15 +1815,46 @@ FORM
 	    }
 	    $result.= "<td>".$classlist->{$uname.':'.$udom}[&Apache::loncoursedata::CL_FULLNAME()].
 		" <tt>($uname:$udom)</tt> </td>";
-	    $result.='<td>'.$slot_text.' End time: '.
-		&Apache::lonlocal::locallocaltime($end_time).
-		"</td>".&Apache::loncommon::end_data_table_row();
+            $result.='<td>'.$slot_text.' '
+                    .&mt('End time: [_1]'
+                        ,&Apache::lonlocal::locallocaltime($end_time))
+                    .'</td>'
+                    .&Apache::loncommon::end_data_table_row();
 	}
     }
     $result.= &Apache::loncommon::end_data_table()."<hr />\n";
     return $result;
 }
 
+sub get_allowed_sections {
+    my @chosen_sections;
+    if (&section_restricted()) {
+	@chosen_sections = ($env{'request.course.sec'});
+    } else {
+	@chosen_sections =
+	    &Apache::loncommon::get_env_multiple('form.chosensections');
+    }
+
+    return @chosen_sections;
+}
+
+sub section_restricted {
+    my $cid =(&Apache::lonnet::whichuser())[1];
+    return (lc($env{'course.'.$cid.'.task_grading'}) eq 'section'
+	    && $env{'request.course.sec'} ne '' );
+}
+
+sub allow_grade_user {
+    my ($classlist_entry) = @_;
+
+    if (&section_restricted()
+	&& $env{'request.course.sec'} ne
+	      $classlist_entry->[&Apache::loncoursedata::CL_SECTION()]) {
+	return 0;
+    }
+    return 1;
+}
+
 sub get_queue_counts {
     my ($queue)=@_;
     my $result;
@@ -1680,11 +1870,14 @@ sub get_queue_counts {
     if ($tmp=~/^error: 2 /) {
 	return (0,0,0);
     }
+
     my ($entries,$ready_to_grade,$locks)=(0,0,0);
     my %slot_cache;
     foreach my $key (sort(keys(%queue))) {
 	my ($symb,$uname,$udom) = &decode_queue_key($key);
-	if (!defined($classlist->{$uname.':'.$udom})) { next; }
+	next if (!defined($classlist->{$uname.':'.$udom}));
+	next if (!&allow_grade_user($classlist->{$uname.':'.$udom}));
+
 	if ($key=~/locked$/) {
 	    $locks++;
 	} elsif ($key=~/timestamp$/) {
@@ -1761,7 +1954,8 @@ sub pick_from_queue_data {
 	if ($key =~ /\0timestamp$/) { next; }
 
 	my ($symb,$uname,$udom)=&decode_queue_key($key);
-	if (!defined($classlist->{$uname.':'.$udom})) { next; }
+	next if (!defined($classlist->{$uname.':'.$udom}));
+	next if (!&allow_grade_user($classlist->{$uname.':'.$udom}));
 
 	if ($check_section) {
 	    my $section =
@@ -1870,7 +2064,7 @@ sub lock_key {
 sub get_queue_symb_status {
     my ($queue,$symb,$cdom,$cnum) = @_;
     if (!defined($cdom) || !defined($cnum)) {
-	my (undef,$cid)=&Apache::lonnet::whichuser();
+	my (undef,$cid) =&Apache::lonnet::whichuser();
 	$cnum=$env{'course.'.$cid.'.num'};
 	$cdom=$env{'course.'.$cid.'.domain'};
     }
@@ -1886,6 +2080,7 @@ sub get_queue_symb_status {
 	next if ($key=~/timestamp$/);
 	my ($symb,$uname,$udom) = &decode_queue_key($key);
 	next if (!defined($classlist->{$uname.':'.$udom}));
+	next if (!&allow_grade_user($classlist->{$uname.':'.$udom}));
 	push(@users,"$uname:$udom");
     }
     return @users;
@@ -1972,15 +2167,15 @@ sub get_from_queue {
 sub select_user {
     my ($symb,$cid)=&Apache::lonnet::whichuser();
 
-    my @chosen_sections=
-	&Apache::loncommon::get_env_multiple('form.chosensections');
-
+    my @chosen_sections = &get_allowed_sections();
     my $classlist = &get_limited_classlist(\@chosen_sections);
     
     my $result;
     if (!(grep(/^all$/,@chosen_sections))) {
-	$result.='<p> Showing only sections <tt>'.join(', ',@chosen_sections).
-	    '</tt>.</p> '."\n";
+        $result.='<p>'
+                .&mt('Showing only sections [_1].'
+                    ,'<tt>'.join(', ',@chosen_sections).'</tt>')
+                .'</p> '."\n";
     }
     $result.=&Apache::loncommon::start_data_table();
 
@@ -2016,6 +2211,7 @@ sub select_user {
 		$seclist.='<input type="hidden" name="chosensections" 
                                value="'.$sec.'" />';
 	    }
+            my $buttontext=&mt('Regrade');
 	    $result.=&Apache::loncommon::start_data_table_row();
 	    $result.=<<RESULT;
   <td>
@@ -2024,10 +2220,10 @@ sub select_user {
       <input type="hidden" name="queue" value="$queue" />
       <input type="hidden" name="webgrade" value="no" />
       <input type="hidden" name="regrade" value="yes" />
-      <input type="submit" name="submit" value="Regrade" />
+      <input type="submit" name="submit" value="$buttontext" />
       $seclist
     </form>
-  <td>$classlist->{$student}[&Apache::loncoursedata::CL_FULLNAME()] <tt>($student)</tt></td>
+  <td>$classlist->{$student}[&Apache::loncoursedata::CL_FULLNAME()] <tt>($student)</tt> Sec: $classlist->{$student}[&Apache::loncoursedata::CL_SECTION()]</td>
   <td>
 RESULT
         }
@@ -2134,9 +2330,7 @@ sub get_dim_id {
 
 sub get_id {
     my ($parstack,$safeeval)=@_;
-    my $id=&Apache::lonxml::get_param('id',$parstack,$safeeval);
-    if (!$id) { $id=$Apache::lonxml::curdepth; }
-    return $id;
+    return &Apache::lonxml::get_id($parstack,$safeeval);
 }
 
 sub start_Setup {
@@ -2224,8 +2418,8 @@ sub start_Dimension {
 	$result.=  
 	    &Apache::edit::text_arg('Id:','id',$token,10).' '.
 	    &Apache::edit::select_arg('Passing is Mandatory:','Mandatory',
-				      [['yes', 'Yes'],
-				       ['no','No'],],
+				      [['Y', 'Yes'],
+				       ['N','No'],],
 				      $token).' <br /> '.
 	    &Apache::edit::text_arg('Required number of passed optional elements to pass the '.$token->[1].':',
 				    'OptionalRequired',$token,4).
@@ -2379,10 +2573,14 @@ sub end_Dimension {
 		    ('sub' x $dimension{$dim}{'depth'}).'question';
 		$ucquestion =~ s/^(.)/uc($1)/e;
 		if ($dim_status eq 'pass') {
-		    $dim_info.='<h3>'.$ucquestion.' : you passed this '.$mandatory.' '.$question.'</h3>';
+                    $dim_info.='<h3>'.$ucquestion.' : '
+                              .&mt('you passed this [_1] [_2]',$mandatory,$question)
+                              .'</h3>';
 		}
 		if ($dim_status eq 'fail') {
-		    $dim_info.='<h3>'.$ucquestion.' : you did not pass this '.$mandatory.' '.$question.'</h3>';
+                    $dim_info.='<h3>'.$ucquestion.' : '
+                              .&mt('you did not pass this [_1] [_2]',$mandatory,$question)
+                              .'</h3>';
 		}
 		my %counts = &get_counts($dim,$instance,$parstack,
 					 $safeeval);
@@ -2581,16 +2779,11 @@ sub question_status_message {
     }
     $status .= '.';
     if ($counts->{'opt'}) {
-	$status .= ' You were required to pass '.$counts->{'opt_req'}.
-	    ' optional ';
-	if ($counts->{'opt_dim'} + $counts->{'man_dim'} < 1) {
-	    $status .=
-		($counts->{'opt_req'} == 1?'criterion':'criteria');
-	} else {
-	    $status .=
-		'component'.($counts->{'opt_req'} == 1?'':'s');
-	}
-	$status .= '.';
+        if ($counts->{'opt_dim'} + $counts->{'man_dim'} < 1) {
+            $status .= ' '.&mt('You were required to pass [quant,_1,optional criterion,optional criteria].',$counts->{'opt_req'});
+        } else { 
+            $status .= ' '.&mt('You were required to pass [quant,_1,optional component].',$counts->{'opt_req'});
+        }
     }
     return $status;
 }
@@ -2689,7 +2882,8 @@ sub end_Setup {
 
 sub grading_history {
     my ($version,$dim,$id) = @_;
-    if (!&Apache::lonnet::allowed('mgq',$env{'request.course.id'})) {
+    if (!&Apache::lonnet::allowed('mgq',$env{'request.course.id'})
+	&& !&Apache::lonnet::allowed('mgq',$env{'request.course.id'}.'/'.$env{'request.course.sec'})) {
 	return '';
     }
     my ($result,$grader);
@@ -2867,8 +3061,8 @@ sub start_Criteria {
 	$result.=  
 	    &Apache::edit::text_arg('Id:','id',$token,10).' '.
 	    &Apache::edit::select_arg('Passing is Mandatory:','Mandatory',
-				      [['yes', 'Yes'],
-				       ['no','No'],],
+				      [['Y', 'Yes'],
+				       ['N','No'],],
 				      $token)
 	    .' <br /> '.&Apache::edit::end_row().
 	    &Apache::edit::start_spanning_row();
@@ -2919,25 +3113,25 @@ sub layout_webgrade_Criteria {
     my $link=&link($id);
     my $version = &get_version();
     my $status  = &get_criteria('status',$version,$dim,$id);
-    my %lt = ( 'ungraded' => 'Ungraded',
-	       'fail'     => 'Fail',
-	       'pass'     => 'Pass',
-	       'review'   => 'Review',
-	       'comment'  => 'Additional Comment for Student',
-	       );
-    %lt = &Apache::lonlocal::texthash(%lt);
+    my %lt = &Apache::lonlocal::texthash(
+        'ungraded' => 'Ungraded',
+        'fail'     => 'Fail',
+        'pass'     => 'Pass',
+        'review'   => 'Review',
+        'comment'  => 'Additional Comment for Student',
+    );
     my $comment = &get_criteria('comment',$version,$dim,$id);
     $comment = &HTML::Entities::encode($comment,'<>"&');
     my %checked;
     foreach my $which ('ungraded','fail','pass','review') {
-	if ($status eq $which) { $checked{$which} = 'checked="checked"'; }
+	if ($status eq $which) { $checked{$which} = ' checked="checked"'; }
     }
-    if (!%checked) { $checked{'ungraded'} = 'checked="checked"'; }
+    if (!%checked) { $checked{'ungraded'} = ' checked="checked"'; }
     my $buttons;
     foreach my $which  ('ungraded','fail','pass','review') {
 	$buttons .= <<END_BUTTON;
 		<label class="LC_GRADING_$which">
-			<input type="radio" name="HWVAL_$link" value="$which" $checked{$which} />
+			<input type="radio" name="HWVAL_$link" value="$which"$checked{$which} />
 			$lt{$which}
 		</label>
 END_BUTTON
@@ -3064,39 +3258,52 @@ sub proctor_validation_screen {
     }
     if (!$valid) {
 	$msg.='<p><span class="LC_error">'
-	    .&mt("No valid poctors are defined.")
+	    .&mt("No valid proctors are defined.")
 	    .'</span></p>';
     }
     
     if (!$env{'form.proctordomain'}) { $env{'form.proctordomain'}=$domain; }
     my $uri = &Apache::lonenc::check_encrypt($env{'request.uri'});
     $uri = &HTML::Entities::encode($uri,'<>&"');
+    my %lt = &Apache::lonlocal::texthash(
+                            'prva' => "Proctor Validation",
+                            'yoro' => "Your room's proctor needs to validate your access to this resource.",
+                            'prus'  => "Proctor's Username:",
+                            'pasw'  => "Password:",
+                            'prdo'  => "Proctor's Domain:",
+                            'vali'  => 'Validate',
+                            'stui'  => "Student who should be logged in is:",
+                            'name'  => "Name:",
+                            'sid'   => "Student/Employee ID",
+                            'unam'  => "Username:",
+                           );
     my $result= (<<ENDCHECKOUT);
-<h2>Proctor Validation</h2>
-    <p>Your room's proctor needs to validate your access to this resource.</p>
+<h2>$lt{'prva'}</h2>
+    <p>$lt{'yoro'}</p>
     $msg
 <form name="checkout" method="post" action="$uri">
 <input type="hidden" name="validate" value="yes" />
 <input type="hidden" name="submitted" value="yes" />
 <table>
-  <tr><td>Proctor's Username:</td><td><input type="string" name="proctorname" value="$env{'form.proctorname'}" /></td></tr>
-  <tr><td>Password:</td><td><input type="password" name="proctorpassword" value="" /></td></tr>
-  <tr><td>Proctor's Domain:</td><td><input type="string" name="proctordomain" value="$env{'form.proctordomain'}" /></td></tr>
+  <tr><td>$lt{'prus'}</td><td><input type="string" name="proctorname" value="$env{'form.proctorname'}" /></td></tr>
+  <tr><td>$lt{'pasw'}</td><td><input type="password" name="proctorpassword" value="" /></td></tr>
+  <tr><td>$lt{'prdo'}</td><td><input type="string" name="proctordomain" value="$env{'form.proctordomain'}" /></td></tr>
 </table>
-<input type="submit" name="checkoutbutton" value="Validate"  /><br />
+<input type="submit" name="checkoutbutton" value="$lt{'vali'}"  /><br />
 <table border="1">
   <tr><td>
     <table>
-      <tr><td colspan="2">Student who should be logged in is:</td></tr>
-      <tr><td>Name:</td><td>$name</td></tr>
-      <tr><td>Student ID:</td><td>$env{'environment.id'}</td></tr>
-      <tr><td>Usename</td><td>$user:$domain</td></tr>
+      <tr><td colspan="2">$lt{'stui'}</td></tr>
+      <tr><td>$lt{'name'}</td><td>$name</td></tr>
+      <tr><td>$lt{'sid'}</td><td>$env{'environment.id'}</td></tr>
+      <tr><td>$lt{'unam'}</td><td>$user:$domain</td></tr>
       $url
     </table>
   </tr></td>
 </table>
 </form>
 ENDCHECKOUT
+
     return $result;
 }