Annotation of loncom/interface/lonpreferences.pm, revision 1.248

1.1       www         1: # The LearningOnline Network
                      2: # Preferences
                      3: #
1.248   ! raeburn     4: # $Id: lonpreferences.pm,v 1.247 2025/03/05 05:24:42 raeburn Exp $
1.2       albertel    5: #
                      6: # Copyright Michigan State University Board of Trustees
                      7: #
                      8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
                      9: #
                     10: # LON-CAPA is free software; you can redistribute it and/or modify
                     11: # it under the terms of the GNU General Public License as published by
                     12: # the Free Software Foundation; either version 2 of the License, or
                     13: # (at your option) any later version.
                     14: #
                     15: # LON-CAPA is distributed in the hope that it will be useful,
                     16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
                     17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     18: # GNU General Public License for more details.
                     19: #
                     20: # You should have received a copy of the GNU General Public License
                     21: # along with LON-CAPA; if not, write to the Free Software
                     22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     23: #
                     24: # /home/httpd/html/adm/gpl.txt
                     25: #
                     26: # http://www.lon-capa.org/
                     27: #
1.3       matthew    28: # This package uses the "londes.js" javascript code. 
                     29: #
                     30:  
1.1       www        31: package Apache::lonpreferences;
                     32: 
                     33: use strict;
                     34: use Apache::Constants qw(:common);
1.3       matthew    35: use Apache::File;
1.4       matthew    36: use Apache::loncommon();
1.23      matthew    37: use Apache::lonhtmlcommon();
1.32      www        38: use Apache::lonlocal;
1.59      albertel   39: use Apache::lonnet;
1.174     raeburn    40: use LONCAPA::lonauthcgi();
1.95      albertel   41: use LONCAPA();
1.241     raeburn    42: use DateTime::TimeZone();
1.3       matthew    43: 
1.4       matthew    44: ################################################################
                     45: #                       Handler subroutines                    #
                     46: ################################################################
1.9       matthew    47: 
                     48: ################################################################
1.28      www        49: #         Language Change Subroutines                          #
                     50: ################################################################
1.44      www        51: 
                     52: sub wysiwygchanger {
                     53:     my $r = shift;
1.126     droeschl   54:     Apache::lonhtmlcommon::add_breadcrumb(
                     55: 	    {	href => '/adm/preferences?action=changewysiwyg',
                     56:                 text => 'Change WYSIWYG Preferences'});
1.147     schafran   57:     $r->print(Apache::loncommon::start_page('Content Display Settings'));
1.126     droeschl   58:     $r->print(Apache::lonhtmlcommon::breadcrumbs('Change WYSIWYG Preferences'));
                     59: 
1.44      www        60:     my %userenv = &Apache::lonnet::get
                     61:         ('environment',['wysiwygeditor']);
1.78      albertel   62:     my $onselect='checked="checked"';
1.44      www        63:     my $offselect='';
1.77      albertel   64:     if ($userenv{'wysiwygeditor'} eq 'on') {
1.44      www        65: 	$onselect='';
1.78      albertel   66: 	$offselect='checked="checked"';
1.44      www        67:     }
                     68:     my $switchoff=&mt('Disable WYSIWYG editor');
                     69:     my $switchon=&mt('Enable WYSIWYG editor');
1.124     www        70:     my $warning='';
                     71:     if ($env{'user.adv'}) {
1.185     droeschl   72:        $warning.='<p class="LC_warning">'.&mt("The WYSIWYG editor only supports simple HTML and is in many cases unsuited for advanced authoring. In a number of cases, it may destroy advanced authoring involving LaTeX and script function calls.")."</p>";
1.124     www        73:     }
1.44      www        74:     $r->print(<<ENDLSCREEN);
1.88      albertel   75: <form name="prefs" action="/adm/preferences" method="post">
1.44      www        76: <input type="hidden" name="action" value="set_wysiwyg" />
1.124     www        77: $warning
1.44      www        78: <br />
1.65      albertel   79: <label><input type="radio" name="wysiwyg" value="off" $onselect /> $switchoff</label><br />
                     80: <label><input type="radio" name="wysiwyg" value="on" $offselect /> $switchon</label>
1.44      www        81: ENDLSCREEN
1.136     schafran   82:     $r->print('<br /><input type="submit" value="'.&mt('Save').'" />');
1.44      www        83: }
                     84: 
                     85: 
                     86: sub verify_and_change_wysiwyg {
                     87:     my $r = shift;
1.59      albertel   88:     my $newsetting=$env{'form.wysiwyg'};
1.44      www        89:     &Apache::lonnet::put('environment',{'wysiwygeditor' => $newsetting});
1.116     raeburn    90:     &Apache::lonnet::appenv({'environment.wysiwygeditor' => $newsetting});
1.158     bisitz     91:     my $message=&Apache::lonhtmlcommon::confirm_success(&mt('Set [_1] to [_2]','<i>'.&mt('WYSIWYG Editor').'</i>','<tt>'.&mt($newsetting).'</tt>'));
                     92:     $message=&Apache::loncommon::confirmwrapper($message);
                     93:     &print_main_menu($r,$message);
1.44      www        94: }
                     95: 
                     96: ################################################################
                     97: #         Language Change Subroutines                          #
                     98: ################################################################
1.28      www        99: sub languagechanger {
                    100:     my $r = shift;
1.126     droeschl  101:     
                    102:     Apache::lonhtmlcommon::add_breadcrumb(
                    103: 	    {	href => '/adm/preferences?action=changelanguages',
1.127     droeschl  104:                 text => 'Change Language'});
1.147     schafran  105:     $r->print(Apache::loncommon::start_page('Content Display Settings'));
1.248   ! raeburn   106:     $r->print(Apache::lonhtmlcommon::breadcrumbs('Change Language').
        !           107:               '<div class="LC_landmark" role="main">'); 
1.204     raeburn   108:     my %userenv = &Apache::lonnet::get('environment',['languages']);
1.29      www       109:     my $language=$userenv{'languages'};
1.32      www       110: 
1.204     raeburn   111:     $r->print(
                    112:         '<form name="prefs" action="/adm/preferences" method="post">'."\n".
                    113:         '<input type="hidden" name="action" value="verify_and_change_languages" />'.
1.248   ! raeburn   114:         '<br /><span class="LC_nobreak"><label>'.&mt('Preferred language').':&nbsp;'.
        !           115:         &Apache::loncommon::select_language('language',$language,1).'</label></span>'."\n".
        !           116:         '<br /><input type="submit" value="'.&mt('Save').'" /></form></div>'
1.204     raeburn   117:     );
1.28      www       118: }
                    119: 
                    120: 
                    121: sub verify_and_change_languages {
                    122:     my $r = shift;
1.59      albertel  123:     my $user       = $env{'user.name'};
                    124:     my $domain     = $env{'user.domain'};
1.28      www       125: # Screenname
1.59      albertel  126:     my $newlanguage  = $env{'form.language'};
1.28      www       127:     $newlanguage=~s/[^\-\w]//g;
                    128:     my $message='';
                    129:     if ($newlanguage) {
1.29      www       130:         &Apache::lonnet::put('environment',{'languages' => $newlanguage});
1.116     raeburn   131:         &Apache::lonnet::appenv({'environment.languages' => $newlanguage});
1.183     bisitz    132:         $message=&Apache::lonhtmlcommon::confirm_success(
                    133:             &mt('Set [_1] to [_2]',
                    134:                 '<i>'.&mt('Preferred language').'</i>',
                    135:                 '<tt>"'.$newlanguage.'"</tt>.'))
                    136:            .'<br />'
                    137:            .&mt('The change will become active on the next page.');
1.28      www       138:     } else {
1.29      www       139:         &Apache::lonnet::del('environment',['languages']);
1.139     raeburn   140:         &Apache::lonnet::delenv('environment.languages');
1.158     bisitz    141:         $message=&Apache::lonhtmlcommon::confirm_success(&mt('Reset [_1]','<i>'.&mt('Preferred language').'</i>'));
1.28      www       142:     }
1.158     bisitz    143:     $message=&Apache::loncommon::confirmwrapper($message);
1.132     raeburn   144:     &Apache::loncommon::flush_langs_cache($user,$domain);
1.152     www       145:     &print_main_menu($r, $message);
1.28      www       146: }
                    147: 
1.50      albertel  148: ################################################################
1.54      albertel  149: #         Tex Engine Change Subroutines                        #
                    150: ################################################################
                    151: sub texenginechanger {
                    152:     my $r = shift;
1.126     droeschl  153:     Apache::lonhtmlcommon::add_breadcrumb(
                    154: 	    {	href => '/adm/preferences?action=changetexenginepref',
1.177     raeburn   155:                 text => 'Math display settings'});
1.147     schafran  156:     $r->print(Apache::loncommon::start_page('Content Display Settings'));
1.177     raeburn   157:     $r->print(Apache::lonhtmlcommon::breadcrumbs('Math display settings'));
1.59      albertel  158:     my $user       = $env{'user.name'};
                    159:     my $domain     = $env{'user.domain'};
1.54      albertel  160:     my %userenv = &Apache::lonnet::get('environment',['texengine']);
                    161:     my $texengine=$userenv{'texengine'};
1.220     raeburn   162:     if (lc($texengine) eq 'jsmath') {
                    163:         $texengine = 'MathJax';
                    164:     }
1.54      albertel  165: 
1.69      albertel  166:     my %mathchoices=('' => 'Default',
1.123     bisitz    167: 		     'tth' => 'tth (TeX to HTML)',
1.64      albertel  168: 		     #'ttm' => 'TeX to MathML',
1.195     dseaton   169: 		     'MathJax' => 'MathJax',
1.168     www       170: 		     'mimetex' => 'mimetex (Convert to Images)',
                    171:                      'raw' => 'Raw (Screen Reader)'
1.54      albertel  172:                      );
1.190     raeburn   173:     %mathchoices = &Apache::lonlocal::texthash(%mathchoices);
1.179     bisitz    174:     my $selectionbox=
                    175:            &Apache::loncommon::select_form(
                    176:                $texengine,
                    177:                'texengine',
1.190     raeburn   178:                \%mathchoices);
1.195     dseaton   179:     my $MathJax_start=&Apache::lontexconvert::MathJax_header();
1.123     bisitz    180:     my %lt=&Apache::lonlocal::texthash(
1.177     raeburn   181:       'headline' => 'Change how math is displayed',
                    182:       'preftxt'  => 'Preferred method to display math',
1.136     schafran  183:       'change'   => 'Save',
1.123     bisitz    184:       'exmpl'    => 'Examples',
1.195     dseaton   185:       'mathjax'  => 'MathJax:',
1.213     bisitz    186:       'mathjaxinfo' => 'MathJax provides rendered equations whose source code can be extracted in TeX and MathML formats by right clicking the equation.',
1.123     bisitz    187:       'tth'      => 'tth (TeX to HTML):',
                    188:       'mimetex'  => 'mimetex (Convert to Images):',
                    189:     );
                    190: 
1.54      albertel  191:     $r->print(<<ENDLSCREEN);
1.123     bisitz    192: <h2>$lt{'headline'}</h2>
1.88      albertel  193: <form name="prefs" action="/adm/preferences" method="post">
1.54      albertel  194: <input type="hidden" name="action" value="verify_and_change_texengine" />
1.123     bisitz    195: <p>
1.248   ! raeburn   196: <label>$lt{'preftxt'}: $selectionbox 
        !           197: </label><br />
1.136     schafran  198: <input type="submit" value="$lt{'change'}" />
1.123     bisitz    199: </p>
1.54      albertel  200: </form>
1.123     bisitz    201: <br />
                    202: <hr />
                    203: $lt{'exmpl'}
                    204: 
1.195     dseaton   205: <h3>$lt{'mathjax'}</h3>
                    206: </script>
1.213     bisitz    207: <iframe src="/res/adm/pages/math_example.tex?inhibitmenu=yes&texengine=MathJax" width="400" height="150"></iframe>
1.195     dseaton   208: </p>
                    209: <p>
1.213     bisitz    210: $lt{'mathjaxinfo'}
1.195     dseaton   211: </p>
                    212: 
1.123     bisitz    213: <h3>$lt{'mimetex'}</h3>
                    214: <p>
1.213     bisitz    215: <iframe src="/res/adm/pages/math_example.tex?inhibitmenu=yes&texengine=mimetex" width="400" height="150"></iframe>
1.67      albertel  216: </p>
1.123     bisitz    217: 
                    218: <h3>$lt{'tth'}</h3>
                    219: <p>
1.213     bisitz    220: <iframe src="/res/adm/pages/math_example.tex?inhibitmenu=yes&texengine=tth" width="400" height="150"></iframe>
1.67      albertel  221: </p>
1.54      albertel  222: ENDLSCREEN
                    223: }
                    224: 
                    225: 
                    226: sub verify_and_change_texengine {
                    227:     my $r = shift;
1.59      albertel  228:     my $user       = $env{'user.name'};
                    229:     my $domain     = $env{'user.domain'};
1.54      albertel  230: # Screenname
1.59      albertel  231:     my $newtexengine  = $env{'form.texengine'};
1.54      albertel  232:     $newtexengine=~s/[^\-\w]//g;
1.220     raeburn   233:     if (lc($newtexengine) eq 'jsmath') {
                    234:         $newtexengine = 'MathJax';
                    235:     }
1.56      albertel  236:     if ($newtexengine eq 'ttm') {
1.116     raeburn   237: 	&Apache::lonnet::appenv({'browser.mathml' => 1});
1.56      albertel  238:     } else {
1.59      albertel  239: 	if ($env{'environment.texengine'} eq 'ttm') {
1.116     raeburn   240: 	    &Apache::lonnet::appenv({'browser.mathml' => 0});
1.56      albertel  241: 	}
                    242:     }
1.54      albertel  243:     my $message='';
                    244:     if ($newtexengine) {
                    245:         &Apache::lonnet::put('environment',{'texengine' => $newtexengine});
1.116     raeburn   246:         &Apache::lonnet::appenv({'environment.texengine' => $newtexengine});
1.158     bisitz    247:         $message=&Apache::lonhtmlcommon::confirm_success(&mt('Set [_1] to [_2]','<i>'.&mt('Preferred method to display Math').'</i>','<tt>"'.$newtexengine.'"</tt>'));
1.54      albertel  248:     } else {
                    249:         &Apache::lonnet::del('environment',['texengine']);
1.139     raeburn   250:         &Apache::lonnet::delenv('environment.texengine');
1.158     bisitz    251:         $message=&Apache::lonhtmlcommon::confirm_success(&mt('Reset [_1]','<i>'.&mt('Preferred method to display Math').'</i>'));
1.54      albertel  252:     }
1.158     bisitz    253:     $message=&Apache::loncommon::confirmwrapper($message);
1.152     www       254:     &print_main_menu($r, $message);
1.54      albertel  255: }
                    256: 
                    257: ################################################################
1.50      albertel  258: #         Roles Page Preference Change Subroutines         #
                    259: ################################################################
                    260: sub rolesprefchanger {
                    261:     my $r = shift;
1.96      albertel  262:     my $role    = ($env{'user.adv'} ? 'Role' : 'Course');
                    263:     my $lc_role = ($env{'user.adv'} ? 'role' : 'course');
1.59      albertel  264:     my $user       = $env{'user.name'};
                    265:     my $domain     = $env{'user.domain'};
1.50      albertel  266:     my %userenv = &Apache::lonnet::get
                    267:         ('environment',['recentroles','recentrolesn']);
1.198     raeburn   268:     my $brtext = 'Change '.$role.' Page Pref';
                    269:     my $brtitle;
                    270:     if ($env{'form.returnurl'} eq '/adm/roles') {
                    271:         $brtext = 'Configure Hotlist';
                    272:     } else {
                    273:         $brtitle = $brtext;
                    274:     }
1.126     droeschl  275:     Apache::lonhtmlcommon::add_breadcrumb(
                    276: 	    {	href => '/adm/preferences?action=changerolespref',
1.198     raeburn   277:                 text => $brtext});
1.147     schafran  278:     $r->print(Apache::loncommon::start_page('Content Display Settings'));
1.248   ! raeburn   279:     $r->print(Apache::lonhtmlcommon::breadcrumbs($brtitle).
        !           280:               '<div class="LC_landmark" role="main">');
1.50      albertel  281:     my $hotlist_flag=$userenv{'recentroles'};
                    282:     my $hotlist_n=$userenv{'recentrolesn'};
1.198     raeburn   283:     my ($checkedon,$checkedoff);
1.50      albertel  284:     if ($hotlist_flag) {
1.198     raeburn   285: 	$checkedon = 'checked="checked"';
                    286:     } else {
                    287:         $checkedoff = 'checked="checked"';
1.50      albertel  288:     }
                    289:     
                    290:     if (!$hotlist_n) { $hotlist_n=3; }
                    291:     my $options;
                    292:     for (my $i=1; $i<10; $i++) {
                    293: 	my $select;
                    294: 	if ($hotlist_n == $i) { $select = 'selected="selected"'; }
                    295: 	$options .= "<option $select>$i</option>\n";
                    296:     }
                    297: 
1.89      albertel  298: # Get list of recent roles and display with checkbox in front
1.248   ! raeburn   299:     my $roles_check_list;
1.89      albertel  300:     if ($env{'environment.recentroles'}) {
                    301:         my %recent_roles =
                    302:                &Apache::lonhtmlcommon::get_recent('roles',$env{'environment.recentrolesn'});
1.91      albertel  303:         my %frozen_roles =
                    304:                &Apache::lonhtmlcommon::get_recent_frozen('roles',$env{'environment.recentrolesn'});
1.248   ! raeburn   305: 
1.93      albertel  306:         my %role_text = &rolespref_get_role_text([keys(%recent_roles)]);
1.92      albertel  307:         my @sorted_roles = sort {$role_text{$a} cmp $role_text{$b}} keys(%role_text);
                    308: 
1.248   ! raeburn   309:         if (@sorted_roles) {
        !           310:             $roles_check_list =
        !           311: 	        &Apache::loncommon::start_data_table().
        !           312: 	        &Apache::loncommon::start_data_table_header_row().
        !           313: 	        "<th>".&mt('Freeze '.$role)."</th>".
        !           314: 	        "<th>".&mt($role)."</th>".
        !           315: 	        &Apache::loncommon::end_data_table_header_row()."\n";
        !           316: 	    my $count = 0;
        !           317:             foreach my $role_key (@sorted_roles) {
        !           318:                 my $checked = "";
        !           319:                 my $value = $recent_roles{$role_key};
        !           320:                 if ($frozen_roles{$role_key}) {
        !           321:                     $checked = ' checked="checked"';
        !           322:                 }
        !           323: 	        $count++;
        !           324:                 $roles_check_list .=
        !           325: 		    &Apache::loncommon::start_data_table_row().
        !           326: 		    '<td class="LC_table_cell_checkbox">'.
        !           327: 		    "<input type=\"checkbox\"$checked name=\"freezeroles\"".
        !           328: 		    " id=\"freezeroles$count\" value=\"$role_key\" /></td>".
        !           329: 		    "<td><label for=\"freezeroles$count\">".
        !           330: 		    "$role_text{$role_key}</label></td>".
        !           331: 		    &Apache::loncommon::end_data_table_row(). "\n";
        !           332:             }
        !           333:             $roles_check_list .= &Apache::loncommon::end_data_table."\n";
1.89      albertel  334:         }
                    335:     }
                    336: 
1.198     raeburn   337:     my $actionurl = '/adm/preferences';
                    338:     if ($env{'form.returnurl'} eq '/adm/roles') {
                    339:         $actionurl = '/adm/roles';
                    340:     }
1.248   ! raeburn   341:     $r->print('<h2 class="LC_heading_2">'.&mt('Recent Roles Hotlist').'</h2>');
1.198     raeburn   342:     unless ($checkedon) {
                    343:         $r->print(&mt('LON-CAPA users with several '.$lc_role.'s may wish to enable the Hotlist.').'<br />');
                    344:     }
1.89      albertel  345:     $r->print('
1.198     raeburn   346: <form name="prefs" action="'.$actionurl.'" method="post">
1.50      albertel  347: <input type="hidden" name="action" value="verify_and_change_rolespref" />
1.198     raeburn   348: <input type="hidden" name="returnurl" value="'.$env{'form.returnurl'}.'" />
1.248   ! raeburn   349: <div class="LC_left_float"><h3 class="LC_heading_3">'.&mt('Hotlist options').'</h3>
1.198     raeburn   350: <p>'.
                    351: &mt('When enabled, the Hotlist keeps track of the last N '.$lc_role.'s visited.').'<br />'.
                    352: &mt('Those N '.$lc_role.'s are then shown in a table at the top of the '.$lc_role.'s page.').'</p>'.
1.181     wenzelju  353: &Apache::lonhtmlcommon::start_pick_box().
1.198     raeburn   354: &Apache::lonhtmlcommon::row_title(&mt('Use Recent '.$role.'s Hotlist')).
                    355: '<span class="LC_nobreak">
                    356: <label><input id="Hotliston" type="radio" '.$checkedon.' name="recentroles" value="1" />'.&mt('Yes').'</label>'.
                    357: ('&nbsp;'x2).
                    358: '<label><input id="Hotlistoff" type="radio" '.$checkedoff.' name="recentroles" value="0" />'.&mt('No').'</label>
                    359: </span>'.
1.181     wenzelju  360: &Apache::lonhtmlcommon::row_closure().
                    361: &Apache::lonhtmlcommon::row_title('<label for="NumberOfRoles">'.&mt('Number of '.$role.'s in Hotlist').'</label>').
                    362: '<select name="recentrolesn" size="1" id ="NumberOfRoles">'.
1.198     raeburn   363: $options.'
                    364: </select>'.
1.181     wenzelju  365: &Apache::lonhtmlcommon::row_closure(1).
1.198     raeburn   366: &Apache::lonhtmlcommon::end_pick_box().'
                    367: </div>');
1.235     raeburn   368:     if ($roles_check_list) {
1.198     raeburn   369:         $r->print('<div class="LC_left_float">
1.248   ! raeburn   370: <h3 class="LC_heading_3">'.&mt('Freeze Roles').'</h3>
1.198     raeburn   371: <p>'.&mt('The table below can be used to [_1]freeze[_2] '.$lc_role.'s in the Hotlist.','<q>','</q>').'<br />'.
1.201     raeburn   372: &mt('Those '.$lc_role.'s marked frozen will not be removed from the list, even if not recently used.').'
1.89      albertel  373: </p>
                    374: '.$roles_check_list.'
1.198     raeburn   375: </div>');
                    376:      } else {
                    377:          $r->print('<br clear="all" />'.
1.210     raeburn   378:                    &mt('Once the Hotlist contains recently visited '.$lc_role.'s you can return to this page to also set frozen roles.'));
1.198     raeburn   379:      }
                    380:      $r->print('
                    381: <br clear="all" />
1.136     schafran  382: <input type="submit" value="'.&mt('Save').'" />
1.248   ! raeburn   383: </form></div>');
1.50      albertel  384: }
                    385: 
1.92      albertel  386: sub rolespref_get_role_text {
                    387: # Get a line of text for each role
                    388:     my ($roles) = @_;
                    389:     my %roletext = ();
                    390: 
                    391:     foreach my $item (@$roles) {
                    392: # get course information
                    393:         my ($role,$rest) = split(/\./, $item);
1.93      albertel  394:         my $trole = "";
                    395:         $trole = &Apache::lonnet::plaintext($role);
1.92      albertel  396:         my ($tdomain,$other,$tsection)= split(/\//,Apache::lonnet::declutter($rest));
                    397:         my $tother = '-';
1.93      albertel  398:         if ($role =~ /^(cc|st|in|ta|ep|cr)/ ) {
1.92      albertel  399:             my %newhash=&Apache::lonnet::coursedescription($tdomain."_".$other);
                    400:             $tother = " - ".$newhash{'description'};
                    401:         } elsif ($role =~ /dc/) {
                    402:             $tother = "";
                    403:         } else {
                    404:             $tother = " - $other";
                    405:         }
                    406:  
                    407:         my $section="";
                    408:         if ($tsection) {
                    409:             $section = " - Section/Group: $tsection";
                    410:         }
                    411:         $roletext{$item} = $tdomain." - ".$trole.$tother.$section;
                    412:     }
                    413:     return %roletext;
                    414: }
                    415: 
1.50      albertel  416: sub verify_and_change_rolespref {
                    417:     my $r = shift;
1.96      albertel  418:     my $role = ($env{'user.adv'} ? 'Role' : 'Course');
1.59      albertel  419:     my $user       = $env{'user.name'};
                    420:     my $domain     = $env{'user.domain'};
1.50      albertel  421: # Recent Roles Hotlist Flag
1.59      albertel  422:     my $hotlist_flag  = $env{'form.recentroles'};
                    423:     my $hotlist_n  = $env{'form.recentrolesn'};
1.89      albertel  424:     my $message='<hr />';
1.50      albertel  425:     if ($hotlist_flag) {
                    426:         &Apache::lonnet::put('environment',{'recentroles' => $hotlist_flag});
1.116     raeburn   427:         &Apache::lonnet::appenv({'environment.recentroles' => $hotlist_flag});
1.180     wenzelju  428:         $message=&Apache::lonhtmlcommon::confirm_success(&mt('Recent '.$role.'s Hotlist is Enabled.')." ".&mt('Display [_1] Most Recent '.$role.'s.',$hotlist_n));
1.50      albertel  429:     } else {
                    430:         &Apache::lonnet::del('environment',['recentroles']);
1.139     raeburn   431:         &Apache::lonnet::delenv('environment.recentroles');
1.180     wenzelju  432:         $message=&Apache::lonhtmlcommon::confirm_success(&mt('Recent '.$role.'s Hotlist is Disabled'));
1.50      albertel  433:     }
                    434:     if ($hotlist_n) {
                    435:         &Apache::lonnet::put('environment',{'recentrolesn' => $hotlist_n});
1.116     raeburn   436:         &Apache::lonnet::appenv({'environment.recentrolesn' => $hotlist_n});
1.89      albertel  437:     }
                    438: 
                    439: # Get list of froze roles and list of recent roles
                    440:     my @freeze_list = &Apache::loncommon::get_env_multiple('form.freezeroles');
                    441:     my %freeze = ();
1.92      albertel  442:     my %roletext = ();
                    443: 
1.89      albertel  444:     foreach my $key (@freeze_list) {
1.91      albertel  445:         $freeze{$key}='1';
1.89      albertel  446:     }
1.92      albertel  447: 
1.89      albertel  448:     my %recent_roles =
                    449:         &Apache::lonhtmlcommon::get_recent('roles',$env{'environment.recentrolesn'});
1.91      albertel  450:     my %frozen_roles =
                    451:         &Apache::lonhtmlcommon::get_recent_frozen('roles',$env{'environment.recentrolesn'});
1.92      albertel  452:     my %role_text = &rolespref_get_role_text([keys(%recent_roles)]);
1.89      albertel  453: 
                    454: # Unset any roles that were previously frozen but aren't in list
                    455:     foreach my $role_key (sort(keys(%recent_roles))) {
1.91      albertel  456:         if (($frozen_roles{$role_key}) && (!exists($freeze{$role_key}))) {
1.158     bisitz    457: 	    $message .= "<br />".&Apache::lonhtmlcommon::confirm_success(&mt('Unfreezing '.$role.': [_1]','<i>'.$role_text{$role_key}.'</i>'));
1.91      albertel  458: 	    &Apache::lonhtmlcommon::store_recent('roles',$role_key,' ',0);
1.89      albertel  459:         }
                    460:     }
                    461: 
                    462: # Freeze selected roles
                    463:     foreach my $role_key (@freeze_list) {
1.91      albertel  464:         if (!$frozen_roles{$role_key}) {
1.154     www       465:              $message .= "<br />".
1.158     bisitz    466:              &Apache::lonhtmlcommon::confirm_success(&mt('Freezing '.$role.': [_1]','<i>'.$role_text{$role_key}.'</i>'));
1.89      albertel  467:              &Apache::lonhtmlcommon::store_recent('roles',
1.91      albertel  468:                                           $role_key,' ',1);
1.50      albertel  469:         }
                    470:     }
1.158     bisitz    471:     $message=&Apache::loncommon::confirmwrapper($message);
1.198     raeburn   472:     if ($env{'form.returnurl'} eq '/adm/roles') {
                    473:         return $message;
                    474:     } else {
                    475:         &print_main_menu($r, $message);
                    476:     }
1.50      albertel  477: }
                    478: 
                    479: 
1.28      www       480: ################################################################
1.9       matthew   481: #         Anonymous Discussion Name Change Subroutines         #
                    482: ################################################################
1.5       www       483: sub screennamechanger {
                    484:     my $r = shift;
1.59      albertel  485:     my $user       = $env{'user.name'};
                    486:     my $domain     = $env{'user.domain'};
1.14      www       487:     my %userenv = &Apache::lonnet::get
                    488:         ('environment',['screenname','nickname']);
1.6       www       489:     my $screenname=$userenv{'screenname'};
1.14      www       490:     my $nickname=$userenv{'nickname'};
1.126     droeschl  491:     Apache::lonhtmlcommon::add_breadcrumb(
                    492: 		{ href => '/adm/preferences?action=changescreenname',
                    493:                   text => 'Change Screen Name'});
1.147     schafran  494:     $r->print(Apache::loncommon::start_page('Personal Data'));
1.126     droeschl  495:     $r->print(Apache::lonhtmlcommon::breadcrumbs('Change Screen Name'));
1.248   ! raeburn   496:     $r->print('<div class="LC_landmark" role="main">');
        !           497:     my $caption = &mt('Name displayed in posts you make').':';            
1.133     bisitz    498:     $r->print('<form name="prefs" action="/adm/preferences" method="post">'
1.248   ! raeburn   499:              .'<p><input type="hidden" name="action" value="verify_and_change_screenname" />'
        !           500:              .&Apache::lonhtmlcommon::start_pick_box(undef,undef,$caption,'LC_caption_prefs')
1.247     raeburn   501:              .&Apache::lonhtmlcommon::row_title('<label for="screenname">'.&mt('Screenname').'</label> '.&mt('(shown if you post anonymously)'))
                    502:              .'<input type="text" size="20" value="'.$screenname.'" name="screenname" id="screenname" />'
1.133     bisitz    503:              .&Apache::lonhtmlcommon::row_closure()
1.247     raeburn   504:              .&Apache::lonhtmlcommon::row_title('<label for="nickname">'.&mt('Nickname').'</label> '.&mt('(shown if you post non-anonymously)'))
                    505:              .'<input type="text" size="20" value="'.$nickname.'" name="nickname" id="nickname" />'
1.133     bisitz    506:              .&Apache::lonhtmlcommon::row_closure()
1.247     raeburn   507:              .&Apache::lonhtmlcommon::row_title('<span class="LC_visually_hidden">'.&mt('Submit').':</span>','','','',1)
1.133     bisitz    508:              .'<input type="submit" value="'.&mt('Save').'" />'
                    509:              .&Apache::lonhtmlcommon::row_closure(1)
                    510:              .&Apache::lonhtmlcommon::end_pick_box()
1.248   ! raeburn   511:              .'</p></form></div>'
1.133     bisitz    512:     );
1.5       www       513: }
1.6       www       514: 
                    515: sub verify_and_change_screenname {
                    516:     my $r = shift;
1.59      albertel  517:     my $user       = $env{'user.name'};
                    518:     my $domain     = $env{'user.domain'};
1.14      www       519: # Screenname
1.59      albertel  520:     my $newscreen  = $env{'form.screenname'};
1.14      www       521:     $newscreen=~s/[^ \w]//g;
1.6       www       522:     my $message='';
                    523:     if ($newscreen) {
1.7       www       524:         &Apache::lonnet::put('environment',{'screenname' => $newscreen});
1.116     raeburn   525:         &Apache::lonnet::appenv({'environment.screenname' => $newscreen});
1.161     bisitz    526:         $message=&Apache::lonhtmlcommon::confirm_success(&mt('Set [_1] to [_2]','<i>'.&mt('Screenname').'</i>','<tt>"'.$newscreen.'"</tt>'));
1.6       www       527:     } else {
                    528:         &Apache::lonnet::del('environment',['screenname']);
1.139     raeburn   529:         &Apache::lonnet::delenv('environment.screenname');
1.158     bisitz    530:         $message=&Apache::lonhtmlcommon::confirm_success(&mt('Reset [_1]','<i>'.&mt('Screenname').'</i>'));
1.6       www       531:     }
1.14      www       532: # Nickname
                    533:     $message.='<br />';
1.59      albertel  534:     $newscreen  = $env{'form.nickname'};
1.14      www       535:     $newscreen=~s/[^ \w]//g;
                    536:     if ($newscreen) {
                    537:         &Apache::lonnet::put('environment',{'nickname' => $newscreen});
1.116     raeburn   538:         &Apache::lonnet::appenv({'environment.nickname' => $newscreen});
1.161     bisitz    539:         $message.=&Apache::lonhtmlcommon::confirm_success(&mt('Set [_1] to [_2]','<i>'.&mt('Nickname').'</i>','<tt>"'.$newscreen.'"</tt>'));
1.14      www       540:     } else {
                    541:         &Apache::lonnet::del('environment',['nickname']);
1.139     raeburn   542:         &Apache::lonnet::delenv('environment.nickname');
1.158     bisitz    543:         $message.=&Apache::lonhtmlcommon::confirm_success(&mt('Reset [_1]','<i>'.&mt('Nickname').'</i>'));
1.14      www       544:     }
1.68      www       545:     &Apache::lonnet::devalidate_cache_new('namescache',$user.':'.$domain);
1.158     bisitz    546:     $message=&Apache::loncommon::confirmwrapper($message);
1.152     www       547:     &print_main_menu($r, $message);
1.20      www       548: }
                    549: 
                    550: ################################################################
1.192     raeburn   551: #                     Icon Subroutines                         #
                    552: ################################################################
                    553: sub iconchanger {
                    554:     my $r = shift;
                    555:     &Apache::lonhtmlcommon::add_breadcrumb(
                    556:             {   href => '/adm/preferences?action=changeicons',
                    557:                 text => 'Change Menu Display'});
                    558:     $r->print(Apache::loncommon::start_page('Page Display Settings'));
1.248   ! raeburn   559:     $r->print(Apache::lonhtmlcommon::breadcrumbs('Change Menu Display').
        !           560:               '<div class="LC_landmark" role="main">');
1.192     raeburn   561: 
                    562:     my $user       = $env{'user.name'};
                    563:     my $domain     = $env{'user.domain'};
                    564:     my %userenv = &Apache::lonnet::get('environment',['icons']);
                    565:     my $iconic='checked="checked"';
                    566:     my ($classic,$onlyicon,$iconic_preview,$iconsonly_preview);
                    567:     if ($userenv{'icons'} eq 'classic') {
                    568:         $iconic='';
                    569:         $classic='<div class="LC_info">'.
                    570:                  &mt('Your current selection: "Use buttons and text" is deprecated - it is recommended that you change this to "Use icons and text".').'</div>';
                    571:     }
                    572:     if ($userenv{'icons'} eq 'iconsonly') {
                    573:        $onlyicon='checked="checked"';
                    574:        $iconic='';
                    575:     }
                    576:     my $change=&mt('Save');
                    577:     my %lt = &icon_options();
                    578:     my ($inlinetools,$toolsorder) = &icon_previews();
                    579:     if ((ref($inlinetools) eq 'HASH') && (ref($toolsorder) eq 'ARRAY')) {
                    580:         foreach my $tool (@{$toolsorder}) {
                    581:             my ($command,$row,$col,$img,$top,$bot,$act,$desc) = 
                    582:                 split(/\&/,$inlinetools->{$tool});
                    583:             $iconic_preview .= '<li><a title="'.$desc.'" class="LC_menubuttons_link" href=""><img alt="'.$desc.'" src="/res/adm/pages/'.$img.'"  class="LC_icon" /><span class="LC_menubuttons_inline_text">'.$top.('&nbsp;' x 2).'</span></a></li>';
                    584:             $iconsonly_preview .= '<li><a title="'.$desc.'" class="LC_menubuttons_link" href=""><img alt="'.$desc.'" src="/res/adm/pages/'.$img.'"  class="LC_icon" />&nbsp;</a></li>';
                    585:         }
                    586:     }
                    587:     $iconsonly_preview = '<ul class="LC_breadcrumb_tools_outerlist"><li>'.
                    588:                          '<ul>'.
                    589:                          $iconsonly_preview.
                    590:                          '</ul></li></ul>';
                    591:     $iconic_preview = '<ul class="LC_breadcrumb_tools_outerlist"><li>'.
                    592:                       '<ul>'.
                    593:                       $iconic_preview.
                    594:                       '</ul></li></ul>'; 
1.248   ! raeburn   595:     my $title = &mt('Use of icons and text');
1.192     raeburn   596:     $r->print(<<ENDSCREEN);
                    597: $classic
                    598: <form name="prefs" action="/adm/preferences" method="post">
                    599: <input type="hidden" name="action" value="verify_and_change_icons" />
1.248   ! raeburn   600: <fieldset style="display:inline;"><legend>$title</legend>
1.192     raeburn   601: <label><input type="radio" name="menumode" value="iconic" $iconic /> $lt{'iconic'}</label>$iconic_preview<br />
                    602: <label><input type="radio" name="menumode" value="iconsonly" $onlyicon /> $lt{'iconsonly'}</label>$iconsonly_preview<br />
1.248   ! raeburn   603: </fieldset>
        !           604: <p>
1.192     raeburn   605: <input type="submit" value="$change" />
1.248   ! raeburn   606: </p>
        !           607: </form></div>
1.192     raeburn   608: ENDSCREEN
                    609: }
                    610: 
                    611: sub verify_and_change_icons {
                    612:     my $r = shift;
                    613:     my $user       = $env{'user.name'};
                    614:     my $domain     = $env{'user.domain'};
                    615:     my $newicons   = $env{'form.menumode'};
                    616:     my %lt = &icon_options();
                    617:     my $newchoice = $newicons;
                    618:     if ($lt{$newicons}) {
                    619:         $newchoice = $lt{$newicons};
                    620:     }
                    621:     &Apache::lonnet::put('environment',{'icons' => $newicons});
                    622:     &Apache::lonnet::appenv({'environment.icons' => $newicons});
                    623:     my $message=&Apache::lonhtmlcommon::confirm_success(&mt('Set [_1] to [_2]','<i>'.&mt('Menu Display').'</i>','<tt>'.$newchoice.'</tt>'));
                    624:     $message=&Apache::loncommon::confirmwrapper($message);
                    625:     &print_main_menu($r, $message);
                    626: }
                    627: 
                    628: sub icon_options {
                    629:     return &Apache::lonlocal::texthash(
                    630:                                         iconic    => 'Use icons and text',
                    631:                                         iconsonly => 'Use icons only',
                    632:                                       );
                    633: }
                    634: 
                    635: sub icon_previews {
1.237     raeburn   636:      my %icon_text = &Apache::lonlocal::texthash (
1.192     raeburn   637:                       annotate => 'Notes',
1.197     raeburn   638:                       wishlist => 'Stored Links',
1.192     raeburn   639:                       catalog  => 'Info',
                    640:                       evaluate => 'Evaluate',
                    641:                       feedback => 'Communicate',
                    642:                       printout => 'Print',
                    643:                      );
                    644:     my %inlinetools = (
1.237     raeburn   645:         printout => "s&8&3&prt.png&$icon_text{'printout'}&printout[_1]&gopost('/adm/printout',currentURL)&".&mt('Prepare a printable document'),
                    646:         wishlist => "s&9&1&wishlist-link.png&$icon_text{'wishlist'}&wishlistlink[_2]&set_wishlistlink()&".&mt('Save a link for this resource in your personal Stored Links repository'),
1.238     raeburn   647:         evaluate => "s&8&1&eval.png&$icon_text{'evaluate'}&this[_1]&gopost('/adm/evaluate',currentURL,1)&".&mt('Provide my evaluation of this resource'),
1.237     raeburn   648:         feedback => "s&8&2&fdbk.png&$icon_text{'feedback'}&discuss[_1]&gopost('/adm/feedback',currentURL,1)&".&mt('Provide feedback messages or contribute to the course discussion about this resource'),
                    649:         annotate => "s&9&3&anot.png&$icon_text{'annotate'}&tations[_1]&annotate()&".&mt('Make notes and annotations about this resource'),
1.238     raeburn   650:         catalog  => "s&6&3&catalog.png&$icon_text{'catalog'}&info[_1]&catalog_info()&".&mt('Show Metadata'),
1.192     raeburn   651:     );
                    652:     my @toolsorder = qw(annotate wishlist evaluate feedback printout catalog);
                    653:     return (\%inlinetools,\@toolsorder);
                    654: }
                    655: 
                    656: ################################################################
1.105     www       657: #                     Clicker Subroutines                      #
                    658: ################################################################
                    659: 
                    660: sub clickerchanger {
                    661:     my $r = shift;
1.152     www       662:     &Apache::lonhtmlcommon::add_breadcrumb(
1.126     droeschl  663: 	    {	href => '/adm/preferences?action=changeclicker',
                    664:                 text => 'Register Clicker'});
1.147     schafran  665:     $r->print(Apache::loncommon::start_page('Other'));
1.248   ! raeburn   666:     $r->print(Apache::lonhtmlcommon::breadcrumbs('Register Clicker').
        !           667:               '<div class="LC_landmark" role="main">');
1.105     www       668:     my $user       = $env{'user.name'};
                    669:     my $domain     = $env{'user.domain'};
                    670:     my %userenv = &Apache::lonnet::get
                    671:         ('environment',['clickers']);
                    672:     my $clickers=$userenv{'clickers'};
                    673:     $clickers=~s/\,/\n/gs;
                    674:     my $text=&mt('Enter response device ("clicker") numbers');
1.151     bisitz    675:     my $change=&mt('Save');
1.114     bisitz    676:     my $helplink=&Apache::loncommon::help_open_topic('Clicker_Registration',&mt('Locating your clicker ID'));
1.105     www       677:     $r->print(<<ENDSCREEN);
1.248   ! raeburn   678: <br />
1.105     www       679: <form name="prefs" action="/adm/preferences" method="post">
                    680: <input type="hidden" name="action" value="verify_and_change_clicker" />
1.151     bisitz    681: <label>$helplink<br /><br />$text<br />
1.108     www       682: <textarea name="clickers" rows="5" cols="20">$clickers</textarea>
1.105     www       683: </label>
1.248   ! raeburn   684: <p>
1.105     www       685: <input type="submit" value="$change" />
1.248   ! raeburn   686: </p>
1.105     www       687: </form>
1.248   ! raeburn   688: </div>
1.105     www       689: ENDSCREEN
                    690: }
                    691: 
                    692: sub verify_and_change_clicker {
                    693:     my $r = shift;
                    694:     my $user       = $env{'user.name'};
                    695:     my $domain     = $env{'user.domain'};
1.218     raeburn   696:     my $uhome      = $env{'user.home'};
1.105     www       697:     my $newclickers  = $env{'form.clickers'};
1.218     raeburn   698:     my $message;
1.108     www       699:     $newclickers=~s/[^\w\:\-]+/\,/gs;
1.105     www       700:     $newclickers=~tr/a-z/A-Z/;
1.108     www       701:     $newclickers=~s/[\:\-]+/\-/g;
                    702:     $newclickers=~s/\,+/\,/g;
1.105     www       703:     $newclickers=~s/^\,//;
                    704:     $newclickers=~s/\,$//;
1.218     raeburn   705:     my @oldclickers = split(/,/,$env{'environment.clickers'});
                    706:     my @newclickers = split(/,/,$newclickers);
                    707:     my %newuniq;
                    708:     map { $newuniq{$_} = 1; }  @newclickers;
                    709:     @newclickers = sort(keys(%newuniq));
                    710:     my @differences = &Apache::loncommon::compare_arrays(\@oldclickers,\@newclickers);
                    711:     if (@differences) {
                    712:         my $putres = &Apache::lonnet::put('environment',{'clickers' => $newclickers});
                    713:         if ($putres eq 'ok') {
                    714:             my @adds = ();
                    715:             my @dels = ();
                    716:             foreach my $item (@differences) {
                    717:                 if (grep(/^\Q$item\E$/,@newclickers)) {
                    718:                     push(@adds,$item);
                    719:                 } else {
                    720:                     push(@dels,$item);
                    721:                 }
                    722:             }
                    723:             if (@dels) {
                    724:                  my %delclicker;
                    725:                  map { $delclicker{$_} = $user; } @dels;
                    726:                  my $putresult = &Apache::lonnet::iddel($domain,\%delclicker,$uhome,'clickers');
                    727:             }
                    728:             if (@adds) {
                    729:                  my %addclicker;
                    730:                  map { $addclicker{$_} = $user; } @adds;
                    731:                  my $putresult = &Apache::lonnet::updateclickers($domain,'add',\%addclicker,$uhome,1);
                    732:             }
                    733:             &Apache::lonnet::appenv({'environment.clickers' => $newclickers});
                    734:             $message=&Apache::lonhtmlcommon::confirm_success(&mt('Registering clickers: [_1]',$newclickers));
                    735:         } else {
                    736:             $message=&Apache::lonhtmlcommon::confirm_success(&mt('Error saving clicker ID').1);
                    737:         }
                    738:     } else {
                    739:         $message='<span class="LC_info">'.&mt('Clicker information unchanged').'</span>';
                    740:     }
1.158     bisitz    741:     $message=&Apache::loncommon::confirmwrapper($message);
                    742:     &print_main_menu($r, $message);
1.105     www       743: }
                    744: 
1.119     www       745: ################################################################
                    746: #               Domcoord Access Subroutines                    #
                    747: ################################################################
                    748: 
                    749: sub domcoordchanger {
                    750:     my $r = shift;
1.154     www       751:     &Apache::lonhtmlcommon::add_breadcrumb(
1.126     droeschl  752: 	    {	href => '/adm/preferences?action=changedomcoord',
                    753:                 text => 'Restrict Domain Coordinator Access'});
                    754:     $r->print(Apache::loncommon::start_page('Restrict Domain Coordinator Access'));
                    755:     $r->print(Apache::lonhtmlcommon::breadcrumbs('Restrict Domain Coordinator Access'));
1.119     www       756:     my $user       = $env{'user.name'};
                    757:     my $domain     = $env{'user.domain'};
                    758:     my %userenv = &Apache::lonnet::get
1.120     www       759:         ('environment',['domcoord.author']);
1.119     www       760:     my $constchecked='';
                    761:     if ($userenv{'domcoord.author'} eq 'blocked') {
1.159     bisitz    762:        $constchecked=' checked="checked"';
1.119     www       763:     }
1.205     bisitz    764:     my $text=&mt('By default, the Domain Coordinator can enter your Authoring Space.');
                    765:     my $construction=&mt('Block access to Authoring Space');
1.136     schafran  766:     my $change=&mt('Save');
1.225     raeburn   767:     my $returnurl = &HTML::Entities::encode($env{'form.returnurl'},'"<>&\'');
1.119     www       768:     $r->print(<<ENDSCREEN);
                    769: <form name="prefs" action="/adm/preferences" method="post">
1.225     raeburn   770: <input type="hidden" name="returnurl" value="$returnurl" />
1.119     www       771: <input type="hidden" name="action" value="verify_and_change_domcoord" />
                    772: $text<br />
1.159     bisitz    773: <label><input type="checkbox" name="construction"$constchecked />$construction</label><br />
1.119     www       774: <input type="submit" value="$change" />
                    775: </form>
                    776: ENDSCREEN
                    777: }
                    778: 
                    779: sub verify_and_change_domcoord {
                    780:     my $r = shift;
                    781:     my $user       = $env{'user.name'};
                    782:     my $domain     = $env{'user.domain'};
1.120     www       783:     my %domcoord=('domcoord.author' => '');
1.119     www       784:     if ($env{'form.construction'}) { $domcoord{'domcoord.author'}='blocked'; }
                    785:     &Apache::lonnet::put('environment',\%domcoord);
1.120     www       786:     &Apache::lonnet::appenv({'environment.domcoord.author' => $domcoord{'domcoord.author'}});
1.158     bisitz    787:     my $status='';
                    788:     if ($domcoord{'domcoord.author'} eq 'blocked') {
                    789:         $status=&mt('on');
                    790:     } else {
                    791:         $status=&mt('off');
                    792:     }
1.205     bisitz    793:     my $message=&Apache::lonhtmlcommon::confirm_success(&mt('Set [_1] to [_2]','<i>'.&mt('Block access to Authoring Space').'</i>','<tt>'.$status.'</tt>'));
1.158     bisitz    794:     $message=&Apache::loncommon::confirmwrapper($message);
1.225     raeburn   795:     if ($env{'form.returnurl'}) {
                    796:         &do_redirect($r,$env{'form.returnurl'},$message);
                    797:     } else {
                    798:         &print_main_menu($r,$message);
                    799:     }
1.119     www       800: }
                    801: 
1.118     www       802: #################################################################
                    803: ##                      Lock Subroutines                        #
                    804: #################################################################
                    805: 
                    806: sub lockwarning {
                    807:     my $r = shift;
                    808:     my $title=&mt('Action locked');
                    809:     my $texttop=&mt('LON-CAPA is currently performing the following actions:');
                    810:     my $textbottom=&mt('Changing roles or logging out may result in data corruption.');
                    811:     my ($num,%which)=&Apache::lonnet::get_locks();
                    812:     my $which='';
1.214     raeburn   813:     foreach my $id (keys(%which)) {
1.118     www       814:        $which.='<li>'.$which{$id}.'</li>';
                    815:     }
                    816:     my $change=&mt('Override');
                    817:     $r->print(<<ENDSCREEN);
                    818: <form name="prefs" action="/adm/preferences" method="post">
                    819: <input type="hidden" name="action" value="verify_and_change_locks" />
                    820: <h1>$title</h1>
                    821: $texttop
                    822: <ul>
                    823: $which
                    824: </ul>
                    825: $textbottom
                    826: <input type="submit" value="$change" />
                    827: </form>
                    828: ENDSCREEN
                    829: }
                    830: 
                    831: sub verify_and_change_lockwarning {
                    832:     my $r = shift;
                    833:     &Apache::lonnet::remove_all_locks();
                    834:     $r->print(&mt('Cleared locks.'));
                    835: }
                    836: 
                    837: 
1.105     www       838: ################################################################
1.20      www       839: #         Message Forward                                      #
                    840: ################################################################
                    841: 
                    842: sub msgforwardchanger {
1.102     raeburn   843:     my ($r,$message) = @_;
1.59      albertel  844:     my $user       = $env{'user.name'};
                    845:     my $domain     = $env{'user.domain'};
1.102     raeburn   846:     my %userenv = &Apache::lonnet::get('environment',['msgforward','notification','critnotification','notifywithhtml']);
1.20      www       847:     my $msgforward=$userenv{'msgforward'};
1.102     raeburn   848:     my %lt = &Apache::lonlocal::texthash(
                    849:                                           all   => 'All',
                    850:                                           crit  => 'Critical only',
                    851:                                           reg   => 'Non-critical only',
1.175     raeburn   852:                                           foad  => 'Forward to account(s)',
                    853:                                           fwdm  => 'Forward messages to other account(s) in LON-CAPA',
                    854:                                           noti  => 'E-mail notification of LON-CAPA messages',
                    855:                                           mnot  => 'E-mail address(es) which should be notified about new LON-CAPA messages',
1.136     schafran  856:                                           chg   => 'Save',
1.104     raeburn   857:                                           email => 'The e-mail address entered in row ',
1.102     raeburn   858:                                           notv => 'is not a valid e-mail address',
1.103     raeburn   859:                                           toen => "To enter multiple addresses, enter one address at a time, click 'Change' and then add the next one", 
1.136     schafran  860:                                           prme => 'Back',
1.248   ! raeburn   861:                                           acti => 'Action',
        !           862:                                           type => 'Types of message for which notification is sent',
        !           863:                                           nota => 'Notification address',
        !           864:                                           exce => 'Excerpt retains HTML tags in message',
        !           865:                                           modi => 'Modify',
        !           866:                                           dele => 'Delete',
        !           867:                                           addn => 'Add new address',
        !           868:                                           yes  => 'Yes',
        !           869:                                           no   => 'No',
1.102     raeburn   870:                                         );
1.208     bisitz    871:     $lt{'foad_exmpl'} = &mt('e.g. [_1]userA:domain1,userB:domain2,...[_2]','<tt>','</tt>');
                    872:     $lt{'mnot_exmpl'} = &mt('e.g. [_1]joe@doe.com[_2]','<tt>','</tt>');
1.126     droeschl  873:     Apache::lonhtmlcommon::add_breadcrumb(
                    874: 	    {	href => '/adm/preferences?action=changemsgforward',
1.248   ! raeburn   875: 		text => 'Messages &amp; Notifications'});
1.178     bisitz    876:     $r->print(Apache::loncommon::start_page('Messages &amp; Notifications'));
1.248   ! raeburn   877:     $r->print(Apache::lonhtmlcommon::breadcrumbs('Messages &amp; Notifications').
        !           878:               '<div class="LC_landmark" role="main">');
1.113     raeburn   879:     my $forwardingHelp = &Apache::loncommon::help_open_topic("Prefs_Forwarding");
                    880:     my $notificationHelp = &Apache::loncommon::help_open_topic("Prefs_Notification");
                    881:     my $criticalMessageHelp = &Apache::loncommon::help_open_topic("Course_Critical_Message");
1.102     raeburn   882:     my @allow_html = split(/,/,$userenv{'notifywithhtml'});
                    883:     my %allnot = &get_notifications(\%userenv);
                    884:     my $validatescript = &Apache::lonhtmlcommon::javascript_valid_email();
                    885:     my $jscript = qq|
1.148     bisitz    886: <script type="text/javascript" language="JavaScript">
1.246     raeburn   887: // <![CDATA[
1.102     raeburn   888: function validate() {
                    889:     for (var i=0; i<document.prefs.numnotify.value; i++) {
1.104     raeburn   890:         var checkaddress = 0;
1.102     raeburn   891:         var addr = document.prefs.elements['address_'+i].value;
1.104     raeburn   892:         var rownum = i+1;
1.102     raeburn   893:         if (i < document.prefs.numnotify.value-1) {
1.104     raeburn   894:             if (document.prefs.elements['modify_notify_'+i].checked) {
1.102     raeburn   895:                 checkaddress = 1;
1.104     raeburn   896:             }
1.102     raeburn   897:         } else {
                    898:             if (document.prefs.elements['add_notify_'+i].checked == true) { 
                    899:                 checkaddress = 1;
                    900:             }
                    901:         }
1.104     raeburn   902:         if (checkaddress == 1)  {
1.102     raeburn   903:             var addr = document.prefs.elements['address_'+i].value;
                    904:             if (validmail(document.prefs.elements['address_'+i]) == false) {
1.104     raeburn   905:                 var multimsg = '';
                    906:                 if (addr.indexOf(",") >= 0) {
                    907:                     multimsg = "\\n($lt{'toen'}).";
                    908:                 }
1.110     bisitz    909:                 alert("$lt{'email'} "+rownum+" ('"+addr+"') $lt{'notv'}."+multimsg);
1.102     raeburn   910:                 return;
                    911:             }
                    912:         }
                    913:     }
                    914:     document.prefs.submit();
                    915: }
1.104     raeburn   916: 
                    917: function address_changes (adnum) {
                    918:      if (!document.prefs.elements['del_notify_'+adnum].checked) { 
                    919:          document.prefs.elements['modify_notify_'+adnum].checked = true;
                    920:      }   
                    921: }
                    922: 
                    923: function new_address(adnum) {
                    924:      document.prefs.elements['add_notify_'+adnum].checked = true;
                    925: }
                    926: 
                    927: function delete_address(adnum) {
                    928:      if (document.prefs.elements['del_notify_'+adnum].checked) {
                    929:           document.prefs.elements['modify_notify_'+adnum].checked = false;
                    930:      }
                    931: }
                    932: 
                    933: function modify_address(adnum) {
                    934:     if (document.prefs.elements['modify_notify_'+adnum].checked) {
                    935:         document.prefs.elements['del_notify_'+adnum].checked = false;
                    936:     }
                    937: } 
                    938: 
1.102     raeburn   939: $validatescript
1.246     raeburn   940: 
                    941: // ]]>
1.102     raeburn   942: </script>
                    943: |;
1.20      www       944:     $r->print(<<ENDMSG);
1.102     raeburn   945: $jscript
                    946: $message
1.248   ! raeburn   947: <h2 class="LC_heading_2">$lt{'fwdm'} $forwardingHelp</h2>
1.88      albertel  948: <form name="prefs" action="/adm/preferences" method="post">
1.20      www       949: <input type="hidden" name="action" value="verify_and_change_msgforward" />
1.248   ! raeburn   950: <label for="msgforward">$lt{'foad'}</label> ($lt{'foad_exmpl'}):
        !           951: <input type="text" size="40" value="$msgforward" name="msgforward" id="msgforward" />
        !           952: <p />
        !           953: <h2 class="LC_heading_2">$lt{'noti'} $notificationHelp</h2>
        !           954: <span id="LC_email_notify">$lt{'mnot'}</span> ($lt{'mnot_exmpl'}):<br />
1.102     raeburn   955: ENDMSG
1.248   ! raeburn   956:     my @sortnotify = sort (keys(%allnot));
1.102     raeburn   957:     my $output = &Apache::loncommon::start_data_table().
                    958:                  &Apache::loncommon::start_data_table_header_row().
1.248   ! raeburn   959:                  '<th>#</th>'.
        !           960:                  '<th>'.$lt{'acti'}.'</th>'.
        !           961:                  '<th>'.$lt{'nota'}.'</th><th>'.
        !           962:                  $lt{'type'}.
1.113     raeburn   963:                  $criticalMessageHelp.'</th><th>'.
1.248   ! raeburn   964:                  $lt{'exce'}.'</th>'.
1.102     raeburn   965:                  &Apache::loncommon::end_data_table_header_row();
                    966:     my $num = 0;
1.104     raeburn   967:     my $counter = 1;
1.248   ! raeburn   968:     foreach my $item (@sortnotify) {
        !           969:         $output .= &Apache::loncommon::start_data_table_row('LC_prefs_row').
1.104     raeburn   970:                    '<td><b>'.$counter.'</b></td>'.
                    971:                    '<td><span class="LC_nobreak"><label>'.
                    972:                    '<input type="checkbox" name="modify_notify_'.
                    973:                    $num.'" onclick="javscript:modify_address('."'$num'".')" />'.
1.248   ! raeburn   974:                    $lt{'modi'}.'</label></span> '.('&nbsp;' x2).
1.104     raeburn   975:                    '<span class="LC_nobreak"><label>'.
                    976:                    '<input type="checkbox" name="del_notify_'.$num.
                    977:                    '" onclick="javscript:delete_address('."'$num'".')" />'.
1.248   ! raeburn   978:                    $lt{'dele'}.'</label></span></td>'.
        !           979:                    '<td><span style="padding: 10px;"><input type="text" value="'.$item.'" name="address_'.
1.206     bisitz    980:                    $num.'" onfocus="javascript:address_changes('."'$num'".
1.248   ! raeburn   981:                    ')" aria-labelledby="LC_email_notify" /></span></td><td>';
1.102     raeburn   982:         my %chk;
                    983:         if (defined($allnot{$item}{'crit'})) {
                    984:             if (defined($allnot{$item}{'reg'})) {
                    985:                 $chk{'all'} = 'checked="checked" ';
                    986:             } else {
                    987:                 $chk{'crit'} = 'checked="checked" ';
                    988:             }
                    989:         } else {
                    990:             $chk{'reg'} = 'checked="checked" ';
                    991:         }
1.248   ! raeburn   992:         $output .= '<fieldset class="LC_landmark" style="display:inline"><legend class="LC_visually_hidden">'.$lt{'type'}.'</legend>';
1.102     raeburn   993:         foreach my $type ('all','crit','reg') {
                    994:             $output .= '<span class="LC_nobreak"><label>'.
                    995:                        '<input type="radio" name="notify_type_'.$num. 
1.104     raeburn   996:                        '" value="'.$type.'" '.$chk{$type}.
                    997:                        ' onchange="javascript:address_changes('."'$num'".')" />'.
1.248   ! raeburn   998:                        $lt{$type}.'</label></span> '.('&nbsp;' x2);
1.102     raeburn   999:         }
1.248   ! raeburn  1000:         $output .= '</fieldset>';
1.102     raeburn  1001:         my $htmlon = '';
                   1002:         my $htmloff = '';
                   1003:         if (grep/^\Q$item\E/,@allow_html) {
                   1004:             $htmlon = 'checked="checked" '; 
                   1005:         } else {
                   1006:             $htmloff = 'checked="checked" ';
                   1007:         }
1.248   ! raeburn  1008:         $output .= '</td><td>'.
        !          1009:                    '<fieldset class="LC_landmark" style="display:inline"><legend class="LC_visually_hidden">'.$lt{'exce'}.'</legend>'.
        !          1010:                    '<label><input type="radio" name="html_'.$num.
1.104     raeburn  1011:                    '" value="1" '.$htmlon.
                   1012:                    ' onchange="javascript:address_changes('."'$num'".')" />'.
1.248   ! raeburn  1013:                    $lt{'yes'}.'</label> '.('&nbsp;' x2).
1.102     raeburn  1014:                    '<label><input type="radio" name="html_'.$num.'" value="0" '.
1.104     raeburn  1015:                    $htmloff. ' onchange="javascript:address_changes('."'$num'".
                   1016: ')" />'.
1.248   ! raeburn  1017:                    $lt{'no'}.'</label></fieldset></td>'.
1.102     raeburn  1018:                    &Apache::loncommon::end_data_table_row();
                   1019:         $num ++;
1.104     raeburn  1020:         $counter ++;
1.102     raeburn  1021:     }
                   1022:     my %defchk = (
                   1023:                    all => 'checked="checked" ',
                   1024:                    crit => '',
                   1025:                    reg => '',
                   1026:                  );
1.248   ! raeburn  1027:     $output .= &Apache::loncommon::start_data_table_row('LC_prefs_row').
1.104     raeburn  1028:                '<td><b>'.$counter.'</b></td>'.
                   1029:                '<td><span class="LC_nobreak"><label>'.
                   1030:                '<input type="checkbox" name="add_notify_'.$num.
1.248   ! raeburn  1031:                '" value="1" />'.$lt{'addn'}.'</label></span></td>'.
        !          1032:                '<td><span style="padding: 10px;"><input type="text" value="" name="address_'.$num.
        !          1033:                '" onfocus="javascript:new_address('."'$num'".')" aria-labelledby="LC_email_notify" /></span></td><td>';
        !          1034:     $output .= '<fieldset class="LC_landmark" style="display:inline"><legend class="LC_visually_hidden">'.$lt{'type'}.'</legend>';
1.102     raeburn  1035:     foreach my $type ('all','crit','reg') {
                   1036:         $output .= '<span class="LC_nobreak"><label>'.
                   1037:                    '<input type="radio" name="notify_type_'.$num.
                   1038:                    '" value="'.$type.'" '.$defchk{$type}.'/>'.
1.248   ! raeburn  1039:                    $lt{$type}.'</label></span> '.('&nbsp;' x2);
1.102     raeburn  1040:     }
1.248   ! raeburn  1041:     $output .= '</fieldset></td><td>'.
        !          1042:                '<fieldset class="LC_landmark" style="display:inline"><legend class="LC_visually_hidden">'.$lt{'exce'}.'</legend>'.
        !          1043:                '<label><input type="radio" name="html_'.$num.
        !          1044:                '" value="1" />'.$lt{'yes'}.'</label> '.('&nbsp;' x2).
1.102     raeburn  1045:                '<label><input type="radio" name="html_'.$num.'" value="0" '.
                   1046:                ' checked="checked" />'.
1.248   ! raeburn  1047:                $lt{'no'}.'</label></fieldset></td>'.
1.102     raeburn  1048:                &Apache::loncommon::end_data_table_row().
                   1049:                &Apache::loncommon::end_data_table();
                   1050:     $num ++;
                   1051:     $r->print($output);
                   1052:     $r->print(qq|
1.113     raeburn  1053: <br /><hr />
1.102     raeburn  1054: <input type="hidden" name="numnotify" value="$num" />
1.136     schafran 1055: <input type="button" value="$lt{'prme'}" onclick="location.href='/adm/preferences'" />
1.102     raeburn  1056: <input type="button" value="$lt{'chg'}" onclick="javascript:validate()" />
1.248   ! raeburn  1057: </form></div>
1.102     raeburn  1058: |);
                   1059: 
                   1060: }
                   1061: 
                   1062: sub get_notifications {
                   1063:     my ($userenv) = @_;
                   1064:     my %allnot;
                   1065:     my @critnot = split(/,/,$userenv->{'critnotification'});
                   1066:     my @regnot = split(/,/,$userenv->{'notification'});
                   1067:     foreach my $item (@critnot) {
                   1068:         $allnot{$item}{crit} = 1;
                   1069:     }
                   1070:     foreach my $item (@regnot) {
                   1071:         $allnot{$item}{reg} = 1;
                   1072:     }
                   1073:     return %allnot;
1.20      www      1074: }
                   1075: 
                   1076: sub verify_and_change_msgforward {
                   1077:     my $r = shift;
1.59      albertel 1078:     my $user       = $env{'user.name'};
                   1079:     my $domain     = $env{'user.domain'};
1.20      www      1080:     my $newscreen  = '';
                   1081:     my $message='';
1.182     raeburn  1082:     foreach my $recip (split(/\,/,$env{'form.msgforward'})) {
                   1083:         my ($msuser,$msdomain);
                   1084:         if ($recip =~ /:/) {
                   1085:             ($msuser,$msdomain)=split(':',$recip);
                   1086:         } else {
                   1087:             ($msuser,$msdomain)=split(/\@/,$recip);
                   1088:         }
1.95      albertel 1089:         $msuser = &LONCAPA::clean_username($msuser);
                   1090:         $msdomain = &LONCAPA::clean_domain($msdomain);
1.20      www      1091:         if (($msuser) && ($msdomain)) {
                   1092: 	    if (&Apache::lonnet::homeserver($msuser,$msdomain) ne 'no_host') {
1.182     raeburn  1093:                 $newscreen.=$msuser.':'.$msdomain.',';
                   1094: 	    } else {
                   1095:                 $message.= &mt('No such user: ').'<tt>'.$msuser.':'.$msdomain.'</tt><br />';
                   1096:             }
1.20      www      1097:         }
                   1098:     }
                   1099:     $newscreen=~s/\,$//;
                   1100:     if ($newscreen) {
                   1101:         &Apache::lonnet::put('environment',{'msgforward' => $newscreen});
1.116     raeburn  1102:         &Apache::lonnet::appenv({'environment.msgforward' => $newscreen});
1.180     wenzelju 1103:         $message .= &Apache::lonhtmlcommon::confirm_success(&mt('Set message forwarding to ').'<tt>"'.$newscreen.'"</tt>.<br />');
1.20      www      1104:     } else {
                   1105:         &Apache::lonnet::del('environment',['msgforward']);
1.139     raeburn  1106:         &Apache::lonnet::delenv('environment.msgforward');
1.180     wenzelju 1107:         $message.= &Apache::lonhtmlcommon::confirm_success(&mt("Set message forwarding to 'off'.").'<br />');
1.20      www      1108:     }
1.102     raeburn  1109:     my $critnotification;
                   1110:     my $notification;
                   1111:     my $notify_with_html;
                   1112:     my $lastnotify = $env{'form.numnotify'}-1;
1.104     raeburn  1113:     my $totaladdresses = 0;
1.102     raeburn  1114:     for (my $i=0; $i<$env{'form.numnotify'}; $i++) {
                   1115:         if ((!defined($env{'form.del_notify_'.$i})) &&  
1.104     raeburn  1116:            ((($i==$lastnotify) && ($env{'form.add_notify_'.$lastnotify} == 1)) ||
1.102     raeburn  1117:             ($i<$lastnotify))) {
                   1118:             if (defined($env{'form.address_'.$i})) {
                   1119:                 if ($env{'form.notify_type_'.$i} eq 'all') {
                   1120:                     $critnotification .= $env{'form.address_'.$i}.',';
                   1121:                     $notification .= $env{'form.address_'.$i}.',';
                   1122:                 } elsif ($env{'form.notify_type_'.$i} eq 'crit') {
                   1123:                     $critnotification .= $env{'form.address_'.$i}.',';
                   1124:                 } elsif ($env{'form.notify_type_'.$i} eq 'reg') {
                   1125:                     $notification .= $env{'form.address_'.$i}.','; 
                   1126:                 }
                   1127:                 if ($env{'form.html_'.$i} eq '1') {
                   1128: 		    $notify_with_html .= $env{'form.address_'.$i}.',';       	
                   1129:                 }
1.104     raeburn  1130:                 $totaladdresses ++;
1.102     raeburn  1131:             }
                   1132:         }
                   1133:     }
                   1134:     $critnotification =~ s/,$//;
                   1135:     $critnotification=~s/\s//gs;
                   1136:     $notification =~ s/,$//;
1.20      www      1137:     $notification=~s/\s//gs;
1.102     raeburn  1138:     $notify_with_html =~ s/,$//;
                   1139:     $notify_with_html =~ s/\s//gs;
1.20      www      1140:     if ($notification) {
                   1141:         &Apache::lonnet::put('environment',{'notification' => $notification});
1.116     raeburn  1142:         &Apache::lonnet::appenv({'environment.notification' => $notification});
1.180     wenzelju 1143:         $message.=&Apache::lonhtmlcommon::confirm_success(&mt('Set non-critical message notification address(es) to ').'<tt>"'.$notification.'"</tt>.<br />');
1.20      www      1144:     } else {
                   1145:         &Apache::lonnet::del('environment',['notification']);
1.139     raeburn  1146:         &Apache::lonnet::delenv('environment.notification');
1.180     wenzelju 1147:         $message.=&Apache::lonhtmlcommon::confirm_success(&mt("Set non-critical message notification to 'off'.").'<br />');
1.20      www      1148:     }
                   1149:     if ($critnotification) {
                   1150:         &Apache::lonnet::put('environment',{'critnotification' => $critnotification});
1.116     raeburn  1151:         &Apache::lonnet::appenv({'environment.critnotification' => $critnotification});
1.180     wenzelju 1152:         $message.=&Apache::lonhtmlcommon::confirm_success(&mt('Set critical message notification address(es) to ').'<tt>"'.$critnotification.'"</tt>.<br />');
1.20      www      1153:     } else {
                   1154:         &Apache::lonnet::del('environment',['critnotification']);
1.139     raeburn  1155:         &Apache::lonnet::delenv('environment.critnotification');
1.180     wenzelju 1156:         $message.=&Apache::lonhtmlcommon::confirm_success(&mt("Set critical message notification to 'off'.").'<br />');
1.102     raeburn  1157:     }
                   1158:     if ($critnotification || $notification) {
                   1159:         if ($notify_with_html) {
                   1160:             &Apache::lonnet::put('environment',{'notifywithhtml' => $notify_with_html});
1.116     raeburn  1161:             &Apache::lonnet::appenv({'environment.notifywithhtml' => $notify_with_html});
1.180     wenzelju 1162:             $message.=&Apache::lonhtmlcommon::confirm_success(&mt('Set address(es) to receive excerpts with html retained ').'<tt>"'.$notify_with_html.'"</tt>.');
1.102     raeburn  1163:         } else {
                   1164:             &Apache::lonnet::del('environment',['notifywithhtml']);
1.139     raeburn  1165:             &Apache::lonnet::delenv('environment.notifywithhtml');
1.104     raeburn  1166:             if ($totaladdresses == 1) {
1.180     wenzelju 1167:                 $message.=&Apache::lonhtmlcommon::confirm_success(&mt("Set notification address to receive excerpts with html stripped."));
1.104     raeburn  1168:             } else {
1.180     wenzelju 1169:                 $message.=&Apache::lonhtmlcommon::confirm_success(&mt("Set all notification addresses to receive excerpts with html stripped."));
1.104     raeburn  1170:             }
1.102     raeburn  1171:         }
                   1172:     } else {
                   1173:         &Apache::lonnet::del('environment',['notifywithhtml']);
1.139     raeburn  1174:         &Apache::lonnet::delenv('environment.notifywithhtml');
1.102     raeburn  1175:     }
1.109     albertel 1176:     &Apache::loncommon::flush_email_cache($user,$domain);
1.180     wenzelju 1177:     $message=&Apache::loncommon::confirmwrapper($message);
1.102     raeburn  1178:     &msgforwardchanger($r,$message);
1.6       www      1179: }
                   1180: 
1.12      www      1181: ################################################################
1.19      www      1182: #         Colors                                               #
1.12      www      1183: ################################################################
                   1184: 
1.19      www      1185: sub colorschanger {
1.12      www      1186:     my $r = shift;
1.126     droeschl 1187:     Apache::lonhtmlcommon::add_breadcrumb(
                   1188: 	    {	href => '/adm/preferences?action=changecolors',
                   1189:                 text => 'Change Colors'});
1.147     schafran 1190:     $r->print(Apache::loncommon::start_page('Page Display Settings'));
1.248   ! raeburn  1191:     $r->print(Apache::lonhtmlcommon::breadcrumbs('Change Colors').
        !          1192:               '<div class="LC_landmark" role="main">');
1.19      www      1193: # figure out colors
1.80      albertel 1194:     my $function=&Apache::loncommon::get_users_function();
1.19      www      1195:     my $domain=&Apache::loncommon::determinedomain();
1.157     bisitz   1196:     my %colortypes=&Apache::lonlocal::texthash(
                   1197:         'pgbg'     => 'Page Background Color',
                   1198:         'tabbg'    => 'Header Background Color',
                   1199:         'sidebg'   => 'Header Border Color',
                   1200:         'font'     => 'Font Color',
                   1201:         'fontmenu' => 'Font Menu Color',
                   1202:         'link'     => 'Un-Visited Link Color',
                   1203:         'vlink'    => 'Visited Link Color',
                   1204:         'alink'    => 'Active Link Color',
                   1205:     );
1.248   ! raeburn  1206:     my $start_data_table = &Apache::loncommon::start_data_table().
        !          1207:                            &Apache::loncommon::data_table_caption(&mt('Colors for LON-CAPA pages')).
        !          1208:                            &Apache::loncommon::start_data_table_header_row().
        !          1209:                            '<th>'.&mt('Page Element').'</th><th>'.&mt('Color').'</th>'.
        !          1210:                            &Apache::loncommon::end_data_table_header_row();
1.19      www      1211:     my $chtable='';
1.22      matthew  1212:     foreach my $item (sort(keys(%colortypes))) {
1.19      www      1213:        my $curcol=&Apache::loncommon::designparm($function.'.'.$item,$domain);
1.82      albertel 1214:        $chtable.=&Apache::loncommon::start_data_table_row().
1.248   ! raeburn  1215: 	   '<td><label for="'.$item.'">'.$colortypes{$item}.'</label></td>'.
        !          1216: 	   '<td><input name="'.$item.
        !          1217:         '" class="colorchooser" id="'.$item.'" size="10" value="'.$curcol.
1.200     foxr     1218: '" /></td>'.
1.83      albertel 1219: 	    &Apache::loncommon::end_data_table_row()."\n";
1.19      www      1220:     }
1.82      albertel 1221:     my $end_data_table = &Apache::loncommon::end_data_table();
1.23      matthew  1222:     my $pjump_def = &Apache::lonhtmlcommon::pjump_javascript_definition();
1.157     bisitz   1223:     my $savebutton = &mt('Save');
                   1224:     my $resetbutton = &mt('Reset All');
                   1225:     my $resetbuttondesc = &mt('Reset All Colors to Default');
1.200     foxr     1226:     my $colorchooser=&Apache::lonhtmlcommon::color_picker();
1.202     raeburn  1227:     $r->print('<script type="text/javascript" language="JavaScript">
1.247     raeburn  1228: // <![CDATA[' ."\n". $colorchooser . "\n". '
1.246     raeburn  1229: // ]]>
1.200     foxr     1230: </script>
                   1231: ');
1.19      www      1232:     $r->print(<<ENDCOL);
                   1233: 
1.207     bisitz   1234: <form name="parmform" action="">
1.21      www      1235: <input type="hidden" name="pres_marker" />
                   1236: <input type="hidden" name="pres_type" />
                   1237: <input type="hidden" name="pres_value" />
                   1238: </form>
1.248   ! raeburn  1239: <br />
1.88      albertel 1240: <form name="prefs" action="/adm/preferences" method="post">
1.19      www      1241: <input type="hidden" name="action" value="verify_and_change_colors" />
1.82      albertel 1242: $start_data_table
1.19      www      1243: $chtable
1.82      albertel 1244: $end_data_table
1.19      www      1245: </table>
1.157     bisitz   1246: <p>
                   1247: <input type="submit" value="$savebutton" />
                   1248: <input type="submit" name="resetall" value="$resetbutton" title="$resetbuttondesc" />
                   1249: </p>
1.248   ! raeburn  1250: </form></div>
1.19      www      1251: ENDCOL
1.12      www      1252: }
                   1253: 
1.19      www      1254: sub verify_and_change_colors {
1.12      www      1255:     my $r = shift;
1.19      www      1256: # figure out colors
1.80      albertel 1257:     my $function=&Apache::loncommon::get_users_function();
1.19      www      1258:     my $domain=&Apache::loncommon::determinedomain();
1.157     bisitz   1259:     my %colortypes=&Apache::lonlocal::texthash(
                   1260:         'pgbg'     => 'Page Background Color',
                   1261:         'tabbg'    => 'Header Background Color',
                   1262:         'sidebg'   => 'Header Border Color',
                   1263:         'font'     => 'Font Color',
                   1264: 	'fontmenu' => 'Font Menu Color',
                   1265:         'link'     => 'Un-Visited Link Color',
                   1266:         'vlink'    => 'Visited Link Color',
                   1267:         'alink'    => 'Active Link Color',
                   1268:     );
1.19      www      1269: 
1.12      www      1270:     my $message='';
1.214     raeburn  1271:     foreach my $item (keys(%colortypes)) {
1.59      albertel 1272:         my $color=$env{'form.'.$item};
1.200     foxr     1273: 	if (!($color =~ /^#/)) {
                   1274: 	    $color = '#' . $color;
                   1275: 	}
1.21      www      1276:         my $entry='color.'.$function.'.'.$item;
1.59      albertel 1277: 	if (($color=~/^\#[0-9A-Fa-f]{6}$/) && (!$env{'form.resetall'})) {
1.21      www      1278: 	    &Apache::lonnet::put('environment',{$entry => $color});
1.116     raeburn  1279: 	    &Apache::lonnet::appenv({'environment.'.$entry => $color});
1.157     bisitz   1280:             $message.=&Apache::lonhtmlcommon::confirm_success(&mt('Set [_1] to [_2]','<i>'.$colortypes{$item}.'</i>','<tt>"'.$color.'"</tt>'))
                   1281:                     .'<br />';
1.21      www      1282: 	} else {
                   1283: 	    &Apache::lonnet::del('environment',[$entry]);
1.138     schafran 1284: 	    &Apache::lonnet::delenv('environment.'.$entry);
1.157     bisitz   1285:             $message.=&Apache::lonhtmlcommon::confirm_success(&mt('Reset [_1]','<i>'.$colortypes{$item}.'</i>'))
                   1286:                      .'<br />';
1.21      www      1287: 	}
                   1288:     }
1.158     bisitz   1289:     $message=&Apache::loncommon::confirmwrapper($message);
1.157     bisitz   1290: 
1.84      albertel 1291:     my $now = time;
                   1292:     &Apache::lonnet::put('environment',{'color.timestamp' => $now});
1.116     raeburn  1293:     &Apache::lonnet::appenv({'environment.color.timestamp' => $now});
1.84      albertel 1294: 
1.152     www      1295:     &print_main_menu($r, $message);
1.12      www      1296: }
                   1297: 
1.4       matthew  1298: ######################################################
                   1299: #            password handler subroutines            #
                   1300: ######################################################
1.3       matthew  1301: sub passwordchanger {
1.228     raeburn  1302:     my ($r,$errormessage,$caller,$mailtoken,$timelimit,$extrafields) = @_;
1.4       matthew  1303:     # This function is a bit of a mess....
1.3       matthew  1304:     # Passwords are encrypted using londes.js (DES encryption)
1.4       matthew  1305:     $errormessage = ($errormessage || '');
1.239     raeburn  1306:     my ($user,$domain,$currentpass,$clientip);
                   1307:     $clientip = &Apache::lonnet::get_requestor_ip($r);
1.152     www      1308:     &Apache::lonhtmlcommon::add_breadcrumb(
1.126     droeschl 1309: 		{ href => '/adm/preferences?action=changepass',
                   1310:                   text => 'Change Password'});
1.144     raeburn  1311:     unless ($caller eq 'reset_by_email') {
1.147     schafran 1312:         $r->print(Apache::loncommon::start_page('Personal Data'));
1.247     raeburn  1313:         $r->print(Apache::lonhtmlcommon::breadcrumbs('Change Password').
                   1314:                   '<div class="LC_landmark" role="main">');
1.144     raeburn  1315:     }
1.94      raeburn  1316:     if ((!defined($caller)) || ($caller eq 'preferences')) {
                   1317:         $user = $env{'user.name'};
                   1318:         $domain = $env{'user.domain'};
                   1319:         if (!defined($caller)) {
                   1320:             $caller = 'preferences';
                   1321:         }
1.236     raeburn  1322:         my ($blocked,$blocktext) =
1.239     raeburn  1323:             &Apache::loncommon::blocking_status('passwd',$clientip);
1.236     raeburn  1324:         if ($blocked) {
1.248   ! raeburn  1325:             $r->print('<p class="LC_warning">'.$blocktext.'</p></div>');
1.236     raeburn  1326:             return;
                   1327:         }
1.94      raeburn  1328:     } elsif ($caller eq 'reset_by_email') {
1.229     raeburn  1329:         my %data = &Apache::lonnet::tmpget($mailtoken);
                   1330:         if (keys(%data) == 0) {
                   1331:             $r->print(
                   1332:                 '<p class="LC_warning">'
                   1333:                .&mt('Sorry, the URL you provided to complete the reset of your password was invalid. Either the token included in the URL has been deleted or the URL you provided was invalid. Please submit a [_1]new request[_2] for a password reset, and follow the link to the new URL included in the e-mail that will be sent to you, to allow you to enter a new password.'
                   1334:                    ,'<a href="/adm/resetpw">','</a>')
                   1335:                .'</p>'
                   1336:             );
                   1337:             return;
                   1338:         }
                   1339:         if (defined($data{time})) {
                   1340:             if (time - $data{'time'} < $timelimit) {
                   1341:                 $user = $data{'username'};
                   1342:                 $domain = $data{'domain'};
                   1343:                 $currentpass = $data{'temppasswd'};
1.236     raeburn  1344:                 my ($blocked,$blocktext) =
1.239     raeburn  1345:                     &Apache::loncommon::blocking_status('passwd',$clientip,$user,$domain);
1.236     raeburn  1346:                 if ($blocked) {
                   1347:                     $r->print('<p class="LC_warning">'.$blocktext.'</p>');
                   1348:                     return;
                   1349:                 }
1.94      raeburn  1350:             } else {
1.199     bisitz   1351:                 $r->print(
                   1352:                     '<p class="LC_warning">'
1.229     raeburn  1353:                    .&mt('Sorry, the token generated when you requested'
                   1354:                        .' a password reset has expired.')
1.199     bisitz   1355:                    .'</p>'
                   1356:                 );
1.94      raeburn  1357:                 return;
                   1358:             }
1.231     raeburn  1359:         } else {
1.229     raeburn  1360:             $r->print(
                   1361:                 '<p class="LC_warning">'
                   1362:                .&mt('Sorry, the URL generated when you requested reset of'
                   1363:                    .' your password contained incomplete information.')
                   1364:                .'</p>'
                   1365:             );
                   1366:             return;
                   1367:         }
                   1368:         if (&Apache::lonnet::domain($domain) eq '') {
                   1369:             $domain = $r->dir_config('lonDefDomain');
                   1370:         }
1.193     raeburn  1371:     } else {
1.199     bisitz   1372:         $r->print(
                   1373:             '<p class="LC_error">'
                   1374:            .&mt('Page requested in unexpected context')
1.248   ! raeburn  1375:            .'</p></div>'
1.199     bisitz   1376:         );
1.94      raeburn  1377:         return;
                   1378:     }
1.3       matthew  1379:     my $currentauth=&Apache::lonnet::queryauthenticate($user,$domain);
                   1380:     # Check for authentication types that allow changing of the password.
1.248   ! raeburn  1381:     if ($currentauth !~ /^(unix|internal):/) {
        !          1382:         unless ($caller eq 'reset_by_email') {
        !          1383:             $r->print('</div>');
        !          1384:         }
        !          1385:         return;
        !          1386:     }
1.3       matthew  1387:     #
                   1388:     # Generate keys
1.212     raeburn  1389:     my ($lkey_cpass ,$ukey_cpass ) = &Apache::loncommon::des_keys();
                   1390:     my ($lkey_npass1,$ukey_npass1) = &Apache::loncommon::des_keys();
                   1391:     my ($lkey_npass2,$ukey_npass2) = &Apache::loncommon::des_keys();
1.4       matthew  1392:     # Store the keys in the log files
1.3       matthew  1393:     my $lonhost = $r->dir_config('lonHostID');
                   1394:     my $logtoken=Apache::lonnet::reply('tmpput:'
                   1395: 				       .$ukey_cpass  . $lkey_cpass .'&'
                   1396: 				       .$ukey_npass1 . $lkey_npass1.'&'
                   1397: 				       .$ukey_npass2 . $lkey_npass2,
                   1398: 				       $lonhost);
1.4       matthew  1399:     # Hexify the keys for output as javascript variables
1.94      raeburn  1400:     my %hexkey;
                   1401:     $hexkey{'ukey_cpass'}  = hex($ukey_cpass);
                   1402:     $hexkey{'lkey_cpass'}  = hex($lkey_cpass);
                   1403:     $hexkey{'ukey_npass1'} = hex($ukey_npass1);
                   1404:     $hexkey{'lkey_npass1'} = hex($lkey_npass1);
                   1405:     $hexkey{'ukey_npass2'} = hex($ukey_npass2);
                   1406:     $hexkey{'lkey_npass2'} = hex($lkey_npass2);
1.3       matthew  1407:     # Output javascript to deal with passwords
1.4       matthew  1408:     # Output DES javascript
1.3       matthew  1409:     {
                   1410: 	my $include = $r->dir_config('lonIncludes');
                   1411: 	my $jsh=Apache::File->new($include."/londes.js");
                   1412: 	$r->print(<$jsh>);
                   1413:     }
1.236     raeburn  1414:     $r->print(&jscript_send($caller,$domain,$currentauth,$extrafields));
1.3       matthew  1415:     $r->print(<<ENDFORM);
1.94      raeburn  1416: $errormessage
                   1417: 
1.247     raeburn  1418: <p></p>
1.94      raeburn  1419: <!-- We separate the forms into 'server' and 'client' in order to
                   1420:      ensure that unencrypted passwords will not be sent out by a
                   1421:      crappy browser -->
                   1422: ENDFORM
1.228     raeburn  1423:     $r->print(&server_form($logtoken,$caller,$mailtoken,$extrafields));
                   1424:     $r->print(&client_form($caller,\%hexkey,$currentpass,$domain,$extrafields));
1.248   ! raeburn  1425:     unless ($caller eq 'reset_by_email') {
        !          1426:         $r->print('</div>');
        !          1427:     }
1.94      raeburn  1428:     #
                   1429:     return;
                   1430: }
                   1431: 
                   1432: sub jscript_send {
1.236     raeburn  1433:     my ($caller,$domain,$currentauth,$extrafields) = @_;
                   1434:     my ($min,$max,$rulestr,$numrules);
                   1435:     $min = $Apache::lonnet::passwdmin;
                   1436:     my %js_lt = &Apache::lonlocal::texthash(
                   1437:               uc => 'New password needs at least one upper case letter',
                   1438:               lc => 'New password needs at least one lower case letter',
                   1439:               num => 'New password needs at least one number',
                   1440:               spec => 'New password needs at least one non-alphanumeric',
                   1441:               blank1 => 'Empty Password field',
                   1442:               blank2 => 'Empty Confirm Password field',
                   1443:               mismatch => 'Contents of Password and Confirm Password fields must match',
                   1444:               fail => 'Please fix the following:',
                   1445:     );
                   1446:     &js_escape(\%js_lt);
                   1447:     if ($currentauth eq 'internal:') {
                   1448:         if ($domain ne '') {
                   1449:             my %passwdconf = &Apache::lonnet::get_passwdconf($domain);
                   1450:             if (keys(%passwdconf)) {
                   1451:                 if ($passwdconf{min}) {
                   1452:                     $min = $passwdconf{min};
                   1453:                 }
                   1454:                 if ($passwdconf{max}) {
                   1455:                     $max = $passwdconf{max};
                   1456:                     $js_lt{'long'} = &js_escape(&mt('Maximum password length: [_1]',$max));
                   1457:                 }
                   1458:                 if (ref($passwdconf{chars}) eq 'ARRAY') {
                   1459:                     if (@{$passwdconf{chars}}) {
                   1460:                         $rulestr =  join('","',@{$passwdconf{chars}});
                   1461:                         $numrules = scalar(@{$passwdconf{chars}});
                   1462:                     }
                   1463:                 }
                   1464:             }
                   1465:         }
                   1466:     }
                   1467:     $js_lt{'short'} = &js_escape(&mt('Minimum password length: [_1]',$min));
                   1468: 
                   1469:     my $passwdcheck = <<"ENDJS";
                   1470:         var errors = new Array();
                   1471:         var min = parseInt("$min") || 0;
                   1472:         var currauth = "$currentauth";
                   1473:         if (this.document.client.elements.newpass_1.value == '') {
                   1474:             errors.push("$js_lt{'blank1'}");
                   1475:         }
                   1476:         if (this.document.client.elements.newpass_2.value == '') {
                   1477:             errors.push("$js_lt{'blank2'}");
                   1478:         }
                   1479:         if (errors.length == 0) {
                   1480:             if (this.document.client.elements.newpass_1.value !=  this.document.client.elements.newpass_2.value) {
                   1481:                 errors.push("$js_lt{'mismatch'}");
                   1482:             }
                   1483:             var posspass = this.document.client.elements.newpass_1.value;
                   1484:             if (min > 0) {
                   1485:                 if (posspass.length < min) {
                   1486:                     errors.push("$js_lt{'short'}");
                   1487:                 }
                   1488:             }
                   1489:             if (currauth == 'internal:') {
                   1490:                 var max = parseInt("$max") || 0;
                   1491:                 if (max > 0) {
                   1492:                     if (posspass.length > max) {
                   1493:                         errors.push("$js_lt{'long'}");
                   1494:                     }
                   1495:                 }
                   1496:                 var numrules = parseInt("$numrules") || 0;
                   1497:                 if (numrules > 0) {
                   1498:                     var rules = new Array("$rulestr");
                   1499:                     for (var i=0; i<rules.length; i++) {
                   1500:                         if (rules[i] == 'uc') {
                   1501:                             if (!posspass.match(/[A-Z]/)) {
                   1502:                                 errors.push("$js_lt{'uc'}");
                   1503:                             }
                   1504:                         } else if (rules[i] == 'lc') {
                   1505:                             if (!posspass.match(/[a-z]/)) {
                   1506:                                 errors.push("$js_lt{'lc'}");
                   1507:                             }
                   1508:                         } else if (rules[i] == 'num') {
                   1509:                             if (!posspass.match(/\\d/)) {
                   1510:                                 errors.push("$js_lt{'num'}");
                   1511:                             }
                   1512:                         } else if (rules[i] == 'spec') {
                   1513:                             var pattern = /^[!@#$%^&*()_+\\-=\\[\\]{};':"\\\|,.<a>\\/?]/;
                   1514:                             if (!posspass.match(pattern)) {
                   1515:                                 errors.push("$js_lt{'spec'}");
                   1516:                             }
                   1517:                         }
                   1518:                     }
                   1519:                 }
                   1520:             }
                   1521:         }
                   1522:         if (errors.length > 0) {
                   1523:             alert("$js_lt{'fail'}"+"\\n\\n"+errors.join("\\n"));
                   1524:             return;
                   1525:         }
                   1526: ENDJS
1.94      raeburn  1527:     my $output = qq|
1.148     bisitz   1528: <script type="text/javascript" language="JavaScript">
1.246     raeburn  1529: // <![CDATA[
1.3       matthew  1530:     function send() {
1.236     raeburn  1531: $passwdcheck
1.3       matthew  1532:         uextkey=this.document.client.elements.ukey_cpass.value;
                   1533:         lextkey=this.document.client.elements.lkey_cpass.value;
                   1534:         initkeys();
1.219     raeburn  1535:         this.document.pserver.elements.currentpass.value =
                   1536:             getCrypted(this.document.client.elements.currentpass.value);
1.3       matthew  1537:         uextkey=this.document.client.elements.ukey_npass1.value;
                   1538:         lextkey=this.document.client.elements.lkey_npass1.value;
                   1539:         initkeys();
1.52      raeburn  1540:         this.document.pserver.elements.newpass_1.value
1.219     raeburn  1541:             =getCrypted(this.document.client.elements.newpass_1.value);
1.3       matthew  1542:         uextkey=this.document.client.elements.ukey_npass2.value;
                   1543:         lextkey=this.document.client.elements.lkey_npass2.value;
                   1544:         initkeys();
1.52      raeburn  1545:         this.document.pserver.elements.newpass_2.value
1.219     raeburn  1546:             =getCrypted(this.document.client.elements.newpass_2.value);
1.94      raeburn  1547: |;
                   1548:     if ($caller eq 'reset_by_email') {
1.228     raeburn  1549:         if ((ref($extrafields) eq 'HASH') && ($extrafields->{'username'})) {
                   1550:             $output .= qq|
1.94      raeburn  1551:         this.document.pserver.elements.uname.value =
                   1552:                    this.document.client.elements.uname.value;
                   1553:         this.document.pserver.elements.udom.value =
                   1554:                    this.document.client.elements.udom.options[this.document.client.elements.udom.selectedIndex].value;
1.228     raeburn  1555: |;
                   1556:         }
                   1557:         if ((ref($extrafields) eq 'HASH') && ($extrafields->{'email'})) {
1.235     raeburn  1558:             $output .= qq|
1.173     raeburn  1559:         this.document.pserver.elements.email.value =
                   1560:                    this.document.client.elements.email.value;
1.94      raeburn  1561: |;
1.228     raeburn  1562:         }
1.94      raeburn  1563:     }
                   1564:     $ output .= qq|
1.52      raeburn  1565:         this.document.pserver.submit();
1.3       matthew  1566:     }
1.219     raeburn  1567: 
1.246     raeburn  1568: // ]]>
1.3       matthew  1569: </script>
1.94      raeburn  1570: |;
                   1571: }
1.3       matthew  1572: 
1.94      raeburn  1573: sub client_form {
1.228     raeburn  1574:     my ($caller,$hexkey,$currentpass,$defdom,$extrafields) = @_;
1.99      www      1575:     my %lt=&Apache::lonlocal::texthash(
1.115     raeburn  1576:                 'email' => 'E-mail Address',
1.99      www      1577:                 'username' => 'Username',
                   1578:                 'domain' => 'Domain',
                   1579:                 'currentpass' => 'Current Password',
                   1580:                 'newpass' => 'New Password',
                   1581:                 'confirmpass' => 'Confirm Password',
1.169     raeburn  1582:                 'changepass' => 'Save',
                   1583:     );
1.99      www      1584: 
1.207     bisitz   1585:     my $output = '<form name="client" action="">'
1.164     bisitz   1586:                 .&Apache::lonhtmlcommon::start_pick_box();
1.94      raeburn  1587:     if ($caller eq 'reset_by_email') {
1.228     raeburn  1588:         if ((ref($extrafields) eq 'HASH') && ($extrafields->{'email'})) {
                   1589:             $output .= &Apache::lonhtmlcommon::row_title(
                   1590:                        '<label for="email">'.$lt{'email'}.'</label>')
                   1591:                       .'<input type="text" name="email" size="30" autocapitalize="off" autocorrect="off" />'
                   1592:                       .&Apache::lonhtmlcommon::row_closure();
1.221     raeburn  1593:         }
1.228     raeburn  1594:         if ((ref($extrafields) eq 'HASH') && ($extrafields->{'username'})) {
1.235     raeburn  1595:             $output .= &Apache::lonhtmlcommon::row_title(
1.164     bisitz   1596:                        '<label for="uname">'.$lt{'username'}.'</label>')
1.228     raeburn  1597:                       .'<input type="text" name="uname" size="20" autocapitalize="off" autocorrect="off" />'
                   1598:                       .&Apache::lonhtmlcommon::row_closure()
                   1599:                       .&Apache::lonhtmlcommon::row_title(
1.164     bisitz   1600:                        '<label for="udom">'.$lt{'domain'}.'</label>')
1.228     raeburn  1601:                       .&Apache::loncommon::select_dom_form($defdom,'udom')
                   1602:                       .&Apache::lonhtmlcommon::row_closure();
                   1603:         }
1.94      raeburn  1604:     } else {
1.164     bisitz   1605:         $output .= &Apache::lonhtmlcommon::row_title(
                   1606:                        '<label for="currentpass">'.$lt{'currentpass'}.'</label>')
1.247     raeburn  1607:                   .'<input type="password" name="currentpass" id="currentpass" size="20" />'
1.164     bisitz   1608:                   .&Apache::lonhtmlcommon::row_closure();
                   1609:     }
                   1610:     $output .= &Apache::lonhtmlcommon::row_title(
                   1611:                    '<label for="newpass_1">'.$lt{'newpass'}.'</label>')
1.247     raeburn  1612:               .'<input type="password" name="newpass_1" id="newpass_1" size="20" />'
1.164     bisitz   1613:               .&Apache::lonhtmlcommon::row_closure()
                   1614:               .&Apache::lonhtmlcommon::row_title(
                   1615:                    '<label for="newpass_2">'.$lt{'confirmpass'}.'</label>')
1.247     raeburn  1616:               .'<input type="password" name="newpass_2" id="newpass_2" size="20" />'
1.164     bisitz   1617:               .&Apache::lonhtmlcommon::row_closure(1)
                   1618:               .&Apache::lonhtmlcommon::end_pick_box();
1.228     raeburn  1619:     if ($caller eq 'reset_by_email') {
                   1620:         $output .= '<input type="hidden" name="currentpass" value="'.$currentpass.'" />';
                   1621:     }
1.206     bisitz   1622:     $output .= '<p><input type="button" value="'.$lt{'changepass'}.'" onclick="send();" /></p>'
1.164     bisitz   1623:               .qq|
1.94      raeburn  1624: <input type="hidden" name="ukey_cpass"  value="$hexkey->{'ukey_cpass'}" />
                   1625: <input type="hidden" name="lkey_cpass"  value="$hexkey->{'lkey_cpass'}" />
                   1626: <input type="hidden" name="ukey_npass1" value="$hexkey->{'ukey_npass1'}" />
                   1627: <input type="hidden" name="lkey_npass1" value="$hexkey->{'lkey_npass1'}" />
                   1628: <input type="hidden" name="ukey_npass2" value="$hexkey->{'ukey_npass2'}" />
                   1629: <input type="hidden" name="lkey_npass2" value="$hexkey->{'lkey_npass2'}" />
1.3       matthew  1630: </form>
1.164     bisitz   1631: |;
1.94      raeburn  1632:     return $output;
                   1633: }
                   1634: 
                   1635: sub server_form {
1.228     raeburn  1636:     my ($logtoken,$caller,$mailtoken,$extrafields) = @_;
1.94      raeburn  1637:     my $action = '/adm/preferences';
                   1638:     if ($caller eq 'reset_by_email') {
                   1639:         $action = '/adm/resetpw';
                   1640:     }
                   1641:     my $output = qq|
                   1642: <form name="pserver" action="$action" method="post">
                   1643: <input type="hidden" name="logtoken"    value="$logtoken" />
                   1644: <input type="hidden" name="currentpass" value="" />
                   1645: <input type="hidden" name="newpass_1"   value="" />
                   1646: <input type="hidden" name="newpass_2"   value="" />
1.228     raeburn  1647: |;
1.94      raeburn  1648:     if ($caller eq 'reset_by_email') {
                   1649:         $output .=  qq|
                   1650: <input type="hidden" name="token"   value="$mailtoken" />
1.228     raeburn  1651: |;
                   1652:        if ((ref($extrafields) eq 'HASH') && ($extrafields->{'username'})) {
                   1653:            $output .=  qq|
1.94      raeburn  1654: <input type="hidden" name="uname"   value="" />
                   1655: <input type="hidden" name="udom"   value="" />
1.228     raeburn  1656: |;
                   1657:        }
                   1658:        if ((ref($extrafields) eq 'HASH') && ($extrafields->{'email'})) {
                   1659:            $output .=  qq|
1.173     raeburn  1660: <input type="hidden" name="email"   value="" />
1.94      raeburn  1661: |;
1.228     raeburn  1662:        }
1.94      raeburn  1663:     }
                   1664:     $output .= qq|
                   1665: <input type="hidden" name="action" value="verify_and_change_pass" />
                   1666: </form>
                   1667: |;
                   1668:     return $output;
1.3       matthew  1669: }
                   1670: 
                   1671: sub verify_and_change_password {
1.236     raeburn  1672:     my ($r,$caller,$mailtoken,$timelimit,$extrafields,$ended) = @_;
1.239     raeburn  1673:     my ($user,$domain,$homeserver,$clientip);
1.94      raeburn  1674:     if ($caller eq 'reset_by_email') {
                   1675:         $user       = $env{'form.uname'};
                   1676:         $domain     = $env{'form.udom'};
                   1677:         if ($user ne '' && $domain ne '') {
                   1678:             $homeserver = &Apache::lonnet::homeserver($user,$domain);
                   1679:             if ($homeserver eq 'no_host') {
1.99      www      1680:         &passwordchanger($r,"<p>\n<span class='LC_error'>".
                   1681:                          &mt("Invalid username and/or domain")."</span>\n</p>",
1.236     raeburn  1682:                          $caller,$mailtoken,$timelimit,$extrafields);
                   1683:                 return 'no_host';
1.94      raeburn  1684:             }
                   1685:         } else {
1.99      www      1686:             &passwordchanger($r,"<p>\n<span class='LC_error'>".
                   1687:                              &mt("Username and domain were blank")."</span>\n</p>",
1.236     raeburn  1688:                              $caller,$mailtoken,$timelimit,$extrafields);
                   1689:             return 'missingdata';
1.94      raeburn  1690:         }
                   1691:     } else {
                   1692:         $user       = $env{'user.name'};
                   1693:         $domain     = $env{'user.domain'};
                   1694:         $homeserver = $env{'user.home'};
                   1695:     }
1.239     raeburn  1696:     $clientip = &Apache::lonnet::get_requestor_ip($r);
1.236     raeburn  1697:     my ($blocked,$blocktext) =
1.239     raeburn  1698:         &Apache::loncommon::blocking_status('passwd',$clientip,$user,$domain);
1.236     raeburn  1699:     if ($blocked) {
                   1700:         $r->print('<p class="LC_warning">'.$blocktext.'</p>');
                   1701:         if ($caller eq 'reset_by_email') {
                   1702:             return 'blocked';
                   1703:         } else {
                   1704:             return;
                   1705:         }
                   1706:     }
1.3       matthew  1707:     my $currentauth=&Apache::lonnet::queryauthenticate($user,$domain);
1.4       matthew  1708:     # Check for authentication types that allow changing of the password.
1.94      raeburn  1709:     if ($currentauth !~ /^(unix|internal):/) {
                   1710:         if ($caller eq 'reset_by_email') {
1.99      www      1711:             &passwordchanger($r,"<p>\n<span class='LC_error'>".
                   1712:                              &mt("Authentication type for this user can not be changed by this mechanism").
                   1713:                              "</span>\n</p>",
1.236     raeburn  1714:                               $caller,$mailtoken,$timelimit,$extrafields);
                   1715:             return 'otherauth';
1.94      raeburn  1716:         } else {
                   1717:             return;
                   1718:         }
                   1719:     }
1.3       matthew  1720:     #
1.59      albertel 1721:     my $currentpass = $env{'form.currentpass'}; 
                   1722:     my $newpass1    = $env{'form.newpass_1'}; 
                   1723:     my $newpass2    = $env{'form.newpass_2'};
                   1724:     my $logtoken    = $env{'form.logtoken'};
1.3       matthew  1725:     # Check for empty data 
1.4       matthew  1726:     unless (defined($currentpass) && 
                   1727: 	    defined($newpass1)    && 
                   1728: 	    defined($newpass2)    ){
1.99      www      1729: 	&passwordchanger($r,"<p>\n<span class='LC_error'>".
                   1730: 			 &mt("One or more password fields were blank").
1.236     raeburn  1731:                          "</span>\n</p>",$caller,$mailtoken,$timelimit,$extrafields);
                   1732:         if ($caller eq 'reset_by_email') {
                   1733:             return 'missingdata';
                   1734:         } else {
                   1735:             return;
                   1736:         }
1.3       matthew  1737:     }
1.16      albertel 1738:     # Get the keys
                   1739:     my $lonhost = $r->dir_config('lonHostID');
1.3       matthew  1740:     my $tmpinfo = Apache::lonnet::reply('tmpget:'.$logtoken,$lonhost);
                   1741:     if (($tmpinfo=~/^error/) || ($tmpinfo eq 'con_lost')) {
1.4       matthew  1742:         # I do not a have a better idea about how to handle this
1.94      raeburn  1743:         my $tryagain_text = &mt('Please log out and try again.');
                   1744:         if ($caller eq 'reset_by_email') {
                   1745:             $tryagain_text = &mt('Please try again later.');
                   1746:         }
1.101     albertel 1747:         my $unable=&mt("Unable to retrieve saved token for password decryption");
1.3       matthew  1748: 	$r->print(<<ENDERROR);
                   1749: <p>
1.99      www      1750: <span class="LC_error">$unable.  $tryagain_text</span>
1.3       matthew  1751: </p>
                   1752: ENDERROR
1.4       matthew  1753:         # Probably should log an error here
1.236     raeburn  1754:         if ($caller eq 'reset_by_email') {
                   1755:             return 'internalerror';
                   1756:         } else {
                   1757:             return;
                   1758:         }
1.3       matthew  1759:     }
                   1760:     my ($ckey,$n1key,$n2key)=split(/&/,$tmpinfo);
1.219     raeburn  1761:     #
1.211     raeburn  1762:     $currentpass = &Apache::loncommon::des_decrypt($ckey ,$currentpass);
                   1763:     $newpass1    = &Apache::loncommon::des_decrypt($n1key,$newpass1);
                   1764:     $newpass2    = &Apache::loncommon::des_decrypt($n2key,$newpass2);
1.94      raeburn  1765:     #
                   1766:     if ($caller eq 'reset_by_email') {
                   1767:         my %data = &Apache::lonnet::tmpget($mailtoken);
1.117     raeburn  1768:         if (keys(%data) == 0) {
                   1769:             &passwordchanger($r,
                   1770:                          '<span class="LC_error">'.
                   1771:                          &mt('Could not verify current authentication.').'  '.
1.236     raeburn  1772:                          &mt('Please try again.').'</span>',$caller,$mailtoken,$timelimit,$extrafields);
                   1773:             return 'emptydata';
1.117     raeburn  1774:         }
1.94      raeburn  1775:         if ($currentpass ne $data{'temppasswd'}) {
                   1776:             &passwordchanger($r,
1.99      www      1777:                          '<span class="LC_error">'.
1.110     bisitz   1778:                          &mt('Could not verify current authentication.').'  '.
1.236     raeburn  1779:                          &mt('Please try again.').'</span>',$caller,$mailtoken,$timelimit,$extrafields);
                   1780:             return 'missingtemp';
1.94      raeburn  1781:         }
1.231     raeburn  1782:     }
1.3       matthew  1783:     if ($newpass1 ne $newpass2) {
1.4       matthew  1784: 	&passwordchanger($r,
1.199     bisitz   1785: 			 '<span class="LC_warning">'.
1.110     bisitz   1786: 			 &mt('The new passwords you entered do not match.').'  '.
1.236     raeburn  1787: 			 &mt('Please try again.').'</span>',$caller,$mailtoken,$timelimit,$extrafields);
                   1788:         if ($caller eq 'reset_by_email') {
                   1789:             return 'mismatch';
                   1790:         } else {
                   1791:             return;
                   1792:         }
1.4       matthew  1793:     }
1.231     raeburn  1794:     if ($currentauth eq 'unix:') {
                   1795:         if (length($newpass1) < 7) {
                   1796:             &passwordchanger($r,
                   1797:                              '<span class="LC_warning">'.
                   1798:                              &mt('Passwords must be a minimum of 7 characters long.').'  '.
1.236     raeburn  1799:                              &mt('Please try again.').'</span>',$caller,$mailtoken,$timelimit,$extrafields);
                   1800:             if ($caller eq 'reset_by_email') {
                   1801:                 return 'length';
                   1802:             } else {
                   1803:                 return;
                   1804:             }
1.231     raeburn  1805:         }
                   1806:     } else {
1.234     raeburn  1807:         my $warning = &Apache::loncommon::check_passwd_rules($domain,$newpass1);
1.233     raeburn  1808:         if ($warning) {
1.231     raeburn  1809:             &passwordchanger($r,'<span class="LC_warning">'.
                   1810:                             $warning.
                   1811:                             &mt('Please try again.').'</span>',
1.236     raeburn  1812:                             $caller,$mailtoken,$timelimit,$extrafields);
                   1813:             if ($caller eq 'reset_by_email') {
                   1814:                 return 'rules';
                   1815:             } else {
                   1816:                 return;
                   1817:             }
1.231     raeburn  1818:         }
1.3       matthew  1819:     }
1.4       matthew  1820:     #
                   1821:     # Check for bad characters
                   1822:     my $badpassword = 0;
                   1823:     foreach (split(//,$newpass1)) {
                   1824: 	$badpassword = 1 if ((ord($_)<32)||(ord($_)>126));
                   1825:     }
                   1826:     if ($badpassword) {
                   1827: 	# I can't figure out how to enter bad characters on my browser.
1.199     bisitz   1828: 	my $errormessage ='<span class="LC_warning">'.
1.110     bisitz   1829:            &mt('The password you entered contained illegal characters.').'<br />'.
1.99      www      1830:            &mt('Valid characters are').(<<"ENDERROR");
                   1831: : space and <br />
1.4       matthew  1832: <pre>
                   1833: !&quot;\#$%&amp;\'()*+,-./0123456789:;&lt;=&gt;?\@
                   1834: ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_\`abcdefghijklmnopqrstuvwxyz{|}~
1.99      www      1835: </pre></span>
1.4       matthew  1836: ENDERROR
1.236     raeburn  1837:         &passwordchanger($r,$errormessage,$caller,$mailtoken,$timelimit,$extrafields);
                   1838:         if ($caller eq 'reset_by_email') {
                   1839:             return 'badchars';
                   1840:         } else {
                   1841:             return;
                   1842:         }
1.4       matthew  1843:     }
                   1844:     # 
                   1845:     # Change the password (finally)
                   1846:     my $result = &Apache::lonnet::changepass
1.94      raeburn  1847: 	($user,$domain,$currentpass,$newpass1,$homeserver,$caller);
1.4       matthew  1848:     # Inform the user the password has (not?) been changed
1.126     droeschl 1849:     my $message;
1.4       matthew  1850:     if ($result =~ /^ok$/) {
1.170     bisitz   1851:         $message = &Apache::lonhtmlcommon::confirm_success(&mt('The password for user [_1] was successfully changed.','<i>'.$user.'</i>'));
1.180     wenzelju 1852:         $message = &Apache::loncommon::confirmwrapper($message);
1.144     raeburn  1853:         if ($caller eq 'reset_by_email') {
                   1854:             $r->print($message.'<br />');
                   1855:         } else {
                   1856:             &print_main_menu($r, $message);
1.226     raeburn  1857:             if (ref($ended)) {
                   1858:                 $$ended = 1;
                   1859:             }
1.144     raeburn  1860:         }
1.4       matthew  1861:     } else {
                   1862: 	# error error: run in circles, scream and shout
1.173     raeburn  1863:         if ($caller eq 'reset_by_email') {
                   1864:             if (!$result) {
1.236     raeburn  1865:                 return 'error';
1.173     raeburn  1866:             } else {
                   1867:                 return $result;
                   1868:             }
                   1869:         } else {
1.232     raeburn  1870:             my $feedback;
                   1871:             if ($result eq 'prioruse') {
                   1872:                 $feedback = &mt('Please enter a password that you have not used recently.');
                   1873:             } else {
                   1874:                 $feedback = &mt('Please make sure your old password was entered correctly.');
                   1875:             }
1.173     raeburn  1876:             $message = &Apache::lonhtmlcommon::confirm_success(
1.232     raeburn  1877:                 &mt("The password for user [_1] was not changed.",'<i>'.$user.'</i>').' '.$feedback,1);
1.158     bisitz   1878:             $message=&Apache::loncommon::confirmwrapper($message);
1.144     raeburn  1879:             &print_main_menu($r, $message);
1.226     raeburn  1880:             if (ref($ended)) {
                   1881:                 $$ended = 1;
                   1882:             }
1.144     raeburn  1883:         }
1.4       matthew  1884:     }
                   1885:     return;
1.3       matthew  1886: }
                   1887: 
1.42      raeburn  1888: ################################################################
                   1889: #            discussion display subroutines 
                   1890: ################################################################
                   1891: sub discussionchanger {
                   1892:     my $r = shift;
1.126     droeschl 1893:     Apache::lonhtmlcommon::add_breadcrumb(
                   1894: 	    {	href => '/adm/preferences?action=changediscussions',
                   1895:                 text => 'Change Discussion Preferences'});
1.178     bisitz   1896:     $r->print(Apache::loncommon::start_page('Change Discussion Preferences'));
1.248   ! raeburn  1897:     $r->print(Apache::lonhtmlcommon::breadcrumbs('Change Discussion Preferences').
        !          1898:               '<div class="LC_landmark" role="main">');
1.59      albertel 1899:     my $user       = $env{'user.name'};
                   1900:     my $domain     = $env{'user.domain'};
1.42      raeburn  1901:     my %userenv = &Apache::lonnet::get
1.43      raeburn  1902:         ('environment',['discdisplay','discmarkread']);
                   1903:     my $discdisp = 'allposts';
                   1904:     my $discmark = 'onmark';
                   1905: 
                   1906:     if (defined($userenv{'discdisplay'})) {
                   1907:         unless ($userenv{'discdisplay'} eq '') { 
                   1908:             $discdisp = $userenv{'discdisplay'};
                   1909:         }
                   1910:     }
                   1911:     if (defined($userenv{'discmarkread'})) {
1.171     raeburn  1912:         unless ($userenv{'discmarkread'} eq '') { 
1.43      raeburn  1913:             $discmark = $userenv{'discmarkread'};
                   1914:         }
                   1915:     }
                   1916: 
                   1917:     my $newdisp = 'unread';
                   1918:     my $newmark = 'ondisp';
                   1919: 
                   1920:     my $function = &Apache::loncommon::get_users_function();
                   1921:     my $color = &Apache::loncommon::designparm($function.'.tabbg',
1.59      albertel 1922:                                                     $env{'user.domain'});
1.43      raeburn  1923:     my %lt = &Apache::lonlocal::texthash(
                   1924:         'pref' => 'Display Preference',
                   1925:         'curr' => 'Current setting ',
                   1926:         'actn' => 'Action',
1.135     schafran 1927:         'sdpf' => 'Set display preferences for discussion posts for both discussion boards and individual resources in all your courses.',
1.43      raeburn  1928:         'prca' => 'Preferences can be set that determine',
1.135     schafran 1929:         'whpo' => 'Which posts are displayed when you display a discussion board or resource, and',
1.194     raeburn  1930:         'unwh' => 'Under what circumstances posts are identified as "NEW"',
1.43      raeburn  1931:         'allposts' => 'All posts',
                   1932:         'unread' => 'New posts only',
                   1933:         'ondisp' => 'Once displayed',
1.194     raeburn  1934:         'onmark' => 'Once marked not NEW',
1.43      raeburn  1935:         'disa' => 'Posts displayed?',
1.194     raeburn  1936:         'npmr' => 'New posts cease to be identified as "NEW"?',
1.43      raeburn  1937:         'thde'  => 'The preferences you set here can be overridden within each individual discussion.',
                   1938:         'chgt' => 'Change to '
                   1939:     );
                   1940:     my $dispchange = $lt{'unread'};
                   1941:     my $markchange = $lt{'ondisp'};
                   1942:     my $currdisp = $lt{'allposts'};
                   1943:     my $currmark = $lt{'onmark'};
                   1944: 
                   1945:     if ($discdisp eq 'unread') {
                   1946:         $dispchange = $lt{'allposts'};
                   1947:         $currdisp = $lt{'unread'};
                   1948:         $newdisp = 'allposts';
                   1949:     }
                   1950: 
                   1951:     if ($discmark eq 'ondisp') {
                   1952:         $markchange = $lt{'onmark'};
                   1953:         $currmark = $lt{'ondisp'};
                   1954:         $newmark = 'onmark';
1.42      raeburn  1955:     }
1.171     raeburn  1956: 
1.43      raeburn  1957:     $r->print(<<"END");
1.88      albertel 1958: <form name="prefs" action="/adm/preferences" method="post">
1.42      raeburn  1959: <input type="hidden" name="action" value="verify_and_change_discussion" />
                   1960: <br />
1.87      albertel 1961: $lt{'sdpf'}<br /> $lt{'prca'}  <ol><li>$lt{'whpo'}</li><li>$lt{'unwh'}</li></ol> 
1.82      albertel 1962: END
1.158     bisitz   1963: 
                   1964:     $r->print('<p class="LC_info">'.$lt{'thde'}.'</p>');
                   1965: 
1.248   ! raeburn  1966:     $r->print(&Apache::loncommon::start_data_table().
        !          1967:               &Apache::loncommon::start_data_table_header_row());
1.82      albertel 1968:     $r->print(<<"END");
                   1969:         <th>$lt{'pref'}</th>
                   1970:         <th>$lt{'curr'}</th>
                   1971:         <th>$lt{'actn'}?</th>
                   1972: END
1.248   ! raeburn  1973:     $r->print(&Apache::loncommon::end_data_table_header_row().
        !          1974:               &Apache::loncommon::start_data_table_row());
1.82      albertel 1975:     $r->print(<<"END");
1.43      raeburn  1976:        <td>$lt{'disa'}</td>
                   1977:        <td>$lt{$discdisp}</td>
1.82      albertel 1978:        <td><label><input type="checkbox" name="discdisp" /><input type="hidden" name="newdisp" value="$newdisp" />&nbsp;$lt{'chgt'} "$dispchange"</label></td>
                   1979: END
                   1980:     $r->print(&Apache::loncommon::end_data_table_row().
                   1981: 	      &Apache::loncommon::start_data_table_row());
                   1982:     $r->print(<<"END");
1.43      raeburn  1983:        <td>$lt{'npmr'}</td>
                   1984:        <td>$lt{$discmark}</td>
1.82      albertel 1985:        <td><label><input type="checkbox" name="discmark" /><input type="hidden" name="newmark" value="$newmark" />&nbsp;$lt{'chgt'} "$markchange"</label></td>
                   1986: END
                   1987:     $r->print(&Apache::loncommon::end_data_table_row().
                   1988: 	      &Apache::loncommon::end_data_table());
1.142     zhu      1989: 
1.158     bisitz   1990:     $r->print('<br />'
                   1991:              .'<input type="submit" name="sub" value="'.&mt('Save').'" />'
1.248   ! raeburn  1992:              .'</form></div>'
1.158     bisitz   1993:     );
1.42      raeburn  1994: }
                   1995:                                                                                                                 
                   1996: sub verify_and_change_discussion {
                   1997:     my $r = shift;
1.59      albertel 1998:     my $user     = $env{'user.name'};
                   1999:     my $domain   = $env{'user.domain'};
1.42      raeburn  2000:     my $message='';
1.59      albertel 2001:     if (defined($env{'form.discdisp'}) ) {
                   2002:         my $newdisp  = $env{'form.newdisp'};
1.43      raeburn  2003:         if ($newdisp eq 'unread') {
1.171     raeburn  2004:             $message .=&Apache::lonhtmlcommon::confirm_success(&mt('In discussions: only new posts will be displayed.')).'<br />';
1.43      raeburn  2005:             &Apache::lonnet::put('environment',{'discdisplay' => $newdisp});
1.116     raeburn  2006:             &Apache::lonnet::appenv({'environment.discdisplay' => $newdisp});
1.43      raeburn  2007:         } else {
1.171     raeburn  2008:             $message .= &Apache::lonhtmlcommon::confirm_success(&mt('In discussions: all posts will be displayed.')).'<br />';
1.43      raeburn  2009:             &Apache::lonnet::del('environment',['discdisplay']);
1.139     raeburn  2010:             &Apache::lonnet::delenv('environment.discdisplay');
1.43      raeburn  2011:         }
                   2012:     }
1.59      albertel 2013:     if (defined($env{'form.discmark'}) ) {
                   2014:         my $newmark = $env{'form.newmark'};
1.43      raeburn  2015:         if ($newmark eq 'ondisp') {
1.209     bisitz   2016:             $message.=&Apache::lonhtmlcommon::confirm_success(&mt('In discussions: new posts will cease to be identified as "NEW" after display.')).'<br />';
1.43      raeburn  2017:             &Apache::lonnet::put('environment',{'discmarkread' => $newmark});
1.116     raeburn  2018:             &Apache::lonnet::appenv({'environment.discmarkread' => $newmark});
1.43      raeburn  2019:         } else {
1.194     raeburn  2020:             $message.=&Apache::lonhtmlcommon::confirm_success(&mt('In discussions: posts will be identified as "NEW" until marked as not "NEW".')).'<br />';
1.43      raeburn  2021:             &Apache::lonnet::del('environment',['discmarkread']);
1.139     raeburn  2022:             &Apache::lonnet::delenv('environment.discmarkread');
1.43      raeburn  2023:         }
1.42      raeburn  2024:     }
1.158     bisitz   2025:     $message=&Apache::loncommon::confirmwrapper($message);
1.152     www      2026:     &print_main_menu($r, $message);
1.42      raeburn  2027: }
                   2028: 
1.63      raeburn  2029: ################################################################
                   2030: # Subroutines for page display on course access (Course Coordinators)
                   2031: ################################################################
                   2032: sub coursedisplaychanger {
                   2033:     my $r = shift;
1.152     www      2034:     &Apache::lonhtmlcommon::add_breadcrumb(
1.126     droeschl 2035: 	    {	href => '/adm/preferences?action=changecourseinit',
                   2036:                 text => 'Change Course Init. Pref.'});
                   2037:     $r->print(Apache::loncommon::start_page('Change Course Initialization Preference'));
                   2038:     $r->print(Apache::lonhtmlcommon::breadcrumbs('Change Course Init. Pref.'));
1.63      raeburn  2039:     my $user       = $env{'user.name'};
                   2040:     my $domain     = $env{'user.domain'};
1.66      albertel 2041:     my %userenv = &Apache::lonnet::get('environment',['course_init_display']);
1.71      raeburn  2042:     my $currvalue = 'whatsnew';
1.73      albertel 2043:     my $firstselect = '';
                   2044:     my $whatsnewselect = 'checked="checked"';
1.71      raeburn  2045:     if (exists($userenv{'course_init_display'})) {
                   2046:         if ($userenv{'course_init_display'} eq 'firstres') {
                   2047:             $currvalue = 'firstres';
1.73      albertel 2048:             $firstselect = 'checked="checked"';
                   2049: 	    $whatsnewselect = '';
1.71      raeburn  2050:         }
1.63      raeburn  2051:     }
1.134     bisitz   2052:     my %pagenames = &Apache::lonlocal::texthash(
1.71      raeburn  2053:                        firstres => 'First resource',
1.143     hauer    2054:                        whatsnew => "What's New Page",
1.71      raeburn  2055:                     );
1.134     bisitz   2056:     my $whatsnew_off=&mt('Display the [_1]first resource[_2] in the course.','<b>','</b>');
1.143     hauer    2057:     my $whatsnew_on=&mt("Display the [_1]What's New Page[_2] - a summary of items in the course which require attention.",'<b>','</b>');
1.63      raeburn  2058: 
1.134     bisitz   2059:     $r->print('<br /><b>'
                   2060:              .&mt('Set the default page to be displayed when you select a course role')
                   2061:              .'</b>&nbsp;'
                   2062:              .&mt('(Currently: [_1])',$pagenames{$currvalue})
                   2063:              .'<br />'
1.143     hauer    2064:              .&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]What's New Page[_2] in the course.",'<i>','</i>')
1.134     bisitz   2065:              .'<br /><br />'
                   2066:     );
1.63      raeburn  2067:     $r->print(<<ENDLSCREEN);
1.88      albertel 2068: <form name="prefs" action="/adm/preferences" method="post">
1.63      raeburn  2069: <input type="hidden" name="action" value="verify_and_change_coursepage" />
1.72      albertel 2070: <br />
1.65      albertel 2071: <label><input type="radio" name="newdisp" value="firstres" $firstselect /> $whatsnew_off</label><br />
1.70      raeburn  2072: <label><input type="radio" name="newdisp" value="whatsnew" $whatsnewselect /> $whatsnew_on</label><input type="hidden" name="refpage" value="$env{'form.refpage'}" />
1.63      raeburn  2073: ENDLSCREEN
1.140     schafran 2074:     $r->print('<br /><br /><input type="submit" value="'.&mt('Save').'" />
1.63      raeburn  2075: </form>');
                   2076: }
                   2077: 
                   2078: sub verify_and_change_coursepage {
                   2079:     my $r = shift;
                   2080:     my $message='';
                   2081:     my %lt = &Apache::lonlocal::texthash(
1.70      raeburn  2082:         'defs' => 'Default now set',
1.71      raeburn  2083:         'when' => 'when you select a course role from the roles screen',
1.63      raeburn  2084:         'ywbt' => 'you will be taken to the start of the course.',
                   2085:         'apwb' => 'a page will be displayed that lists items in the course that may require action from you.',
                   2086:         'gtts' => 'Go to the start of the course',
1.146     hauer    2087:         'dasp' => "Display the What's New Page", 
1.63      raeburn  2088:     );
                   2089:     my $newdisp  = $env{'form.newdisp'};
1.70      raeburn  2090:     $message = '<b>'.$lt{'defs'}.'</b>: '.$lt{'when'}.', ';
1.63      raeburn  2091:     if ($newdisp eq 'firstres') {
1.87      albertel 2092:         $message .= $lt{'ywbt'}.'<br />';
1.63      raeburn  2093:         &Apache::lonnet::put('environment',{'course_init_display' => $newdisp});
1.116     raeburn  2094:         &Apache::lonnet::appenv({'environment.course_init_display' => $newdisp});
1.63      raeburn  2095:     } else {
1.87      albertel 2096:         $message .= $lt{'apwb'}.'<br />';
1.63      raeburn  2097:         &Apache::lonnet::del('environment',['course_init_display']);
1.139     raeburn  2098:         &Apache::lonnet::delenv('environment.course_init_display');
1.63      raeburn  2099:     }
1.70      raeburn  2100:     my $refpage = $env{'form.refpage'};
1.63      raeburn  2101:     if (($env{'request.course.fn'}) && ($env{'request.course.id'})) {
                   2102:         if ($newdisp eq 'firstres') {
                   2103:             my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   2104:             my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; 
                   2105:             my ($furl,$ferr)=
                   2106:                 &Apache::lonuserstate::readmap($cdom.'/'.$cnum);
1.180     wenzelju 2107:             $message .= '<br /><a href="'.$furl.'">'.$lt{'gtts'}.' <i>'.&mt('now').'</i></a>';
1.63      raeburn  2108:         } else {
1.180     wenzelju 2109:             $message .= '<br /><a href="/adm/whatsnew?refpage='.
                   2110:                         $refpage.'">'.$lt{'dasp'}.'</a>';
1.63      raeburn  2111:         }
                   2112:     }
1.180     wenzelju 2113:     $message = &Apache::lonhtmlcommon::confirm_success($message);
                   2114:     $message = &Apache::loncommon::confirmwrapper($message);
                   2115:     &print_main_menu($r,$message);
1.63      raeburn  2116: }
                   2117: 
1.215     golterma 2118: sub author_space_settings {
                   2119:     my $r = shift;
                   2120:     &Apache::lonhtmlcommon::add_breadcrumb(
                   2121:             {   href => '/adm/preferences?action=authorsettings',
                   2122:                 text => 'Authoring Space Settings'});
                   2123:     my $user       = $env{'user.name'};
                   2124:     my $domain     = $env{'user.domain'};
                   2125:     my %author_roles = &Apache::lonnet::get_my_roles($user,$domain,'userroles','',['au','ca','aa']);
                   2126:     if (keys(%author_roles) > 0) {
1.242     raeburn  2127:         my ($showdomdefs,$js,$args,@items);
                   2128:         my $returnurl = &HTML::Entities::encode($env{'form.returnurl'},'"<>&\'');
1.244     raeburn  2129:         if (&expanded_authoring_settings()) {
1.245     raeburn  2130:             @items = ('nocodemirror');
                   2131:             if (&daxe_permitted(\%author_roles)) {
                   2132:                 push(@items,'daxecollapse');
                   2133:             }
                   2134:             push(@items,('copyright','sourceavail'));
1.242     raeburn  2135:             $showdomdefs = 1;
                   2136:             $js = &toggle_options_js();
                   2137:             my $onload;
                   2138:             foreach my $item (@items) {
                   2139:                 $onload .= "javascript:toggleOptions(document.prefs,'$item','user_$item');"
                   2140:             }
                   2141:             $args = { 'add_entries' => { 'onload' => $onload } };
                   2142:         }
                   2143:         $r->print(Apache::loncommon::start_page('Authoring Space Settings',$js,$args));
                   2144:         $r->print(Apache::lonhtmlcommon::breadcrumbs('Authoring Space Settings'));
                   2145:         if ($showdomdefs) {
                   2146:             my %userenv = &Apache::lonnet::get('environment',\@items);
                   2147:             my %domdefs = &Apache::lonnet::get_domain_defaults($domain);
                   2148:             my %staticdefaults = (
                   2149:                             'nocodemirror'  => '0',
1.245     raeburn  2150:                             'daxecollapse'  => '0',
1.242     raeburn  2151:                             'copyright'     => 'default',
                   2152:                             'sourceavail'   => 'closed',
                   2153:             );
                   2154:             my %lt = &authoring_settings_text();
                   2155:             my %titles = &authoring_settings_titles();
1.245     raeburn  2156:             $r->print("<h3>$lt{'auss'}</h3>".
1.242     raeburn  2157:                       '<form name="prefs" action="/adm/preferences" method="post">'."\n".
1.245     raeburn  2158:                       '<input type="submit" value="'.$lt{'save'}.'" /><br /><hr />'."\n".
1.242     raeburn  2159:                       '<input type="hidden" name="returnurl" value="'.$returnurl.'" />'."\n".
                   2160:                       '<input type="hidden" name="action" value="change_authoring_settings" />'."\n");
                   2161:             foreach my $item (@items) {
                   2162:                 my ($domdef,$checkeddom,$checkeduser,$domdefdisplay,$divsty,$userelem);
                   2163:                 $checkeddom = ' checked="checked"';
                   2164:                 $divsty = 'display:none';
                   2165:                 if (exists($domdefs{$item})) {
                   2166:                     $domdef = $domdefs{$item};
                   2167:                 } else {
                   2168:                     $domdef = $staticdefaults{$item};
                   2169:                 }
                   2170:                 if ($item eq 'copyright') {
                   2171:                     $domdefdisplay = &Apache::loncommon::copyrightdescription($domdef);
                   2172:                     $userelem = &selectbox('userchoice_'.$item,$userenv{$item},'',
                   2173:                                            \&Apache::loncommon::copyrightdescription,
                   2174:                                            (grep !/^priv|custom$/,(&Apache::loncommon::copyrightids)));
                   2175:                 } elsif ($item eq 'sourceavail') {
                   2176:                     $domdefdisplay = &Apache::loncommon::source_copyrightdescription($domdef);
                   2177:                     $userelem = &selectbox('userchoice_'.$item,$userenv{$item},'',
                   2178:                                            \&Apache::loncommon::source_copyrightdescription,
                   2179:                                            (&Apache::loncommon::source_copyrightids));
1.245     raeburn  2180:                 } elsif (($item eq 'nocodemirror') || ($item eq 'daxecollapse')) {
1.242     raeburn  2181:                     if ($domdef) {
1.245     raeburn  2182:                         if ($item eq 'daxecollapse') {
                   2183:                             $domdefdisplay = $lt{'coll'};
                   2184:                         } else {
                   2185:                             $domdefdisplay = $lt{'yes'};
                   2186:                         }
1.242     raeburn  2187:                     } else {
1.245     raeburn  2188:                         if ($item eq 'daxecollapse') {
                   2189:                             $domdefdisplay = $lt{'expa'};
                   2190:                         } else {
                   2191:                             $domdefdisplay = $lt{'no'};
                   2192:                         }
1.242     raeburn  2193:                     }
1.245     raeburn  2194:                     my (%checked,%text);
1.242     raeburn  2195:                     $checked{'no'} = ' checked="checked"';
1.243     raeburn  2196:                     if ($userenv{$item} eq 'yes') {
1.242     raeburn  2197:                         $checked{'yes'} = $checked{'no'};
                   2198:                         $checked{'no'} = '';
                   2199:                     }
1.245     raeburn  2200:                     if ($item eq 'daxecollapse') {
                   2201:                         %text = (
                   2202:                                  yes => $lt{'coll'},
                   2203:                                  no  => $lt{'expa'},
                   2204:                                );
                   2205:                     } else {
                   2206:                         %text = (
                   2207:                                  yes => $lt{'yes'},
                   2208:                                  no  => $lt{'no'},
                   2209:                                );
                   2210:                     }
1.242     raeburn  2211:                     $userelem = '<span class="LC_nobreak">';
                   2212:                     foreach my $choice ('yes','no') {
                   2213:                         $userelem .= '<label><input type="radio" name="userchoice_'.$item.'" value="'.$choice.'"'.
1.245     raeburn  2214:                                      $checked{$choice}.' />'.$text{$choice}.'</label>&nbsp;&nbsp;&nbsp;';
1.242     raeburn  2215:                     }
                   2216:                     $userelem .= '</span>';
                   2217:                 }
                   2218:                 if ($userenv{$item} ne '') {
                   2219:                     $checkeduser = $checkeddom;
                   2220:                     $checkeddom = '';
                   2221:                     $divsty = 'display:inline-block';
                   2222:                 }
                   2223:                 $r->print(<<"END");
1.248   ! raeburn  2224: <h3 class="LC_heading_3"><span class="LC_nobreak">$titles{$item}</span></h3>
1.242     raeburn  2225: <p class="LC_nobreak">$lt{'curd'}: <span style="font-style:italic">$domdefdisplay</span></p>
                   2226: <p class="LC_nobreak">
                   2227: <label><input type="radio" name="$item" value="dom" onclick="toggleOptions(this.form,'$item','user_$item');"$checkeddom />$lt{'used'}</label>&nbsp;&nbsp;&nbsp;
                   2228: <label><input type="radio" name="$item" value="user" onclick="toggleOptions(this.form,'$item','user_$item');"$checkeduser />$lt{'usyo'}</label></p>
                   2229: <fieldset id="user_$item" style="$divsty">
                   2230: <legend style="font-weight:normal;font-style:italic;">$lt{'ousv'}</legend>
                   2231: $userelem
                   2232: </fieldset><br /><hr />
                   2233: END
                   2234:             }
1.245     raeburn  2235:             $r->print('<input type="submit" value="'.$lt{'save'}.'" />'.
1.242     raeburn  2236:                       '</form>'."\n");
                   2237:         } else {
1.215     golterma 2238:             my $constchecked='';
                   2239:             if ($env{'environment.nocodemirror'}) {
                   2240:                $constchecked=' checked="checked"';
                   2241:             }
1.216     droeschl 2242:             my $text=&mt('By default, CodeMirror an editor with advanced functionality for editing code is activated for authors.');
                   2243:             my $cmoff=&mt('Deactivate CodeMirror. This can improve performance on slow computers and accessibility.');
1.215     golterma 2244:             my $change=&mt('Save');
                   2245:             $r->print(<<ENDSCREEN);
                   2246:         <form name="prefs" action="/adm/preferences" method="post">
1.225     raeburn  2247:         <input type="hidden" name="returnurl" value="$returnurl" />
1.215     golterma 2248:         <input type="hidden" name="action" value="change_authoring_settings" />
                   2249:         $text<br />
                   2250:         <label><input type="checkbox" name="cmoff"$constchecked />$cmoff</label><br />
                   2251:         <input type="submit" value="$change" />
                   2252:         </form>
                   2253: ENDSCREEN
1.242     raeburn  2254:         }
1.215     golterma 2255:     }
                   2256: }
                   2257: 
                   2258: sub change_authoring_settings {
                   2259:     my $r = shift;
                   2260:     my $user       = $env{'user.name'};
                   2261:     my $domain     = $env{'user.domain'};
                   2262:     my %author_roles = &Apache::lonnet::get_my_roles($user,$domain,'userroles','',['au','ca','aa']);
                   2263:     if (keys(%author_roles) > 0) {
1.242     raeburn  2264:         my $message;
1.244     raeburn  2265:         if (!&expanded_authoring_settings()) {
1.215     golterma 2266:             my %ausettings=('environment.nocodemirror' => '');
                   2267:             if ($env{'form.cmoff'}) { $ausettings{'environment.nocodemirror'}='yes'; }
                   2268:             &Apache::lonnet::put('environment',\%ausettings);
                   2269:             &Apache::lonnet::appenv({'environment.nocodemirror' => $ausettings{'environment.nocodemirror'}});
                   2270:             my $status='';
                   2271:             if ($ausettings{'environment.nocodemirror'} eq 'yes') {
                   2272:                 $status=&mt('on');
                   2273:             } else {
                   2274:                 $status=&mt('off');
                   2275:             }
1.242     raeburn  2276:             $message=&Apache::lonhtmlcommon::confirm_success(&mt('Set [_1] to [_2]','<i>'.&mt('Deactivate CodeMirror in Authoring Space').'</i>','<tt>'.$status.'</tt>'));
1.215     golterma 2277:             $message=&Apache::loncommon::confirmwrapper($message);
1.242     raeburn  2278:         } else {
1.245     raeburn  2279:             my @items = ('nocodemirror');
                   2280:             if (&daxe_permitted(\%author_roles)) {
                   2281:                 push(@items,'daxecollapse');
                   2282:             }
                   2283:             push(@items,('copyright','sourceavail'));
1.242     raeburn  2284:             my %oldsettings = &Apache::lonnet::get('environment',\@items);
                   2285:             my %domdefs = &Apache::lonnet::get_domain_defaults($domain);
                   2286:             my %lt = &authoring_settings_text();
                   2287:             my %titles = &authoring_settings_titles();
                   2288:             my ($result,%newsettings,%changes,@delete,@unchanged,@delerrors,@adderrors);
                   2289:             foreach my $item (@items) {
                   2290:                 if ($env{'form.'.$item} eq 'dom') {
                   2291:                     if ($oldsettings{$item} eq '') {
                   2292:                         push(@unchanged,$item);
                   2293:                     } else {
                   2294:                         push(@delete,$item);
                   2295:                     }
                   2296:                 } elsif ($env{'form.'.$item} eq 'user') {
                   2297:                     my $newval = $env{'form.userchoice_'.$item};
                   2298:                     my @possibles;
1.245     raeburn  2299:                     if (($item eq 'nocodemirror') || ($item eq 'daxecollapse')) {
1.242     raeburn  2300:                         if ($newval =~ /^yes|no$/) {
                   2301:                             $newsettings{$item} = $newval;
                   2302:                         }
                   2303:                     } elsif ($item eq 'copyright') {
                   2304:                         @possibles = (grep !/^priv|custom$/,(&Apache::loncommon::copyrightids));
                   2305:                         if (grep(/^\Q$newval\E$/,@possibles)) {
                   2306:                             $newsettings{$item} = $newval;
                   2307:                         }
                   2308:                     } elsif ($item eq 'sourceavail') {
                   2309:                         @possibles = (&Apache::loncommon::source_copyrightids);
                   2310:                         if (grep(/^\Q$newval\E$/,@possibles)) {
                   2311:                             $newsettings{$item} = $newval;
                   2312:                         }
                   2313:                     }
                   2314:                     if ($oldsettings{$item} eq $newsettings{$item}) {
                   2315:                         push(@unchanged,$item);
                   2316:                     } else {
                   2317:                         $changes{$item} = $newsettings{$item};
                   2318:                     }
                   2319:                 }
                   2320:             }
                   2321:             if (@delete) {
                   2322:                 if (&Apache::lonnet::del('environment',\@delete) eq 'ok') {
                   2323:                     foreach my $key (@delete) {
                   2324:                         &Apache::lonnet::delenv('environment.'.$key);
                   2325:                     }
                   2326:                 } else {
                   2327:                     @delerrors = @delete;
                   2328:                 }
                   2329:             }
                   2330:             if (keys(%changes)) {
                   2331:                 if (&Apache::lonnet::put('environment',\%changes) eq 'ok') {
                   2332:                     my %newenvhash;
                   2333:                     map {$newenvhash{'environment.'.$_} = $changes{$_}; } (keys(%changes));
                   2334:                     &Apache::lonnet::appenv(\%newenvhash);
                   2335:                 } else {
                   2336:                     foreach my $item (@items) {
                   2337:                         if (exists($changes{$item})) {
                   2338:                             push(@adderrors,$item);
                   2339:                         }
                   2340:                     }
                   2341:                 }
                   2342:             }
                   2343:             if (@adderrors) {
                   2344:                 $result = &mt('An error occurred when saving user-specific settings for').': '.
                   2345:                           join(', ', map { $titles{$_} } @adderrors);
                   2346:                 $message = &Apache::loncommon::confirmwrapper(&Apache::lonhtmlcommon::confirm_success($result,1));
                   2347:             } elsif (keys(%changes)) {
                   2348:                 $result = &mt('User-specific settings saved:').'<ul>';
                   2349:                 foreach my $item (@items) {
                   2350:                     next unless (exists($changes{$item}));
                   2351:                     my $value = $changes{$item};
                   2352:                     if ($item eq 'nocodemirror') {
                   2353:                         $value = $lt{$changes{$item}};
1.245     raeburn  2354:                     } elsif ($item eq 'daxecollapse') {
                   2355:                         if ($value eq 'yes') {
                   2356:                             $value = $lt{'coll'};
                   2357:                         } else {
                   2358:                             $value = $lt{'expa'};
                   2359:                         }
1.242     raeburn  2360:                     } elsif ($item eq 'copyright') {
                   2361:                         $value = &Apache::loncommon::copyrightdescription($changes{$item});
                   2362:                     } elsif ($item eq 'sourceavail') {
                   2363:                         $value = &Apache::loncommon::source_copyrightdescription($changes{$item});
                   2364:                     }
                   2365:                     $result .= '<li>'.
                   2366:                                &mt('[_1] set to [_2]',
                   2367:                                    $titles{$item},
                   2368:                                    '<span style="font-style:italic">'.$value.'</span>').
                   2369:                                '</li>';
                   2370:                 }
                   2371:                 $result .= '</ul>';
                   2372:                 $message = &Apache::loncommon::confirmwrapper(&Apache::lonhtmlcommon::confirm_success($result));
                   2373:             }
                   2374:             if (@delerrors) {
                   2375:                 $result = &mt('An error occurred when deleting user-specific settings for').':<ul><li>'.
                   2376:                           join('</li><li>', map { $titles{$_} } @delerrors).'</li></ul>';
                   2377:                 $message .= &Apache::loncommon::confirmwrapper(&Apache::lonhtmlcommon::confirm_success($result,1));
                   2378:             } elsif (@delete) {
                   2379:                 $result = &mt('Set use of domain default for').':<ul><li>'.
                   2380:                           join('</li><li>', map { $titles{$_} } @delete).'</li></ul>';
                   2381:                 $message .= &Apache::loncommon::confirmwrapper(&Apache::lonhtmlcommon::confirm_success($result));
                   2382:             }
                   2383:             if (@unchanged) {
                   2384:                 $result = &mt('No changes made for').':<ul><li>'.
                   2385:                           join('</li><li>', map { $titles{$_} } @unchanged).'</li></ul>';
                   2386:                 $message .= &Apache::loncommon::confirmwrapper(&Apache::lonhtmlcommon::confirm_success($result));
1.225     raeburn  2387:             }
1.242     raeburn  2388:         }
                   2389:         if ($env{'form.returnurl'}) {
                   2390:             &do_redirect($r,$env{'form.returnurl'},$message);
                   2391:         } else {
                   2392:             &print_main_menu($r,$message);
                   2393:         }
1.215     golterma 2394:     }
                   2395: }
                   2396: 
1.242     raeburn  2397: sub authoring_settings_text {
                   2398:     return &Apache::lonlocal::texthash(
                   2399:                'auss' => 'Authoring Space Settings',
                   2400:                'used' => 'Use domain default',
                   2401:                'usyo' => 'Use your own user-specific setting',
                   2402:                'curd' => 'Current domain default is',
                   2403:                'ousv' => 'Own user-specific value',
                   2404:                'save' => 'Save',
                   2405:                'yes'  => 'Deactivated',
                   2406:                'no'   => 'Activated',
1.245     raeburn  2407:                'expa' => 'Start Expanded',
                   2408:                'coll' => 'Start Collapsed',
1.242     raeburn  2409:      );
                   2410: }
                   2411: 
                   2412: sub authoring_settings_titles {
                   2413:     return &Apache::lonlocal::texthash(
                   2414:                'nocodemirror' => 'CodeMirror for EditXML editor',
1.245     raeburn  2415:                'daxecollapse' => 'Daxe editor: collapsible standard LON-CAPA menus',
1.242     raeburn  2416:                'copyright'    => 'Default Copyright/Distribution in new metadata file',
                   2417:                'sourceavail'  => 'Default Source Available in new metadata file',
                   2418:     );
                   2419: }
                   2420: 
1.244     raeburn  2421: sub expanded_authoring_settings {
                   2422:     my $reqdmajor = 2;
                   2423:     my $reqdminor = 12;
                   2424:     my $loncaparev = &Apache::lonnet::get_server_loncaparev($env{'user.domain'},$env{'user.home'});
                   2425:     my ($major,$minor) = ($loncaparev =~ /^\'?(\d+)\.(\d+)\.[\w.\-]+\'?$/);
                   2426:     unless (($major eq '' && $minor eq '') ||
                   2427:             ($reqdmajor > $major) || (($reqdmajor == $major) && ($reqdminor > $minor))) {
                   2428:         return 1;
                   2429:     }
                   2430:     return;
                   2431: }
                   2432: 
1.245     raeburn  2433: sub daxe_permitted {
                   2434:     my ($aurolesref) = @_;
                   2435:     my $hasdaxe;
                   2436:     if (ref($aurolesref) eq 'HASH') {
                   2437:         my %editors;
                   2438:         foreach my $key (keys(%{$aurolesref})) {
                   2439:             if ($key =~ /^:$LONCAPA::match_domain:au$/) {
                   2440:                 if (exists($env{'environment.editors'})) {
                   2441:                     if (grep(/^daxe$/,split(/,/,$env{'environment.editors'}))) {
                   2442:                         $hasdaxe = 1;
                   2443:                         last;
                   2444:                     }
                   2445:                 }
                   2446:             } else {
                   2447:                 my ($auname,$audom) = ($key =~ /^($LONCAPA::match_username):($LONCAPA::match_domain):(ca|aa)$/);
                   2448:                 if (exists($env{"environment.internal.editors./$audom/$auname"})) {
                   2449:                     if (grep(/^daxe$/,split(/,/,$env{"environment.internal.editors./$audom/$auname"}))) {
                   2450:                         $hasdaxe = 1;
                   2451:                         last;
                   2452:                     }
                   2453:                 }
                   2454:             }
                   2455:         }
                   2456:     }
                   2457:     return $hasdaxe;
                   2458: }
                   2459: 
1.186     raeburn  2460: sub lockednameschanger {
                   2461:     my $r = shift;
                   2462:     my %userenv = &Apache::lonnet::get('environment',['lockedname']);
                   2463:     my $lockedname='';
1.240     raeburn  2464:     my $ended;
1.186     raeburn  2465:     if (&can_toggle_namelocking()) {
                   2466:         if ($userenv{'lockedname'}) {
                   2467:             $lockedname = ' checked="checked"';
                   2468:         }
                   2469:         my %updateable;
                   2470:         my %domconfig =
                   2471:             &Apache::lonnet::get_dom('configuration',['autoupdate'],$env{'user.domain'});
                   2472:         if (ref($domconfig{'autoupdate'}) eq 'HASH') {
                   2473:             if ($domconfig{'autoupdate'}{'run'}) {
                   2474:                 my @inststatuses = split(':',$env{'environment.inststatus'});
                   2475:                 unless (@inststatuses) {
                   2476:                     @inststatuses = ('default');
                   2477:                 }
                   2478:                 %updateable = &updateable_userinfo($domconfig{'autoupdate'},\@inststatuses);
                   2479:             }
                   2480:         }
                   2481:         if (keys(%updateable)) {
1.240     raeburn  2482:             &Apache::lonhtmlcommon::add_breadcrumb(
                   2483:                 {   href => '/adm/preferences?action=changelockednames',
                   2484:                     text => 'Automatic name changes'});
                   2485:             $r->print(Apache::loncommon::start_page('Automatic name changes'));
                   2486:             $r->print(Apache::lonhtmlcommon::breadcrumbs('Allow/disallow name updates'));
1.186     raeburn  2487:             my %longnames = &Apache::lonlocal::texthash (
                   2488:                                 firstname  => 'First Name',
                   2489:                                 middlename => 'Middle Name',
                   2490:                                 lastname   => 'Last Name',
                   2491:                             );
                   2492:             my $text=&mt('By default, based on your institutional affiliation, your LON-CAPA account can be automatically updated nightly based on directory information from your institution.').'<br />'.&mt('The following may be updated, unless you disallow updates:').
                   2493:                      '<ul>';
                   2494:            foreach my $item ('firstname','middlename','lastname') {
                   2495:                if ($updateable{$item}) {
                   2496:                    $text .= '<li>'.$longnames{$item}.'</li>';
                   2497:                }
                   2498:            }
                   2499:            $text .= '</ul>'; 
                   2500:            my $locking=&mt('Disallow automatic updates to name information for your LON-CAPA account');
                   2501:            my $change=&mt('Save');
                   2502:            $r->print(<<ENDSCREEN);
                   2503: <form name="prefs" action="/adm/preferences" method="post">
                   2504: <input type="hidden" name="action" value="verify_and_change_lockednames" />
                   2505: $text<br />
                   2506: <label><input type="checkbox" value="1" name="lockednames"$lockedname />$locking</label><br />
                   2507: <input type="submit" value="$change" />
                   2508: </form>
                   2509: ENDSCREEN
                   2510:         } else {
                   2511:             my $message = &mt('Based on your institutional affiliation no name information is automatically updated for your LON-CAPA account.');
                   2512:             &print_main_menu($r,$message);
1.240     raeburn  2513:             $ended = 1;
1.186     raeburn  2514:         }
                   2515:     } else {
                   2516:         my $message = &mt('You are not permitted to set a user preference for automatic name updates for your LON-CAPA account.');
                   2517:         &print_main_menu($r,$message);
1.240     raeburn  2518:         $ended = 1;
1.186     raeburn  2519:     }
1.240     raeburn  2520:     return $ended;
1.186     raeburn  2521: }
                   2522: 
                   2523: sub verify_and_change_lockednames {
                   2524:     my $r = shift;
                   2525:     my $message;
                   2526:     if (&can_toggle_namelocking()) {
                   2527:         my $newlockedname = $env{'form.lockednames'};
                   2528:         $newlockedname =~ s/\D//g;
                   2529:         my $currlockedname = $env{'environment.lockedname'};
                   2530:         if ($newlockedname ne $currlockedname) {
                   2531:             if ($newlockedname) {
                   2532:                 if (&Apache::lonnet::put('environment',{lockedname => $newlockedname}) eq 'ok') {
                   2533:                     &Apache::lonnet::appenv({'environment.lockedname' => $newlockedname});
                   2534:                 }
                   2535:             } elsif (&Apache::lonnet::del('environment',['lockedname']) eq 'ok') {
                   2536:                 &Apache::lonnet::delenv('environment.lockedname');
                   2537:             }
                   2538:         }
                   2539:         my $status='';
                   2540:         if ($newlockedname) {
                   2541:             $status=&mt('disallowed');
                   2542:         } else {
                   2543:             $status=&mt('allowed');
                   2544:         }
                   2545:         $message=&Apache::lonhtmlcommon::confirm_success(&mt('[_1] set to [_2]','<i>'.&mt('Automatic update of first, middle and last names if institutional directory information indicates changes').'</i>','<tt>'.$status.'</tt>'));
                   2546:         $message=&Apache::loncommon::confirmwrapper($message);
                   2547:     }
                   2548:     &print_main_menu($r,$message);
                   2549: }
                   2550: 
1.241     raeburn  2551: sub timezonechanger {
                   2552:     my $r = shift;
                   2553:     my $uname = $env{'user.name'};
                   2554:     my $udom = $env{'user.domain'};
                   2555:     if (&Apache::lonnet::usertools_access($uname,$udom,'timezone')) {
1.242     raeburn  2556:         my $js = &toggle_options_js();
1.241     raeburn  2557:         my %loaditems = (
1.242     raeburn  2558:                            onload => "javascript:toggleOptions(document.prefs,'settimezone','LC_timezone_selector');",
1.241     raeburn  2559:                         );
                   2560:         my $args = { 'add_entries' => \%loaditems };
                   2561:         &Apache::lonhtmlcommon::add_breadcrumb(
                   2562:                 {   href => '/adm/preferences?action=',
                   2563:                     text => 'Set Your Time Zone'});
                   2564:         $r->print(Apache::loncommon::start_page('Set Your Time Zone',$js,$args));
1.248   ! raeburn  2565:         $r->print(Apache::lonhtmlcommon::breadcrumbs('Set Your Time Zone').
        !          2566:                   '<div class="LC_landmark" role="main">');
1.241     raeburn  2567:         my %userenv = &Apache::lonnet::get('environment',['timezone']);
                   2568:         my $timezone = $userenv{'timezone'};
                   2569:         my %lt = &Apache::lonlocal::texthash(
1.248   ! raeburn  2570:                      tztu  => 'Time Zone in use',
1.241     raeburn  2571:                      lctz  => 'Use Time Zone set by LON-CAPA',
                   2572:                      owntz => 'Use Time Zone set by you',
                   2573:                      save  => 'Save',
                   2574:         );
                   2575:         my (%checked,$tzsty);
                   2576:         if ($userenv{'timezone'} ne '') {
                   2577:             $checked{'owntz'} = ' checked="checked"';
                   2578:             $tzsty = 'inline-block';
                   2579:         } else {
                   2580:             $checked{'lctz'} = ' checked="checked"';
                   2581:             $tzsty = 'none';
                   2582:         }
1.242     raeburn  2583:         my $onclick = ' onclick="javascript:toggleOptions(this.form,'."'settimezone','LC_timezone_selector'".');"';
1.241     raeburn  2584:         my $selector = &Apache::loncommon::select_timezone('timezone',$timezone,undef,1);
                   2585:         $r->print(<<"END");
                   2586: <form name="prefs" action="/adm/preferences" method="post">
                   2587: <input type="hidden" name="action" value="verify_and_change_timezone" />
1.248   ! raeburn  2588: <fieldset style="display:inline; padding: 5px;"><legend>$lt{'tztu'}</legend>
1.241     raeburn  2589: <span class="LC_nobreak">
                   2590: <label><input type="radio" name="settimezone" value="0"$checked{'lctz'}$onclick />
1.248   ! raeburn  2591: $lt{'lctz'}</label></span><br />
        !          2592: <span class="LC_nobreak">
1.241     raeburn  2593: <label><input type="radio" name="settimezone" value="1"$checked{'owntz'}$onclick />
1.248   ! raeburn  2594: $lt{'owntz'}</label></span><div style="display:$tzsty" id="LC_timezone_selector">&nbsp;
1.241     raeburn  2595: $selector
1.248   ! raeburn  2596: </div></fieldset><p>
1.241     raeburn  2597: <input type="submit" value="$lt{'save'}" />
1.248   ! raeburn  2598: </p></form></div>
1.241     raeburn  2599: END
                   2600:     }
                   2601:     return;
                   2602: }
                   2603: 
                   2604: sub verify_and_change_timezone {
                   2605:     my $r = shift;
                   2606:     my $currtimezone = $env{'environment.timezone'};
                   2607:     my $newtimezone;
                   2608:     if ($env{'form.settimezone'}) {
                   2609:         $newtimezone = $env{'form.timezone'};
                   2610:         if (DateTime::TimeZone->is_valid_name($env{'form.timezone'})) {
                   2611:             $newtimezone = $env{'form.timezone'};
                   2612:         }
                   2613:     }
                   2614:     my $message='';
                   2615:     if ($newtimezone) {
                   2616:         if ($newtimezone eq $currtimezone) {
                   2617:             $message = &mt('Time Zone settings unchanged');
                   2618:         } else {
                   2619:             &Apache::lonnet::put('environment',{'timezone' => $newtimezone});
                   2620:             &Apache::lonnet::appenv({'environment.timezone' => $newtimezone});
                   2621:             $message=&Apache::lonhtmlcommon::confirm_success(
                   2622:                 &mt('Set [_1] to [_2]',
                   2623:                     '<i>'.&mt('Your Time Zone').'</i>',
                   2624:                     '<tt>"'.$newtimezone.'"</tt>.')).
                   2625:                '<br />';
                   2626:         }
                   2627:     } elsif ($currtimezone) {
                   2628:         &Apache::lonnet::del('environment',['timezone']);
                   2629:         &Apache::lonnet::delenv('environment.timezone');
                   2630:         $message=&Apache::lonhtmlcommon::confirm_success(&mt('Time Zone now set by LON-CAPA'));
                   2631:     } else {
                   2632:         $message = &mt('Time Zone settings unchanged');
                   2633:     }
                   2634:     $message=&Apache::loncommon::confirmwrapper($message);
                   2635:     &print_main_menu($r,$message);
                   2636:     return;
                   2637: }
                   2638: 
1.126     droeschl 2639: sub print_main_menu {
                   2640:     my ($r, $message) = @_;
                   2641:     # Determine current authentication method
                   2642:     my $user = $env{'user.name'};
                   2643:     my $domain = $env{'user.domain'};
                   2644:     my $currentauth=&Apache::lonnet::queryauthenticate($user,$domain);
                   2645: 
                   2646:     # build the data structure for menu generation
                   2647: my $aboutmeurl='/adm/'.$env{'user.domain'}.'/'.$env{'user.name'}.'/aboutme';
                   2648: my $role = ($env{'user.adv'} ? 'Roles' : 'Course');
1.131     raeburn  2649: my %permissions;
                   2650: if (&Apache::lonnet::usertools_access($user,$domain,'aboutme')) {
                   2651:     $permissions{'aboutme'} = 'F';
                   2652: }
1.241     raeburn  2653: if (&Apache::lonnet::usertools_access($user,$domain,'timezone')) {
                   2654:     $permissions{'timezone'} = 'F';
                   2655: }
1.242     raeburn  2656: my %author_roles = &Apache::lonnet::get_my_roles($user,$domain,'userroles','',['au']);
                   2657: my %author_coauthor_roles = &Apache::lonnet::get_my_roles($user,$domain,'userroles','',['au','ca','aa']);
1.126     droeschl 2658: my @menu=
                   2659:     ({	categorytitle=>'Personal Data',
                   2660: 	items =>[
1.141     weissno  2661: 	    {	linktext => 'Personal Information Page',
1.126     droeschl 2662: 		url => $aboutmeurl,
1.131     raeburn  2663: 		permission => $permissions{'aboutme'},
1.126     droeschl 2664: 		#help => 'Prefs_About_Me',
                   2665: 		icon => 'system-users.png',
1.247     raeburn  2666:                 alttext => 'About Me Icon',
1.126     droeschl 2667: 		linktitle => 'Edit information about yourself that should be displayed on your public profile.'
                   2668: 	    },
                   2669: 	    {	linktext => 'Screen Name',
                   2670: 		url => '/adm/preferences?action=changescreenname',
                   2671: 		permission => 'F',
                   2672: 		#help => 'Prefs_Screen_Name_Nickname',
                   2673: 		icon => 'preferences-desktop-font.png',
1.247     raeburn  2674:                 alttext => 'Nickname Icon',
1.126     droeschl 2675: 		linktitle => 'Change the name that is displayed in your posts.'
                   2676: 	    },
                   2677: 		]
                   2678:     },
                   2679:     {	categorytitle=>'Content Display Settings',
                   2680: 	items =>[
                   2681: 	    {	linktext => 'Language',
                   2682: 		url => '/adm/preferences?action=changelanguages',
                   2683: 		permission => 'F',
                   2684: 		#help => 'Prefs_Language',
                   2685: 		icon => 'preferences-desktop-locale.png',
1.247     raeburn  2686:                 alttext => 'Language Icon',
1.127     droeschl 2687: 		linktitle => 'Choose the default language for this user.'
1.126     droeschl 2688: 	    },
1.128     droeschl 2689: 	    {	linktext => $role.' Page',
1.126     droeschl 2690: 		url => '/adm/preferences?action=changerolespref',
                   2691: 		permission => 'F',
                   2692: 		#help => '',
1.189     wenzelju 2693: 		icon => 'role_hotlist.png',
1.247     raeburn  2694:                 alttext => 'Switch Role Icon',
1.126     droeschl 2695: 		linktitle => 'Configure the roles hotlist.'
                   2696: 	    },
1.177     raeburn  2697: 	    {	linktext => 'Math display settings',
1.126     droeschl 2698: 		url => '/adm/preferences?action=changetexenginepref',
                   2699: 		permission => 'F',
                   2700: 		#help => '',
1.188     wenzelju 2701: 		icon => 'dismath.png',
1.247     raeburn  2702:                 alttext => 'Math Icon',
1.177     raeburn  2703: 		linktitle => 'Change how math is displayed.'
1.126     droeschl 2704: 	    },
1.241     raeburn  2705:             {
                   2706:                 linktext => 'Time Zone',
                   2707:                 url => '/adm/preferences?action=changetimezone',
                   2708:                 permission => $permissions{'timezone'},
                   2709:                 #help => '',
                   2710:                 icon => 'timezone.png',
1.247     raeburn  2711:                 alttext => 'Clock Icon',
1.241     raeburn  2712:                 linktitle => 'Set your time zone.',
                   2713:              }
1.126     droeschl 2714: 		]
                   2715:     },
1.185     droeschl 2716:     {	categorytitle=>'Page Display Settings',
                   2717: 	items =>[
                   2718: 	    {	linktext => 'Color Scheme',
                   2719: 		url => '/adm/preferences?action=changecolors',
                   2720: 		permission => 'F',
                   2721: 		#help => 'Change_Colors',
                   2722: 		icon => 'preferences-desktop-theme.png',
1.247     raeburn  2723:                 alttext => 'Colors Icon',
1.185     droeschl 2724: 		linktitle => 'Change LON-CAPA default colors.'
                   2725: 	    },
1.192     raeburn  2726:             {   linktext => 'Menu Display',
                   2727:                 url => '/adm/preferences?action=changeicons',
                   2728:                 permission => 'F',
                   2729:                 #help => '',
                   2730:                 icon => 'preferences-system-windows.png',
1.247     raeburn  2731:                 alttext => 'Menus Icon',
1.192     raeburn  2732:                 linktitle => 'Change whether the menus are displayed with icons or icons and text.'
                   2733:             }
1.185     droeschl 2734: 		]
                   2735:     },
1.178     bisitz   2736:     {	categorytitle=>'Messages &amp; Notifications',
1.128     droeschl 2737: 	items =>[
1.153     www      2738: 	    {	linktext => 'Messages &amp; Notifications',
1.128     droeschl 2739: 		url => '/adm/preferences?action=changemsgforward',
                   2740: 		permission => 'F',
                   2741: 		#help => 'Prefs_Messages',
                   2742: 		icon => 'mail-reply-all.png',
1.247     raeburn  2743:                 alttext => 'Notifications Icon',
1.128     droeschl 2744: 		linktitle => 'Change messageforwarding or notifications settings.'
                   2745: 	    },
                   2746: 	    {	linktext => 'Discussion Display',
                   2747: 		url => '/adm/preferences?action=changediscussions',
                   2748: 		permission => 'F',
                   2749: 		#help => 'Change_Discussion_Display',
1.191     riegler  2750: 		icon => 'chat.png',
1.248   ! raeburn  2751:                 alttext => 'Discussions Icon',
1.135     schafran 2752: 		linktitle => 'Set display preferences for discussion posts for both discussion boards and individual resources in all your courses.'
1.128     droeschl 2753: 	    },
                   2754: 		]
                   2755:     },
1.242     raeburn  2756:     );
                   2757: if (keys(%author_coauthor_roles) > 0) {
                   2758:     push(@menu,
                   2759:     {    categorytitle=>'Authoring Settings',
                   2760:          items => [
                   2761:              {
                   2762:                   linktext => 'Authoring Space Configuration',
                   2763:                   url => '/adm/preferences?action=authorsettings',
                   2764:                   permission => 'F',
                   2765:                   icon => 'codemirror.png',
1.247     raeburn  2766:                   alttext => 'Coding Icon',
1.242     raeburn  2767:                   linktitle => 'Settings for your authoring space.',
                   2768:              },
                   2769:                   ]
                   2770:     },
                   2771:     );
                   2772:     if (keys(%author_roles) > 0) {
                   2773:         push(@{ $menu[4]->{items} }, {
                   2774:         linktext => 'Restrict Domain Coordinator Access',
                   2775:         url => '/adm/preferences?action=changedomcoord',
                   2776:         permission => 'F',
                   2777:         #help => '',
                   2778:         icon => 'system-lock-screen.png',
1.247     raeburn  2779:         alttext => 'Lock Icon',
1.242     raeburn  2780:         linktitle => 'Restrict domain coordinator access.',
                   2781:         });
                   2782:     }
                   2783: }
                   2784: push(@menu,
1.126     droeschl 2785:     {	categorytitle=>'Other',
                   2786: 	items =>[
1.153     www      2787: 	    {	linktext => 'Register Response Devices (&quot;Clickers&quot;)',
1.126     droeschl 2788: 		url => '/adm/preferences?action=changeclicker',
                   2789: 		permission => 'F',
                   2790: 		#help => '',
                   2791: 		icon => 'network-workgroup.png',
1.247     raeburn  2792:                 alttext => 'Clicker Icon',
1.126     droeschl 2793: 		linktitle => 'Register your clicker.'
                   2794: 	    },
                   2795: 		]
                   2796:     },
1.242     raeburn  2797: );
1.126     droeschl 2798: 
                   2799:     if ($currentauth =~ /^(unix|internal):/) {
1.242     raeburn  2800:         push(@{ $menu[0]->{items} }, {
1.126     droeschl 2801: 	linktext => 'Password',
                   2802: 	url => '/adm/preferences?action=changepass',
                   2803: 	permission => 'F',
                   2804: 	#help => 'Change_Password',
                   2805: 	icon => 'emblem-readonly.png',
1.248   ! raeburn  2806:         alttext => 'Secure Icon',
1.126     droeschl 2807: 	linktitle => 'Change your password.',
                   2808: 	});
                   2809:     }
1.186     raeburn  2810: 
                   2811:     if (&can_toggle_namelocking()) {
                   2812:         push(@{ $menu[0]->{items} }, {
                   2813:         linktext => 'Automatic name changes',
                   2814:         url => '/adm/preferences?action=changelockednames',
                   2815:         permission => 'F',
                   2816:         #help => '',
                   2817:         icon => 'system-lock-screen.png',
1.247     raeburn  2818:         alttext => 'Screen Lock Icon',
1.186     raeburn  2819:         linktitle => 'Allow/disallow propagation of name changes from institutional directory service',
                   2820:         });
                   2821:     }
                   2822: 
1.126     droeschl 2823:     if (&Apache::lonnet::allowed('whn',$env{'request.course.id'})
                   2824: 	|| &Apache::lonnet::allowed('whn',$env{'request.course.id'}.'/'
                   2825: 				    .$env{'request.course.sec'})) {
1.242     raeburn  2826: push(@{ $menu[-1]->{items} }, {
1.128     droeschl 2827: 	linktext => 'Course Initialization',
1.126     droeschl 2828: 	url => '/adm/preferences?action=changecourseinit',
                   2829: 	permission => 'F',
                   2830: 	#help => '',
1.189     wenzelju 2831: 	icon => 'course_ini.png',
1.247     raeburn  2832:         alttext => 'Course Launch Icon',
1.126     droeschl 2833: 	linktitle => 'Set the default page to be displayed when you select a course role.',
                   2834: 	});
                   2835: 
                   2836:     }
1.215     golterma 2837: 
1.174     raeburn  2838:     if (&can_toggle_debug()) {
1.242     raeburn  2839: push(@{ $menu[-1]->{items} }, {
1.174     raeburn  2840: 	linktext => 'Toggle Debug Messages (Currently '.($env{'user.debug'} ? 'on)' : 'off)'),
1.126     droeschl 2841: 	url => '/adm/preferences?action=debugtoggle',
                   2842: 	permission => 'F',
                   2843: 	#help => '',
                   2844: 	icon => 'blog.png',
1.248   ! raeburn  2845:         alttext => 'Debugging Icon',
1.126     droeschl 2846: 	linktitle => 'Toggle Debug Messages.',
                   2847: 	});
1.186     raeburn  2848:     }
1.126     droeschl 2849: 
1.147     schafran 2850:     $r->print(&Apache::loncommon::start_page('My Space'));
1.126     droeschl 2851:     $r->print(Apache::lonhtmlcommon::breadcrumbs('Change Preferences'));
1.247     raeburn  2852:     $r->print('<div class="LC_landmark" role="main">'."\n".$message);
                   2853:     $r->print(Apache::lonhtmlcommon::generate_menu(@menu)."\n".'</div>');
1.126     droeschl 2854:     $r->print(Apache::loncommon::end_page());
                   2855: }
1.63      raeburn  2856: 
1.4       matthew  2857: ######################################################
                   2858: #            other handler subroutines               #
                   2859: ######################################################
                   2860: 
1.3       matthew  2861: ################################################################
                   2862: #                          Main handler                        #
                   2863: ################################################################
1.126     droeschl 2864: sub handler {    
                   2865:     my $r = shift;
                   2866:     Apache::loncommon::content_type($r,'text/html');
                   2867:     # Some pages contain DES keys and should not be cached.
                   2868:     Apache::loncommon::no_cache($r);
                   2869:     $r->send_http_header;
                   2870:     return OK if $r->header_only;
                   2871:     #
                   2872:     Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                   2873:                                    ['action','wysiwyg','returnurl','refpage']);
                   2874:     #
                   2875:     Apache::lonhtmlcommon::clear_breadcrumbs();
1.226     raeburn  2876:     my ($brlink,$brtxt,$brhelp,$ended);
1.198     raeburn  2877:     if (($env{'form.action'} eq 'changerolespref') && ($env{'form.returnurl'} eq '/adm/roles')) {
                   2878:         $brlink ='/adm/roles';
                   2879:         $brtxt = 'User Roles';
1.225     raeburn  2880:     } elsif ((($env{'form.action'} eq 'changedomcoord') ||
                   2881:               ($env{'form.action'} eq 'authorsettings')) &&
                   2882:              (($env{'form.returnurl'} =~ m{^/(priv/|res($|/))}) ||
                   2883:               ($env{'form.returnurl'} eq '/adm/createuser'))) {
                   2884:         $brlink = $env{'form.returnurl'};
                   2885:         if ($env{'form.returnurl'} eq '/adm/createuser') {
                   2886:             $brtxt = 'User Management';
                   2887:         } elsif ($env{'form.returnurl'} =~ m{^/res($\/)}) {
                   2888:             $brtxt = 'Browse published resources';
                   2889:         } else {
                   2890:             $brtxt = 'Authoring Space';
                   2891:         }
1.198     raeburn  2892:     } else {
                   2893:         $brlink ='/adm/preferences';
                   2894:         $brtxt = 'Set User Preferences';
1.235     raeburn  2895:         $brhelp = 'Prefs_About_Me,Prefs_Language,Prefs_Screen_Name_Nickname,Change_Colors,Change_Password,Prefs_Messages,Change_Discussion_Display';
1.198     raeburn  2896:     }
1.126     droeschl 2897:     Apache::lonhtmlcommon::add_breadcrumb
1.198     raeburn  2898:         ({href => $brlink,
                   2899:           text => $brtxt,
                   2900:           help => $brhelp,});
1.126     droeschl 2901:     if(!exists $env{'form.action'}) {
1.225     raeburn  2902: 	&print_main_menu($r);
1.226     raeburn  2903:         $ended = 1;
1.126     droeschl 2904:     }elsif($env{'form.action'} eq 'changepass'){
                   2905:         &passwordchanger($r);
                   2906:     }elsif($env{'form.action'} eq 'verify_and_change_pass'){
1.236     raeburn  2907:         &verify_and_change_password($r,'preferences','','','',\$ended);
1.126     droeschl 2908:     }elsif($env{'form.action'} eq 'changescreenname'){
                   2909:         &screennamechanger($r);
                   2910:     }elsif($env{'form.action'} eq 'verify_and_change_screenname'){
                   2911:         &verify_and_change_screenname($r);
1.226     raeburn  2912:         $ended = 1;
1.126     droeschl 2913:     }elsif($env{'form.action'} eq 'changemsgforward'){
                   2914:         &msgforwardchanger($r);
                   2915:     }elsif($env{'form.action'} eq 'verify_and_change_msgforward'){
                   2916:         &verify_and_change_msgforward($r);
                   2917:     }elsif($env{'form.action'} eq 'changecolors'){
                   2918:         &colorschanger($r);
                   2919:     }elsif($env{'form.action'} eq 'verify_and_change_colors'){
                   2920:         &verify_and_change_colors($r);
1.226     raeburn  2921:         $ended = 1;
1.126     droeschl 2922:     }elsif($env{'form.action'} eq 'changelanguages'){
                   2923:         &languagechanger($r);
                   2924:     }elsif($env{'form.action'} eq 'verify_and_change_languages'){
                   2925:         &verify_and_change_languages($r);
1.226     raeburn  2926:         $ended = 1;
1.126     droeschl 2927:     }elsif($env{'form.action'} eq 'changewysiwyg'){
                   2928:         &wysiwygchanger($r);
                   2929:     }elsif($env{'form.action'} eq 'set_wysiwyg'){
                   2930:         &verify_and_change_wysiwyg($r);
1.227     raeburn  2931:         $ended = 1;
1.126     droeschl 2932:     }elsif($env{'form.action'} eq 'changediscussions'){
                   2933:         &discussionchanger($r);
                   2934:     }elsif($env{'form.action'} eq 'verify_and_change_discussion'){
                   2935:         &verify_and_change_discussion($r);
1.226     raeburn  2936:         $ended = 1;
1.126     droeschl 2937:     }elsif($env{'form.action'} eq 'changerolespref'){
                   2938:         &rolesprefchanger($r);
                   2939:     }elsif($env{'form.action'} eq 'verify_and_change_rolespref'){
                   2940:         &verify_and_change_rolespref($r);
1.226     raeburn  2941:         $ended = 1;
1.126     droeschl 2942:     }elsif($env{'form.action'} eq 'changetexenginepref'){
                   2943:         &texenginechanger($r);
                   2944:     }elsif($env{'form.action'} eq 'verify_and_change_texengine'){
                   2945:         &verify_and_change_texengine($r);
1.227     raeburn  2946:         $ended = 1;
1.192     raeburn  2947:     }elsif($env{'form.action'} eq 'changeicons'){
                   2948:         &iconchanger($r);
                   2949:     }elsif($env{'form.action'} eq 'verify_and_change_icons'){
                   2950:         &verify_and_change_icons($r);
1.226     raeburn  2951:         $ended = 1;
1.126     droeschl 2952:     }elsif($env{'form.action'} eq 'changeclicker'){
                   2953:         &clickerchanger($r);
                   2954:     }elsif($env{'form.action'} eq 'verify_and_change_clicker'){
                   2955:         &verify_and_change_clicker($r);
1.227     raeburn  2956:         $ended = 1;
1.126     droeschl 2957:     }elsif($env{'form.action'} eq 'changedomcoord'){
                   2958:         &domcoordchanger($r);
                   2959:     }elsif($env{'form.action'} eq 'verify_and_change_domcoord'){
                   2960:         &verify_and_change_domcoord($r);
1.226     raeburn  2961:         $ended = 1;
1.126     droeschl 2962:     }elsif($env{'form.action'} eq 'lockwarning'){
                   2963:         &lockwarning($r);
                   2964:     }elsif($env{'form.action'} eq 'verify_and_change_locks'){
                   2965:         &verify_and_change_lockwarning($r);
                   2966:     }elsif($env{'form.action'} eq 'changecourseinit'){
                   2967:         &coursedisplaychanger($r);
                   2968:     }elsif($env{'form.action'} eq 'verify_and_change_coursepage'){
                   2969:         &verify_and_change_coursepage($r);
1.226     raeburn  2970:         $ended = 1;
1.215     golterma 2971:     }elsif($env{'form.action'} eq 'authorsettings'){
                   2972:         &author_space_settings($r);
                   2973:     }elsif($env{'form.action'} eq 'change_authoring_settings'){
                   2974:         &change_authoring_settings($r);
1.227     raeburn  2975:         $ended = 1;
1.126     droeschl 2976:     }elsif($env{'form.action'} eq 'debugtoggle'){
1.174     raeburn  2977:         if (&can_toggle_debug()) {
                   2978:             &toggle_debug();
                   2979:         }
1.154     www      2980: 	&print_main_menu($r);
1.226     raeburn  2981:         $ended = 1;
1.186     raeburn  2982:     } elsif ($env{'form.action'} eq 'changelockednames') {
1.240     raeburn  2983:         $ended = &lockednameschanger($r);
1.186     raeburn  2984:     } elsif ($env{'form.action'} eq 'verify_and_change_lockednames') {
                   2985:         &verify_and_change_lockednames($r);
1.226     raeburn  2986:         $ended = 1;
1.241     raeburn  2987:     } elsif ($env{'form.action'} eq 'changetimezone') {
                   2988:         &timezonechanger($r);
                   2989:     } elsif ($env{'form.action'} eq 'verify_and_change_timezone') {
                   2990:         &verify_and_change_timezone($r);
1.126     droeschl 2991:     }
                   2992: 
1.165     bisitz   2993:     # Properly end the HTML page of all preference pages
                   2994:     # started in each sub routine
                   2995:     # Exception: print_main_menu has its own end_page call
1.226     raeburn  2996:     unless ($ended) {
1.165     bisitz   2997:         $r->print(&Apache::loncommon::end_page());
                   2998:     }
                   2999: 
1.126     droeschl 3000:     return OK;
1.35      matthew  3001: }
                   3002: 
                   3003: sub toggle_debug {
1.59      albertel 3004:     if ($env{'user.debug'}) {
1.139     raeburn  3005:         &Apache::lonnet::delenv('user.debug');
1.35      matthew  3006:     } else {
1.116     raeburn  3007:         &Apache::lonnet::appenv({'user.debug' => 1});
1.35      matthew  3008:     }
1.13      www      3009: }
1.1       www      3010: 
1.174     raeburn  3011: sub can_toggle_debug {
                   3012:     my $can_toggle = 0;
                   3013:     my $page = 'toggledebug';
                   3014:     if (&LONCAPA::lonauthcgi::can_view($page)) {
                   3015:         $can_toggle = 1;
                   3016:     } elsif (&LONCAPA::lonauthcgi::check_ipbased_access($page)) {
                   3017:         $can_toggle = 1;
                   3018:     }
                   3019:     return $can_toggle;
                   3020: }
                   3021: 
1.186     raeburn  3022: sub can_toggle_namelocking {
                   3023:     my $lockablenames;
                   3024:     my %domconfig =
                   3025:         &Apache::lonnet::get_dom('configuration',['autoupdate'],$env{'user.domain'});
                   3026:     if (ref($domconfig{'autoupdate'}) eq 'HASH') {
                   3027:         if ($domconfig{'autoupdate'}{'run'}) {
                   3028:             my @inststatuses = split(':',$env{'environment.inststatus'});
                   3029:             unless (@inststatuses) {
                   3030:                 @inststatuses = ('default');
                   3031:             }
                   3032:             my %updateable = &updateable_userinfo($domconfig{'autoupdate'},\@inststatuses);
                   3033:             if ($updateable{'lastname'} || $updateable{'firstname'} ||
                   3034:                 $updateable{'middlename'}) { 
                   3035:                 if (ref($domconfig{'autoupdate'}{'lockablenames'}) eq 'ARRAY') {
                   3036:                     unless (@inststatuses) {
                   3037:                         @inststatuses = ('default');
                   3038:                     }
                   3039:                     foreach my $status (@inststatuses) {
                   3040:                         if (grep(/^\Q$status\E$/,@{$domconfig{'autoupdate'}{'lockablenames'}})) {
                   3041:                             $lockablenames = 1;
                   3042:                             last;
                   3043:                         }
                   3044:                     }
                   3045:                 }
                   3046:             }
                   3047:         }
                   3048:     }
                   3049:     return $lockablenames;
                   3050: }
                   3051: 
                   3052: sub updateable_userinfo {
                   3053:     my ($autoupdate,$inststatuses) = @_;
                   3054:     my %updateable;
                   3055:     return %updateable unless ((ref($autoupdate) eq 'HASH') && 
                   3056:                                (ref($inststatuses) eq 'ARRAY'));
                   3057:     if (ref($autoupdate->{'fields'}) eq 'HASH') {
                   3058:         foreach my $status (@{$inststatuses}) {
                   3059:             if (ref($autoupdate->{'fields'}{$status}) eq 'ARRAY') {
                   3060:                 foreach my $field (@{$autoupdate->{'fields'}{$status}}) {
                   3061:                     $updateable{$field} = 1;
                   3062:                 }
                   3063:             }
                   3064:         }
                   3065:     }
                   3066:     return %updateable;
                   3067: }
                   3068: 
1.225     raeburn  3069: sub do_redirect {
                   3070:     my ($r,$url,$msg) = @_;
                   3071:     $r->print(
1.242     raeburn  3072:         &Apache::loncommon::start_page('Loading ...',undef,
                   3073:                                        {'redirect'       => [2,$url]}).
1.225     raeburn  3074:         '<div style="padding:0;clear:both;margin:0;border:0"></div>'."\n".
                   3075:         "$msg\n".
                   3076:         &Apache::loncommon::end_page());
                   3077:     return;
                   3078: }
                   3079: 
1.242     raeburn  3080: sub toggle_options_js {
                   3081:     return <<"ENDSCRIPT";
                   3082: <script type="text/javascript">
                   3083: // <![CDATA[
                   3084: function toggleOptions(form,radioname,divid) {
                   3085:     var num = form.elements[radioname].length;
                   3086:     if (num) {
                   3087:         var setvis = '';
                   3088:         var onvalue = 'user';
                   3089:         if (radioname == 'settimezone') {
                   3090:             onvalue = '1';
                   3091:         }
                   3092:         for (var i=0; i<num; i++) {
                   3093:             if (form.elements[radioname][i].checked) {
                   3094:                 if (form.elements[radioname][i].value == onvalue) {
                   3095:                     if (document.getElementById(divid)) {
                   3096:                         document.getElementById(divid).style.display = 'inline-block';
                   3097:                     }
                   3098:                     setvis = 1;
                   3099:                 }
                   3100:                 break;
                   3101:             }
                   3102:         }
                   3103:         if (!setvis) {
                   3104:             if (document.getElementById(divid)) {
                   3105:                 document.getElementById(divid).style.display = 'none';
                   3106:             }
                   3107:         }
                   3108:     }
                   3109:     return;
                   3110: }
                   3111: // ]]>
                   3112: </script>
                   3113: ENDSCRIPT
                   3114: }
                   3115: 
                   3116: sub selectbox {
                   3117:     my ($name,$value,$readonly,$functionref,@idlist)=@_;
                   3118:     my $selout = '<select name="'.$name.'">';
                   3119:     foreach my $id (@idlist) {
                   3120:         $selout.='<option value="'.$id.'"';
                   3121:         if ($id eq $value) {
                   3122:             $selout.=' selected="selected"';
                   3123:         }
                   3124:         if ($readonly) {
                   3125:             $selout .= ' disabled="disabled"';
                   3126:         }
                   3127:         $selout.='>'.&{$functionref}($id).'</option>';
                   3128:     }
                   3129:     $selout.='</select>';
                   3130:     return $selout;
                   3131: }
                   3132: 
1.1       www      3133: 1;
                   3134: __END__

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