--- loncom/interface/lonpreferences.pm	2006/03/15 21:19:10	1.75
+++ loncom/interface/lonpreferences.pm	2006/06/22 23:30:33	1.92
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Preferences
 #
-# $Id: lonpreferences.pm,v 1.75 2006/03/15 21:19:10 albertel Exp $
+# $Id: lonpreferences.pm,v 1.92 2006/06/22 23:30:33 albertel Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -33,6 +33,7 @@
 package Apache::lonpreferences;
 
 use strict;
+use LONCAPA;
 use Apache::Constants qw(:common);
 use Apache::File;
 use Crypt::DES;
@@ -98,16 +99,16 @@ sub wysiwygchanger {
     my $r = shift;
     my %userenv = &Apache::lonnet::get
         ('environment',['wysiwygeditor']);
+    my $onselect='checked="checked"';
     my $offselect='';
-    my $onselect='checked="1"';
-    if ($userenv{'wysiwygeditor'}) {
+    if ($userenv{'wysiwygeditor'} eq 'on') {
 	$onselect='';
-	$offselect='checked="1"';
+	$offselect='checked="checked"';
     }
     my $switchoff=&mt('Disable WYSIWYG editor');
     my $switchon=&mt('Enable WYSIWYG editor');
     $r->print(<<ENDLSCREEN);
-<form name="server" action="/adm/preferences" method="post">
+<form name="prefs" action="/adm/preferences" method="post">
 <input type="hidden" name="action" value="set_wysiwyg" />
 <br />
 <label><input type="radio" name="wysiwyg" value="off" $onselect /> $switchoff</label><br />
@@ -147,7 +148,7 @@ sub languagechanger {
     my $selectionbox=&Apache::loncommon::select_form($language,'language',
 						     %langchoices);
     $r->print(<<ENDLSCREEN);
-<form name="server" action="/adm/preferences" method="post">
+<form name="prefs" action="/adm/preferences" method="post">
 <input type="hidden" name="action" value="verify_and_change_languages" />
 <br />$pref: $selectionbox
 ENDLSCREEN
@@ -201,14 +202,14 @@ sub texenginechanger {
     $r->print(<<ENDLSCREEN);
 <br />
 
-<form name="server" action="/adm/preferences" method="post">
+<form name="prefs" action="/adm/preferences" method="post">
 <input type="hidden" name="action" value="verify_and_change_texengine" />
 <p>$pref: $selectionbox</p>
 <p><input type="submit" value="$change" /></p>
 </form>
 Examples:
 <p> TeX to HTML <br /> 
-<iframe src="/res/adm/pages/math_example.tex?buttons=no&mode=tth" width="400" hieght="200"></iframe>
+<iframe src="/res/adm/pages/math_example.tex?inhibitmenu=yes&texengine=tth" width="400" hieght="200"></iframe>
 </p>
 <p>jsMath <br /> 
 $jsMath_start
@@ -228,12 +229,12 @@ if (jsMath.nofonts == 1) {
 	 +'</font></small></div></center>');
 }
 </script>
-<iframe src="/res/adm/pages/math_example.tex?buttons=no&mode=jsMath" width="400" hieght="200"></iframe>
+<iframe src="/res/adm/pages/math_example.tex?inhibitmenu=yes&texengine=jsMath" width="400" hieght="200"></iframe>
 
 </p>
 <p> Convert to Images <br />
 <br />
-<iframe src="/res/adm/pages/math_example.tex?buttons=no&mode=mimetex" width="400" hieght="200"></iframe>
+<iframe src="/res/adm/pages/math_example.tex?inhibitmenu=yes&texengine=mimetex" width="400" hieght="200"></iframe>
 </p>
 ENDLSCREEN
     if ($env{'environment.texengine'} ne 'jsMath') {
@@ -297,25 +298,91 @@ sub rolesprefchanger {
 	$options .= "<option $select>$i</option>\n";
     }
 
-    $r->print(<<ENDSCREEN);
-<p>Some LON-CAPA users have a long list of roles. The Recent Roles Hotlist
-feature keeps track of the last N roles which have been
-visited and places a table of these at the top of the roles page.
-People with very few roles should leave this feature disabled.
-</p>
+# Get list of recent roles and display with checkbox in front
+    my $roles_check_list = '';
+    my $role_key='';
+    if ($env{'environment.recentroles'}) {
+        my %recent_roles =
+               &Apache::lonhtmlcommon::get_recent('roles',$env{'environment.recentrolesn'});
+        my %frozen_roles =
+               &Apache::lonhtmlcommon::get_recent_frozen('roles',$env{'environment.recentrolesn'});
+        
+        my %role_text = &rolespref_get_role_text(keys(%recent_roles));
+        my @sorted_roles = sort {$role_text{$a} cmp $role_text{$b}} keys(%role_text);
+
+        $roles_check_list .=
+	    &Apache::loncommon::start_data_table().
+	    &Apache::loncommon::start_data_table_header_row().
+	    "<th>".&mt('Freeze Role')."</th>".
+	    "<th>".&mt('Role')."</td>".
+	    &Apache::loncommon::end_data_table_header_row().
+	    "\n";
+	my $count;
+        foreach $role_key (@sorted_roles) {
+            my $checked = "";
+            my $value = $recent_roles{$role_key};
+            if ($frozen_roles{$role_key}) {
+                $checked = "checked=\"checked\"";
+            }
+	    $count++;
+            $roles_check_list .=
+		&Apache::loncommon::start_data_table_row().
+		'<td class="LC_table_cell_checkbox">'.
+		"<input type=\"checkbox\" $checked name=\"freezeroles\"".
+		" id=\"freezeroles$count\" value=\"$role_key\" /></td>".
+		"<td><label for=\"freezeroles$count\">".
+		"$role_text{$role_key}</label></td>".
+		&Apache::loncommon::end_data_table_row(). "\n";
+        }
+        $roles_check_list .= "</table>\n";
+    }
 
-<form name="server" action="/adm/preferences" method="post">
+    $r->print('
+<p>'.&mt('Some LON-CAPA users have a long list of roles. The Recent Roles Hotlist feature keeps track of the last N roles which have been visited and places a table of these at the top of the roles page. People with very few roles should leave this feature disabled.').'
+</p>
+<form name="prefs" action="/adm/preferences" method="POST">
 <input type="hidden" name="action" value="verify_and_change_rolespref" />
-<br />Enable Recent Roles Hotlist:
-<input type="checkbox" $checked name="recentroles" value="true" />
-<br />Number of roles in Hotlist:
+<br /><label>'.&mt('Enable Recent Roles Hotlist:').'
+<input type="checkbox" '.$checked.' name="recentroles" value="true" /></label>
+<br />'.&mt('Number of roles in Hotlist:').'
 <select name="recentrolesn" size="1">
-$options
+'.$options.'
 </select>
+<p>'.&mt('This list below can be used to <q>freeze</q> roles on your screen. Those marked as frozen will not be removed from the list, even if they have not been used recently.').'
+</p>
+'.$roles_check_list.'
 <br />
-<input type="submit" value="Change" />
-</form>
-ENDSCREEN
+<input type="submit" value="'.&mt('Change').'" />
+</form>');
+}
+
+sub rolespref_get_role_text {
+# Get a line of text for each role
+    my ($roles) = @_;
+    my %roletext = ();
+
+    foreach my $item (@$roles) {
+# get course information
+        my ($role,$rest) = split(/\./, $item);
+        my $trole = &Apache::lonnet::plaintext($role);
+        my ($tdomain,$other,$tsection)= split(/\//,Apache::lonnet::declutter($rest));
+        my $tother = '-';
+        if ($role =~ /cc|st|in|ta/ ) {
+            my %newhash=&Apache::lonnet::coursedescription($tdomain."_".$other);
+            $tother = " - ".$newhash{'description'};
+        } elsif ($role =~ /dc/) {
+            $tother = "";
+        } else {
+            $tother = " - $other";
+        }
+ 
+        my $section="";
+        if ($tsection) {
+            $section = " - Section/Group: $tsection";
+        }
+        $roletext{$item} = $tdomain." - ".$trole.$tother.$section;
+    }
+    return %roletext;
 }
 
 sub verify_and_change_rolespref {
@@ -325,24 +392,58 @@ sub verify_and_change_rolespref {
 # Recent Roles Hotlist Flag
     my $hotlist_flag  = $env{'form.recentroles'};
     my $hotlist_n  = $env{'form.recentrolesn'};
-    my $message='';
+    my $message='<hr />';
     if ($hotlist_flag) {
         &Apache::lonnet::put('environment',{'recentroles' => $hotlist_flag});
         &Apache::lonnet::appenv('environment.recentroles' => $hotlist_flag);
-        $message='Recent Roles Hotlist is Enabled';
+        $message=&mt('Recent Roles Hotlist is Enabled');
     } else {
         &Apache::lonnet::del('environment',['recentroles']);
         &Apache::lonnet::delenv('environment\.recentroles');
-        $message='Recent Roles Hotlist is Disabled';
+        $message=&mt('Recent Roles Hotlist is Disabled');
     }
     if ($hotlist_n) {
         &Apache::lonnet::put('environment',{'recentrolesn' => $hotlist_n});
         &Apache::lonnet::appenv('environment.recentrolesn' => $hotlist_n);
         if ($hotlist_flag) {
-            $message.="<br />Display $hotlist_n Most Recent Roles\n";
+            $message.="<br />".
+		&mt('Display [_1] Most Recent Roles',$hotlist_n)."\n";
+        }
+    }
+
+# Get list of froze roles and list of recent roles
+    my @freeze_list = &Apache::loncommon::get_env_multiple('form.freezeroles');
+    my %freeze = ();
+    my %roletext = ();
+
+    foreach my $key (@freeze_list) {
+        $freeze{$key}='1';
+    }
+
+    my %recent_roles =
+        &Apache::lonhtmlcommon::get_recent('roles',$env{'environment.recentrolesn'});
+    my %frozen_roles =
+        &Apache::lonhtmlcommon::get_recent_frozen('roles',$env{'environment.recentrolesn'});
+    my %role_text = &rolespref_get_role_text([keys(%recent_roles)]);
+
+# Unset any roles that were previously frozen but aren't in list
+    foreach my $role_key (sort(keys(%recent_roles))) {
+        if (($frozen_roles{$role_key}) && (!exists($freeze{$role_key}))) {
+	    $message .= "<br />".&mt('Unfreezing Role: [_1]',$role_text{$role_key})."\n";
+	    &Apache::lonhtmlcommon::store_recent('roles',$role_key,' ',0);
         }
     }
 
+# Freeze selected roles
+    foreach my $role_key (@freeze_list) {
+        if (!$frozen_roles{$role_key}) {
+             $message .= "<br />".&mt('Freezing Role: [_1]',$role_text{$role_key})."\n";
+             &Apache::lonhtmlcommon::store_recent('roles',
+                                          $role_key,' ',1);
+        }
+    }
+    $message .= "<hr /><br />\n";
+
     $r->print(<<ENDRPSCREEN);
 $message
 ENDRPSCREEN
@@ -362,7 +463,7 @@ sub screennamechanger {
     my $screenname=$userenv{'screenname'};
     my $nickname=$userenv{'nickname'};
     $r->print(<<ENDSCREEN);
-<form name="server" action="/adm/preferences" method="post">
+<form name="prefs" action="/adm/preferences" method="post">
 <input type="hidden" name="action" value="verify_and_change_screenname" />
 <br />New screenname (shown if you post anonymously):
 <input type="text" size="20" value="$screenname" name="screenname" />
@@ -430,7 +531,7 @@ sub msgforwardchanger {
 
     $r->print(<<ENDMSG);
 $forwardingHelp <br />
-<form name="server" action="/adm/preferences" method="post">
+<form name="prefs" action="/adm/preferences" method="post">
 <input type="hidden" name="action" value="verify_and_change_msgforward" />
 New Forwarding Address(es) (<tt>user:domain,user:domain,...</tt>):
 <input type="text" size="40" value="$msgforward" name="msgforward" /><hr />
@@ -505,17 +606,7 @@ ENDVCMSG
 sub colorschanger {
     my $r = shift;
 # figure out colors
-    my $function='student';
-    if ($env{'request.role'}=~/^(cc|in|ta|ep)/) {
-	$function='coordinator';
-    }
-    if ($env{'request.role'}=~/^(su|dc|ad|li)/) {
-	$function='admin';
-    }
-    if (($env{'request.role'}=~/^(au|ca)/) ||
-	($ENV{'REQUEST_URI'}=~/^(\/priv|\~)/)) {
-	$function='author';
-    }
+    my $function=&Apache::loncommon::get_users_function();
     my $domain=&Apache::loncommon::determinedomain();
     my %colortypes=('pgbg'  => 'Page Background',
                     'tabbg' => 'Header Background',
@@ -524,19 +615,23 @@ sub colorschanger {
                     'link'  => 'Un-Visited Link',
                     'vlink' => 'Visited Link',
                     'alink' => 'Active Link');
+    my $start_data_table = &Apache::loncommon::start_data_table();
     my $chtable='';
     foreach my $item (sort(keys(%colortypes))) {
        my $curcol=&Apache::loncommon::designparm($function.'.'.$item,$domain);
-       $chtable.='<tr><td>'.$colortypes{$item}.'</td><td bgcolor="'.$curcol.
+       $chtable.=&Apache::loncommon::start_data_table_row().
+	   '<td>'.$colortypes{$item}.'</td><td style="background: '.$curcol.
         '">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td><td><input name="'.$item.
         '" size="10" value="'.$curcol.
 '" /></td><td><a href="javascript:pjump('."'color_custom','".$colortypes{$item}.
 "','".$curcol."','"
-	    .$item."','parmform.pres','psub'".');">Select</a></td></tr>';
+	    .$item."','parmform.pres','psub'".');">Select</a></td>'.
+	    &Apache::loncommon::end_data_table_row()."\n";
     }
+    my $end_data_table = &Apache::loncommon::end_data_table();
     my $pjump_def = &Apache::lonhtmlcommon::pjump_javascript_definition();
     $r->print(<<ENDCOL);
-<script>
+<script type="text/javascript">
 
     function pclose() {
         parmwin=window.open("/adm/rat/empty.html","LONCAPAparms",
@@ -550,7 +645,7 @@ sub colorschanger {
         pclose();
         if (document.parmform.pres_marker.value!='') {
             if (document.parmform.pres_type.value!='') {
-                eval('document.server.'+
+                eval('document.prefs.'+
                      document.parmform.pres_marker.value+
 		     '.value=document.parmform.pres_value.value;');
 	    }
@@ -567,10 +662,11 @@ sub colorschanger {
 <input type="hidden" name="pres_type" />
 <input type="hidden" name="pres_value" />
 </form>
-<form name="server" action="/adm/preferences" method="post">
+<form name="prefs" action="/adm/preferences" method="post">
 <input type="hidden" name="action" value="verify_and_change_colors" />
-<table border="2">
+$start_data_table
 $chtable
+$end_data_table
 </table>
 <input type="submit" value="Change Custom Colors" />
 <input type="submit" name="resetall" value="Reset All Colors to Default" />
@@ -581,17 +677,7 @@ ENDCOL
 sub verify_and_change_colors {
     my $r = shift;
 # figure out colors
-    my $function='student';
-    if ($env{'request.role'}=~/^(cc|in|ta|ep)/) {
-	$function='coordinator';
-    }
-    if ($env{'request.role'}=~/^(su|dc|ad|li)/) {
-	$function='admin';
-    }
-    if (($env{'request.role'}=~/^(au|ca)/) ||
-	($ENV{'REQUEST_URI'}=~/^(\/priv|\~)/)) {
-	$function='author';
-    }
+    my $function=&Apache::loncommon::get_users_function();
     my $domain=&Apache::loncommon::determinedomain();
     my %colortypes=('pgbg'  => 'Page Background',
                     'tabbg' => 'Header Background',
@@ -615,6 +701,10 @@ sub verify_and_change_colors {
 	    $message.='Reset '.$colortypes{$item}.'<br />';
 	}
     }
+    my $now = time;
+    &Apache::lonnet::put('environment',{'color.timestamp' => $now});
+    &Apache::lonnet::appenv('environment.color.timestamp' => $now);
+
     $r->print(<<ENDVCCOL);
 $message
 <form name="client" action="/adm/preferences" method="post">
@@ -887,40 +977,38 @@ sub discussionchanger {
     }
     
     $r->print(<<"END");
-<form name="server" action="/adm/preferences" method="post">
+<form name="prefs" action="/adm/preferences" method="post">
 <input type="hidden" name="action" value="verify_and_change_discussion" />
 <br />
-$lt{'sdpf'}<br/> $lt{'prca'}  <ol><li>$lt{'whpo'}</li><li>$lt{'unwh'}</li></ol> 
+$lt{'sdpf'}<br /> $lt{'prca'}  <ol><li>$lt{'whpo'}</li><li>$lt{'unwh'}</li></ol> 
 <br />
 <br />
-<table border="0" cellpadding="0" cellspacing="0">
- <tr>
-  <td width="100%" bgcolor="#000000">
-   <table width="100%" border="0" cellpadding="1" cellspacing="0">
-    <tr>
-     <td width="100%" bgcolor="#000000">
-      <table border="0" cellpadding="3" cellspacing="3" bgcolor="#FFFFFF">
-       <tr bgcolor="$color">
-        <td><b>$lt{'pref'}</b></td>
-        <td><b>$lt{'curr'}</b></td>
-        <td><b>$lt{'actn'}?</b></td>
+END
+    $r->print(&Apache::loncommon::start_data_table());
+    $r->print(<<"END");
+       <tr>
+        <th>$lt{'pref'}</th>
+        <th>$lt{'curr'}</th>
+        <th>$lt{'actn'}?</th>
        </tr>
-       <tr bgcolor="#dddddd">
+END
+    $r->print(&Apache::loncommon::start_data_table_row());
+    $r->print(<<"END");
        <td>$lt{'disa'}</td>
        <td>$lt{$discdisp}</td>
-       <td><input type="checkbox" name="discdisp" /><input type="hidden" name="newdisp" value="$newdisp" />&nbsp;$lt{'chgt'} "$dispchange"</td>
-      </tr><tr bgcolor="#eeeeee">
+       <td><label><input type="checkbox" name="discdisp" /><input type="hidden" name="newdisp" value="$newdisp" />&nbsp;$lt{'chgt'} "$dispchange"</label></td>
+END
+    $r->print(&Apache::loncommon::end_data_table_row().
+	      &Apache::loncommon::start_data_table_row());
+    $r->print(<<"END");
        <td>$lt{'npmr'}</td>
        <td>$lt{$discmark}</td>
-       <td><input type="checkbox" name="discmark" /><input type="hidden" name="newmark" value="$newmark" />&nbsp;$lt{'chgt'} "$markchange"</td>
+       <td><label><input type="checkbox" name="discmark" /><input type="hidden" name="newmark" value="$newmark" />&nbsp;$lt{'chgt'} "$markchange"</label></td>
       </tr>
-     </table>
-    </td>
-   </tr>
-  </table>
- </td>
-</tr>
-</table>
+END
+    $r->print(&Apache::loncommon::end_data_table_row().
+	      &Apache::loncommon::end_data_table());
+    $r->print(<<"END");
 <br />
 <br />
 <input type="submit" name="sub" value="Store Changes" />
@@ -939,11 +1027,11 @@ sub verify_and_change_discussion {
     if (defined($env{'form.discdisp'}) ) {
         my $newdisp  = $env{'form.newdisp'};
         if ($newdisp eq 'unread') {
-            $message .='In discussions: only new posts will be displayed.<br/>';
+            $message .='In discussions: only new posts will be displayed.<br />';
             &Apache::lonnet::put('environment',{'discdisplay' => $newdisp});
             &Apache::lonnet::appenv('environment.discdisplay' => $newdisp);
         } else {
-            $message .= 'In discussions: all posts will be displayed.<br/>';
+            $message .= 'In discussions: all posts will be displayed.<br />';
             &Apache::lonnet::del('environment',['discdisplay']);
             &Apache::lonnet::delenv('environment\.discdisplay');
         }
@@ -951,11 +1039,11 @@ sub verify_and_change_discussion {
     if (defined($env{'form.discmark'}) ) {
         my $newmark = $env{'form.newmark'};
         if ($newmark eq 'ondisp') {
-           $message.='In discussions: new posts will be cease to be identified as "new" after display.<br/>';
+           $message.='In discussions: new posts will be cease to be identified as "new" after display.<br />';
             &Apache::lonnet::put('environment',{'discmarkread' => $newmark});
             &Apache::lonnet::appenv('environment.discmarkread' => $newmark);
         } else {
-            $message.='In discussions: posts will be identified as "new" until marked as read by the reader.<br/>';
+            $message.='In discussions: posts will be identified as "new" until marked as read by the reader.<br />';
             &Apache::lonnet::del('environment',['discmarkread']);
             &Apache::lonnet::delenv('environment\.discmarkread');
         }
@@ -992,7 +1080,7 @@ sub coursedisplaychanger {
 
     $r->print('<br /><b>'.&mt('Set the default page to be displayed when you select a course role').'</b>&nbsp;'.&mt('(Currently: [_1])',$pagenames{$currvalue}).'<br />'.&mt('The global user preference you set for your courses can be overridden in an individual course by setting a course specific setting via the "[_1]" page in the course',"<i>What's New</i>").'<br /><br />');
     $r->print(<<ENDLSCREEN);
-<form name="server" action="/adm/preferences" method="post">
+<form name="prefs" action="/adm/preferences" method="post">
 <input type="hidden" name="action" value="verify_and_change_coursepage" />
 <br />
 <label><input type="radio" name="newdisp" value="firstres" $firstselect /> $whatsnew_off</label><br />
@@ -1016,11 +1104,11 @@ sub verify_and_change_coursepage {
     my $newdisp  = $env{'form.newdisp'};
     $message = '<b>'.$lt{'defs'}.'</b>: '.$lt{'when'}.', ';
     if ($newdisp eq 'firstres') {
-        $message .= $lt{'ywbt'}.'<br/>';
+        $message .= $lt{'ywbt'}.'<br />';
         &Apache::lonnet::put('environment',{'course_init_display' => $newdisp});
         &Apache::lonnet::appenv('environment.course_init_display' => $newdisp);
     } else {
-        $message .= $lt{'apwb'}.'<br/>';
+        $message .= $lt{'apwb'}.'<br />';
         &Apache::lonnet::del('environment',['course_init_display']);
         &Apache::lonnet::delenv('environment\.course_init_display');
     }
@@ -1224,6 +1312,19 @@ sub handler {
                             text => 'Change Math Preferences'},
                       printmenu => 'yes',
                       }));
+
+    if ($env{'environment.remote'} eq 'off') {
+	push (@Options,({ action => 'launch',
+			  linktext => 'Launch Remote Control',
+			  href => '/adm/remote?url=/adm/preferences',
+		      }));
+    } else {
+	push (@Options,({ action => 'collapse',
+			  linktext => 'Collapse Remote Control',
+			  href => '/adm/remote?url=/adm/preferences',
+		      }));
+    }
+
     if (&Apache::lonnet::allowed('whn',$env{'request.course.id'})
 	|| &Apache::lonnet::allowed('whn',$env{'request.course.id'}.'/'
 				    .$env{'request.course.sec'})) {
@@ -1249,13 +1350,9 @@ sub handler {
                           subroutine => \&toggle_debug,
                           }));
     }
-    my $html=&Apache::lonxml::xmlbegin();
-    $r->print(<<ENDHEADER);
-$html
-<head>
-<title>LON-CAPA Preferences</title>
-</head>
-ENDHEADER
+
+    $r->print(&Apache::loncommon::start_page('Change Preferences'));
+
     my $call = undef;
     my $help = undef;
     my $printmenu = 'yes';
@@ -1270,9 +1367,7 @@ ENDHEADER
 	    $help=$option->{'help'};
         }
     }
-    $r->print(&Apache::loncommon::bodytag('Change Preferences'));
-    $r->print(&Apache::lonhtmlcommon::breadcrumbs
-              (undef,'Change Preferences',$help));
+    $r->print(&Apache::lonhtmlcommon::breadcrumbs('Change Preferences',$help));
     my $error;
     if (defined($call)) {
         $error = $call->($r);
@@ -1296,9 +1391,10 @@ ENDHEADER
         foreach my $option(@Options) {
             my $optiontext = '';
             if (exists($option->{'href'})) {
-                $optiontext .= 
-                    '<a href="'.$option->{'href'}.
-                    '?action='.$option->{'action'}.'">'.
+		$option->{'href_args'}{'action'}=$option->{'action'};
+		$optiontext .= 
+                    '<a href="'.&add_get_param($option->{'href'},
+					       $option->{'href_args'}).'">'.
                     &mt($option->{'linktext'}).'</a>';
             }
             if (exists($option->{'text'})) {
@@ -1323,7 +1419,7 @@ ENDHEADER
 	$r->print('<br /><a href="'.$env{'form.returnurl'}.'"><font size="+1">'.
 		  &mt('Return').'</font></a>');
     }
-    $r->print(&Apache::loncommon::endbodytag().'</html>');
+    $r->print(&Apache::loncommon::end_page());
     return OK;
 }