File:  [LON-CAPA] / loncom / interface / lonmenu.pm
Revision 1.258: download - view: text, annotated - select for diffs
Tue Apr 14 23:52:11 2009 UTC (15 years, 1 month ago) by raeburn
Branches: MAIN
CVS tags: HEAD
- HTML documents uploaded directly to a course can be edited by a Course Coordinator (mdc priv).
- "Edit this resource" link displayed in inline menu.
- Link will switch server to course's home server if session is currently hoosted elsewehere (unless a lock is in place).

- Deep linking:
  - origurl and symb args can be included in query string for switchserver call, so switched session will go to the same resource on the new server.

Work in progress.
Logging needed: changes, and by whom.

    1: # The LearningOnline Network with CAPA
    2: # Routines to control the menu
    3: #
    4: # $Id: lonmenu.pm,v 1.258 2009/04/14 23:52:11 raeburn Exp $
    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: #
   28: #
   29: # There are two parameters controlling the action of this module:
   30: #
   31: # browser.interface - if this is 'textual', it overrides the second parameter
   32: # and goes to screen reader PDA mode
   33: #
   34: # environment.remote - if this is 'on', the routines controll the remote
   35: # control, otherwise they render the main window controls; ignored it
   36: # browser.interface is 'textual'
   37: #
   38: 
   39: =head1 NAME
   40: 
   41: Apache::lonmenu
   42: 
   43: =head1 SYNOPSIS
   44: 
   45: Coordinates the response to clicking an image.
   46: 
   47: This is part of the LearningOnline Network with CAPA project
   48: described at http://www.lon-capa.org.
   49: 
   50: =head1 SUBROUTINES
   51: 
   52: =over
   53: 
   54: =item show_course()
   55: 
   56: Little texts
   57: 
   58: =item initlittle()
   59: 
   60: =item menubuttons()
   61: 
   62: This gets called at the top of the body section
   63: 
   64: =item show_return_link()
   65: 
   66: =item registerurl()
   67: 
   68: This gets called in the header section
   69: 
   70: =item innerregister()
   71: 
   72: This gets called in order to register a URL, both with the Remote
   73: and in the body of the document
   74: 
   75: =item loadevents()
   76: 
   77: =item unloadevents()
   78: 
   79: =item startupremote()
   80: 
   81: =item setflags()
   82: 
   83: =item maincall()
   84: 
   85: =item load_remote_msg()
   86: 
   87: =item get_menu_name()
   88: 
   89: =item reopenmenu()
   90: 
   91: =item open()
   92: 
   93: Open the menu
   94: 
   95: =item clear()
   96: 
   97: =item switch()
   98: 
   99: Switch a button or create a link
  100: Switch acts on the javascript that is executed when a button is clicked.  
  101: The javascript is usually similar to "go('/adm/roles')" or "cstrgo(..)".
  102: 
  103: =item secondlevel()
  104: 
  105: =item openmenu()
  106: 
  107: =item inlinemenu()
  108: 
  109: =item rawconfig()
  110: 
  111: =item close()
  112: 
  113: =item footer()
  114: 
  115: =item utilityfunctions()
  116: 
  117: =item serverform()
  118: 
  119: =item constspaceform()
  120: 
  121: =item get_nav_status()
  122: 
  123: =item convert_menu_function()
  124: 
  125: FIXME this needs to move into mydesktab and the other locations 
  126: the text is generated
  127: 
  128: =item hidden_button_check()
  129: 
  130: =item roles_selector()
  131: 
  132: =item jump_to_role()
  133: 
  134: =back
  135: 
  136: =cut
  137: 
  138: package Apache::lonmenu;
  139: 
  140: use strict;
  141: use Apache::lonnet;
  142: use Apache::lonhtmlcommon();
  143: use Apache::loncommon();
  144: use Apache::lonenc();
  145: use Apache::lonlocal;
  146: use LONCAPA qw(:DEFAULT :match);
  147: 
  148: use vars qw(@desklines %category_names %category_members %category_positions $readdesk);
  149: 
  150: 
  151: my @inlineremote;
  152: 
  153: 
  154: 
  155: sub show_course {
  156:     my $course = !$env{'user.adv'};
  157:     if (!$env{'user.adv'}) {
  158: 	foreach my $env (keys(%env)) {
  159: 	    next if ($env !~ m/^user\.priv\./);
  160: 	    if ($env !~ m/^user\.priv\.(?:st|cm)/) {
  161: 		$course = 0;
  162: 		last;
  163: 	    }
  164: 	}
  165:     }
  166:     return $course;
  167: }
  168: 
  169: sub initlittle {
  170:     return &Apache::lonlocal::texthash('ret' => 'Return to Last Location',
  171: 				       'nav' => 'Navigate Contents',
  172: 				       'main' => 'Main Menu',
  173:                                        'roles' => (&show_course()?
  174:                                                     'Courses':'Roles'),
  175:                                        'other' => 'Other Roles',
  176:                                        'docs' => 'Edit Course',
  177:                                        'exit' => 'Logout',
  178:                                        'login' => 'Log In',
  179: 				       'launch' => 'Launch Remote Control',
  180:                                        'groups' => 'Groups',
  181:                                        'gdoc' => 'Group Documents',
  182:                                        );
  183: }
  184: 
  185: sub menubuttons {
  186:     my $forcereg=shift;
  187:     my $registration=shift;
  188:     my $titletable=shift;
  189:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
  190: 					    ['inhibitmenu']);
  191:     if (($env{'form.inhibitmenu'} eq 'yes') ||
  192:         ($ENV{'REQUEST_URI'} eq '/adm/logout')) { return ''; }
  193: 
  194:     if ($env{'request.noversionuri'} =~ m{^/res/adm/pages/}) { return ''; }
  195: 
  196:     my %lt=&initlittle();
  197:     my $navmaps='';
  198:     my $reloadlink='';
  199:     my $docs='';
  200:     my $groups='';
  201:     my $roles='<a href="/adm/roles" target="_top">'.$lt{'roles'}.'</a>';
  202:     my $role_selector;
  203:     my $showgroups=0;
  204:     my ($cnum,$cdom);
  205:     my $escurl=&escape(&Apache::lonenc::check_encrypt($env{'request.noversionuri'}));
  206:     my $escsymb=&escape(&Apache::lonenc::check_encrypt($env{'request.symb'}));
  207: 
  208:     my $logo=&Apache::loncommon::lonhttpdurl("/adm/lonIcons/minilogo.gif");
  209:     $logo = '<a href="/adm/about.html"><img src="'.
  210: 	$logo.'" alt="LON-CAPA Logo" class="LC_noBorder" /></a>';
  211: 
  212:     if ($env{'request.state'} eq 'construct') {
  213:         if (($env{'request.noversionuri'} eq '') || (!defined($env{'request.noversionuri'}))) {
  214:             my $returnurl = $env{'request.filename'};
  215:             $returnurl =~ s:^/home/([^/]+)/public_html/(.*)$:/priv/$1/$2:;
  216:             $escurl = &escape($returnurl);
  217:         }
  218:     }
  219:     if ($env{'request.course.id'}) {
  220:         $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
  221:         $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
  222:         my %coursegroups;
  223:         my $viewgrps_permission =
  224: 	    &Apache::lonnet::allowed('vcg',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''));
  225:         if (!$viewgrps_permission) {
  226:             %coursegroups = &Apache::lonnet::get_active_groups($env{'user.domain'},$env{'user.name'},$cdom,$cnum);
  227: 	}
  228:         if ((keys(%coursegroups) > 0) || ($viewgrps_permission)) {
  229:             $showgroups = 1;
  230:         }
  231:         $role_selector = &roles_selector($cdom,$cnum);
  232:         if ($role_selector) {
  233:             $roles = '<span class="LC_nobreak">'.$role_selector.'&nbsp;&nbsp;<a href="/adm/roles" target="_top">'.$lt{'other'}.'</a></span>';
  234:         }
  235:     }
  236: 
  237:     if ($env{'browser.interface'} eq 'textual') {
  238: # Textual display only
  239:         if ($env{'request.course.id'}) {
  240: 	    $navmaps=(<<ENDNAV);
  241: <a href="/adm/navmaps?postdata=$escurl&amp;postsymb=$escsymb" target="_top">$lt{'nav'}</a>
  242: ENDNAV
  243:             if (&show_return_link()) {
  244:                 my $escreload=&escape('return:');
  245:                 $reloadlink=(<<ENDRELOAD);
  246: <a href="/adm/flip?postdata=$escreload" target="_top">$lt{'ret'}</a>
  247: ENDRELOAD
  248:             }
  249: 	    if (&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) {
  250:                $docs=(<<ENDDOCS);
  251: <a href="/adm/coursedocs" target="_top">$lt{'docs'}</a>
  252: ENDDOCS
  253:             }
  254:             if ($showgroups) {
  255:                 $groups =(<<ENDGROUPS);
  256: <a href="/adm/coursegroups" target="_top">$lt{'groups'}</a>
  257: ENDGROUPS
  258:             }
  259: 	}
  260:         my $form=&serverform();
  261:         my $utility=&utilityfunctions();
  262: 	my $output=(<<ENDMAINMENU);
  263: <script type="text/javascript">
  264: // BEGIN LON-CAPA Internal
  265: $utility
  266: </script>
  267: <div id="LC_top_nav">
  268: <a href="/adm/menu" target="_top">$lt{'main'}</a>
  269: $reloadlink $navmaps $docs $groups $roles
  270: <a href="/adm/logout" target="_top">$lt{'exit'}</a>
  271: </div>
  272: <br />
  273: <script type="text/javascript">
  274: // END LON-CAPA Internal
  275: </script>
  276: $form
  277: ENDMAINMENU
  278:         if ($registration) { $output.=&innerregister($forcereg); }
  279: 	return $output."<hr />";
  280:     } elsif ($env{'environment.remote'} eq 'off') {
  281: # Remote Control is switched off
  282: # figure out colors
  283: 	my %lt=&initlittle();
  284: 
  285:         my $domain=&Apache::loncommon::determinedomain();
  286: 	my $function =&Apache::loncommon::get_users_function();
  287:         my $link=&Apache::loncommon::designparm($function.'.link',$domain);
  288:         my $alink=&Apache::loncommon::designparm($function.'.alink',$domain);
  289:         my $vlink=&Apache::loncommon::designparm($function.'.vlink',$domain);
  290:         my $sidebg=&Apache::loncommon::designparm($function.'.sidebg',$domain);
  291: 	if ($env{'user.name'} eq 'public' && $env{'user.domain'} eq 'public') {
  292: 	    return (<<ENDINLINEMENU);
  293:    <table id="LC_top_nav">
  294:     <tr>
  295:       <td>$logo</td>
  296:       <td></td>
  297:       <td class="LC_top_nav_login">
  298:         <a href="/adm/roles" target="_top">$lt{'login'}</a>
  299:      </td>
  300:     </tr>
  301:   </table>
  302: ENDINLINEMENU
  303:         }
  304:         $roles = '<a href="/adm/roles" target="_top">'.$lt{'roles'}.'</a>';
  305: # Do we have a NAV link?
  306:         if ($env{'request.course.id'}) {
  307: 	    my $link='/adm/navmaps?postdata='.$escurl.'&amp;postsymb='.
  308: 		$escsymb;
  309: 	    if ($env{'environment.remotenavmap'} eq 'on') {
  310: 		$link="javascript:gonav('".$link."')";
  311: 	    }
  312: 	    $navmaps=(<<ENDNAV);
  313: <li><a href="$link" target="_top">$lt{'nav'}</a></li>
  314: ENDNAV
  315:             my $is_group = (&Apache::loncommon::course_type() eq 'Group');
  316: 	    if (&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) {
  317:                 my $text = ($is_group) ? $lt{'gdoc'} : $lt{'docs'};
  318: 		$docs=(<<ENDDOCS);
  319: <li><a href="/adm/coursedocs" target="_top">$text</a></li>
  320: ENDDOCS
  321:             }
  322:             if ($showgroups) {
  323:                 $groups =(<<ENDGROUPS);
  324: <li><a href="/adm/coursegroups" target="_top">$lt{'groups'}</a></li>
  325: ENDGROUPS
  326:             }
  327: 	    if (&show_return_link()) {
  328:                 my $escreload=&escape('return:');
  329:                 $reloadlink=(<<ENDRELOAD);
  330: <li><a href="/adm/flip?postdata=$escreload" target="_top">$lt{'ret'}</a></li>
  331: ENDRELOAD
  332:             }
  333:             if ($role_selector) {
  334:             	#$roles = '<td>'.$role_selector.'</td><td><a href="/adm/roles" target="_top">'.$lt{'other'}.'</a></td>';
  335: 				$role_selector = '<li>'.$role_selector.'</li>';
  336:             }
  337:         }
  338: 	if (($env{'request.state'} eq 'construct') && ($env{'request.course.id'})) {
  339: 	    my $escreload=&escape('return:');
  340: 	    $reloadlink=(<<ENDCRELOAD);
  341: <li><a href="/adm/flip?postdata=$escreload" target="_top">$lt{'ret'}</a></li>
  342: ENDCRELOAD
  343:         }
  344:         my $reg='';
  345:         if ($registration) {
  346:            $reg=&innerregister($forcereg,$titletable);
  347:         }
  348:         my $form=&serverform();
  349: 	my $utility=&utilityfunctions();
  350: 
  351: 	my $messagelink = "";
  352: 	if(&Apache::lonmsg::mynewmail()){
  353: 		$messagelink = '<a href="javascript:go(\'/adm/communicate\');">Message(new)</a>'
  354: 	}else{
  355: 		$messagelink = '<a href="javascript:go(\'/adm/communicate\');">Message</a>'
  356: 	}
  357:         my $helplink=&Apache::loncommon::top_nav_help('Help');
  358: 	return (<<ENDINLINEMENU);
  359: <script type="text/javascript">
  360: // BEGIN LON-CAPA Internal
  361: // <![CDATA[
  362: $utility
  363: // ]]>
  364: </script>
  365: <ol class="LC_smallMenu LC_right">
  366: 	<li>$logo</li>
  367: 	<li>$messagelink</li>
  368: 	<li>$roles</li>
  369: 	<li>$helplink</li>
  370: 	<li><a href="/adm/logout" target="_top">$lt{'exit'}</a></li>
  371: </ol>
  372: <ol id="LC_TabMainMenuContent">
  373: <li><a href="/adm/menu" target="_top">$lt{'main'}</a></li>
  374: $reloadlink
  375: $navmaps
  376: $docs
  377: $groups
  378: $role_selector
  379: </ol>
  380: $form
  381: <script type="text/javascript">
  382: // END LON-CAPA Internal
  383: </script>
  384: <br clear="all" />
  385: $reg
  386: ENDINLINEMENU
  387:     } else {
  388: 	return '';
  389:     }
  390: }
  391: 
  392: sub show_return_link {
  393:     return (($env{'request.noversionuri'}=~m{^/(res|public)/} &&
  394: 	     $env{'request.symb'} eq '')
  395: 	    ||
  396: 	    ($env{'request.noversionuri'}=~ m{^/cgi-bin/printout.pl})
  397: 	    ||
  398: 	    (($env{'request.noversionuri'}=~/^\/adm\//) &&
  399: 	     ($env{'request.noversionuri'}!~/^\/adm\/wrapper\//) &&
  400: 	     ($env{'request.noversionuri'}!~
  401: 	      m[^/adm/.*/(smppg|bulletinboard|aboutme)($|\?)])
  402: 	     ));
  403: }
  404: 
  405: 
  406: sub registerurl {
  407:     my ($forcereg) = @_;
  408:     my $result = '';
  409:     if ($env{'request.noversionuri'} =~ m{^/res/adm/pages/}) { return ''; }
  410:     my $force_title='';
  411:     if ($env{'request.state'} eq 'construct') {
  412: 	$force_title=&Apache::lonxml::display_title();
  413:     }
  414:     if (($env{'browser.interface'} eq 'textual') ||
  415:         ($env{'environment.remote'} eq 'off') ||
  416:         ((($env{'request.publicaccess'}) || 
  417:          (!&Apache::lonnet::is_on_map(
  418: 	   &unescape($env{'request.noversionuri'})))) &&
  419:         (!$forcereg))) {
  420:  	return $result.
  421:           '<script type="text/javascript">function LONCAPAreg(){;} function LONCAPAstale(){}</script>'.$force_title;
  422:     }
  423: # Graphical display after login only
  424:     if ($env{'request.registered'} && !$forcereg) { return ''; }
  425:     $result.=&innerregister($forcereg);
  426:     return $result.$force_title;
  427: }
  428: 
  429: sub innerregister {
  430:     my ($forcereg, $titletable) = @_;
  431:     my $result = '';
  432:     my ($uname,$thisdisfn);
  433:     my $const_space = ($env{'request.state'} eq 'construct');
  434:     my $is_const_dir = 0;
  435: 
  436:     if ($env{'request.noversionuri'} =~ m{^/res/adm/pages/}) { return ''; }
  437: 
  438:     $env{'request.registered'} = 1;
  439: 
  440:     my $textinter=($env{'browser.interface'} eq 'textual');
  441:     my $noremote=($env{'environment.remote'} eq 'off');
  442:     
  443:     my $textual=($textinter || $noremote);
  444: 
  445:     undef(@inlineremote);
  446: 
  447:     my $reopen=&Apache::lonmenu::reopenmenu();
  448: 
  449:     my $newmail='';
  450:     if ($noremote) {
  451: 	$newmail='<table id="LC_nav_location"><tr>';
  452:     }
  453:     if (&Apache::lonmsg::newmail()) { 
  454: 	if ($textual) {
  455: 	    $newmail.= '<td class="LC_new_mail">
  456:                    <a href="/adm/communicate" target="_top">'.
  457: 		   &mt('You have new messages').'</a></td>';
  458: 	} else {
  459: 	    $newmail= 'swmenu.setstatus("you have","messages");';
  460: 	}
  461:     } 
  462:     if (($textual) 
  463: 	     && ($env{'request.symb'}) 
  464: 	     && ($env{'request.course.id'})) {
  465: 	$newmail.= '<td class="LC_current_location">';
  466: 	my ($mapurl,$rid,$resurl)=
  467: 	    &Apache::lonnet::decode_symb(&Apache::lonnet::symbread());
  468:         my $coursetitle=$env{'course.'.$env{'request.course.id'}.'.description'};
  469:         $newmail.=$coursetitle;
  470:         my $maptitle=&Apache::lonnet::gettitle($mapurl);
  471: 	my $restitle=&Apache::lonnet::gettitle(&Apache::lonnet::symbread());
  472:         if ($maptitle && ($maptitle ne 'default.sequence') && ($maptitle ne $coursetitle)) {
  473: 	    $newmail.=', '.$maptitle;
  474:         }
  475:         if ($restitle) {
  476: 	    $newmail.=': '.$restitle;
  477:         }
  478:         $newmail.='&nbsp;&nbsp;&nbsp;</td>';
  479:     }
  480:     if ($env{'request.state'} eq 'construct') {
  481:         $newmail = $titletable;
  482:     } else {
  483: 	if ($noremote) {
  484: 	    $newmail.='</tr></table>';
  485: 	}
  486:     }
  487:     my $timesync=($textual?'':'swmenu.syncclock(1000*'.time.');');
  488:     my $tablestart=($noremote?'<table id="LC_menubuttons">':'').
  489: 	($textinter?'<br /><a href="#content">'.&mt('Skip to Content').'</a><br />':'');
  490:     my $tableend=($noremote?'</table>':'').($textinter?'<a name="content" />':'');
  491: # =============================================================================
  492: # ============================ This is for URLs that actually can be registered
  493:     if (($env{'request.noversionuri'}!~m|^/(res/)*adm/|) || ($forcereg)) {
  494: # -- This applies to homework problems for users with grading privileges
  495: 	my $crs='/'.$env{'request.course.id'};
  496: 	if ($env{'request.course.sec'}) {
  497: 	    $crs.='_'.$env{'request.course.sec'};
  498: 	}
  499: 	$crs=~s/\_/\//g;
  500: 
  501:         my $hwkadd='';
  502:         if ($env{'request.symb'} ne '' &&
  503: 	    $env{'request.filename'}=~/\.(problem|exam|quiz|assess|survey|form|task)$/) {
  504: 	    if (&Apache::lonnet::allowed('mgr',$crs)) {
  505: 		$hwkadd.=&switch('','',7,2,'pgrd.gif','problem[_1]','grades[_3]',
  506:                        "gocmd('/adm/grades','gradingmenu')",
  507:                        'Modify user grades for this assessment resource');
  508:             } elsif (&Apache::lonnet::allowed('vgr',$crs)) {
  509: 		$hwkadd.=&switch('','',7,2,'subm.gif','view sub-[_1]','missions[_1]',
  510:                        "gocmd('/adm/grades','submission')",
  511: 		       'View user submissions for this assessment resource');
  512:             }
  513: 	}
  514: 	if ($env{'request.symb'} ne '' &&
  515: 	    &Apache::lonnet::allowed('opa',$crs)) {
  516: 	    $hwkadd.=&switch('','',7,3,'pparm.gif','problem[_2]','parms[_2]',
  517: 			     "gocmd('/adm/parmset','set')",
  518: 			     'Modify parameter settings for this resource');
  519: 	}
  520: # -- End Homework
  521:         ###
  522:         ### Determine whether or not to display the 'cstr' button for this
  523:         ### resource
  524:         ###
  525:         my $editbutton = '';
  526:         my $noeditbutton = 1;
  527:         my ($cnum,$cdom);
  528:         if ($env{'request.course.id'}) {
  529:             $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
  530:             $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
  531:         }
  532:         if ($env{'user.author'}) {
  533:             if ($env{'request.role'}=~/^(aa|ca|au)/) {
  534:                 # Set defaults for authors
  535:                 my ($top,$bottom) = ('con-','struct');
  536:                 my $action = "go('/priv/".$env{'user.name'}."');";
  537:                 my $cadom  = $env{'request.role.domain'};
  538:                 my $caname = $env{'user.name'};
  539:                 my $desc = "Enter my construction space";
  540:                 # Set defaults for co-authors
  541:                 if ($env{'request.role'} =~ /^ca/) { 
  542:                     ($cadom,$caname)=($env{'request.role'}=~/($match_domain)\/($match_username)$/);
  543:                     ($top,$bottom) = ('co con-','struct');
  544:                     $action = "go('/priv/".$caname."');";
  545:                     $desc = "Enter construction space as co-author";
  546:                 } elsif ($env{'request.role'} =~ /^aa/) {
  547:                     ($cadom,$caname)=($env{'request.role'}=~/($match_domain)\/($match_username)$/);
  548:                     ($top,$bottom) = ('co con-','struct');
  549:                     $action = "go('/priv/".$caname."');";
  550:                     $desc = "Enter construction space as assistant co-author";
  551:                 }
  552:                 # Check that we are on the correct machine
  553:                 my $home = &Apache::lonnet::homeserver($caname,$cadom);
  554: 		my $allowed=0;
  555: 		my @ids=&Apache::lonnet::current_machine_ids();
  556: 		foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } }
  557: 		if (!$allowed) {
  558: 		    $editbutton=&switch('','',6,1,$top,,$bottom,$action,$desc);
  559:                     $noeditbutton = 0;
  560:                 }
  561:             }
  562:             ##
  563:             ## Determine if user can edit url.
  564:             ##
  565:             my $cfile='';
  566:             my $cfuname='';
  567:             my $cfudom='';
  568:             my $uploaded;
  569:             if ($env{'request.filename'}) {
  570:                 my $file=&Apache::lonnet::declutter($env{'request.filename'});
  571:                 if (defined($cnum) && defined($cdom)) {
  572:                     $uploaded = &is_course_upload($file,$cnum,$cdom);
  573:                 }
  574:                 if (!$uploaded) {
  575:                     $file=~s/^($match_domain)\/($match_username)/\/priv\/$2/;
  576:                     # Check that the user has permission to edit this resource
  577:                     ($cfuname,$cfudom)=&Apache::loncacc::constructaccess($file,$1);
  578:                     if (defined($cfudom)) {
  579: 		        my $home=&Apache::lonnet::homeserver($cfuname,$cfudom);
  580: 		        my $allowed=0;
  581: 		        my @ids=&Apache::lonnet::current_machine_ids();
  582: 		        foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } }
  583: 		        if ($allowed) {
  584:                             $cfile=$file;
  585:                         }
  586:                     }
  587:                 }
  588:             }
  589:             # Finally, turn the button on or off
  590:             if ($cfile && !$const_space) {
  591:                 $editbutton=&switch
  592:                     ('','',6,1,'pcstr.gif','edit[_1]','resource[_2]',
  593:                      "go('".$cfile."');","Edit this resource");
  594:                 $noeditbutton = 0;
  595:             } elsif ($editbutton eq '') {
  596:                 $editbutton=&clear(6,1);
  597:             }
  598:         }
  599:         if (($noeditbutton) && ($env{'request.filename'})) { 
  600:             if (&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) {
  601:                 my $file=&Apache::lonnet::declutter($env{'request.filename'});
  602:                 if (defined($cnum) && defined($cdom)) {
  603:                     if (&is_course_upload($file,$cnum,$cdom)) {
  604:                         my $cfile = &edit_course_upload($file,$cnum,$cdom);
  605:                         if ($cfile) {
  606:                             $editbutton=&switch
  607:                                         ('','',6,1,'pcstr.gif','edit[_1]',
  608:                                          'resource[_2]',"go('".$cfile."');",
  609:                                          'Edit this resource');
  610:                         }
  611:                     }
  612:                 }
  613:             }
  614:         }
  615:         ###
  616:         ###
  617: # Prepare the rest of the buttons
  618:         my $menuitems;
  619:         if ($const_space) {
  620: 	    my ($uname,$thisdisfn) =
  621: 		($env{'request.filename'}=~m|^/home/([^/]+)/public_html/(.*)|);
  622:             my $currdir = '/priv/'.$uname.'/'.$thisdisfn;
  623:             if ($currdir =~ m-/$-) {
  624:                 $is_const_dir = 1;
  625:             } else {
  626:                 $currdir =~ s#[^/]+$##;
  627: 		my $cleandisfn = &Apache::loncommon::escape_single($thisdisfn);
  628: 		my $esc_currdir = &Apache::loncommon::escape_single($currdir);
  629:                 $menuitems=(<<ENDMENUITEMS);
  630: s&6&1&list.gif&list[_1]&dir[_1]&golist('$esc_currdir')&List current directory
  631: s&6&2&rtrv.gif&retrieve[_1]&version[_1]&gocstr('/adm/retrieve','/~$uname/$cleandisfn')&Retrieve old version
  632: s&6&3&pub.gif&publish[_1]&resource[_1]&gocstr('/adm/publish','/~$uname/$cleandisfn')&Publish this resource
  633: s&7&1&del.gif&delete[_1]&resource[_2]&gocstr('/adm/cfile?action=delete','/~$uname/$cleandisfn')&Delete this resource
  634: s&7&2&prt.gif&prepare[_1]&printout[_1]&gocstr('/adm/printout','/~$uname/$cleandisfn')&Prepare a printable document
  635: ENDMENUITEMS
  636:             }
  637:         } elsif ( defined($env{'request.course.id'}) && 
  638: 		 $env{'request.symb'} ne '' ) {
  639: 	    $menuitems=(<<ENDMENUITEMS);
  640: c&3&1
  641: s&2&1&back.gif&backward[_1]&&gopost('/adm/flip','back:'+currentURL)&Go to the previous resource in the course sequence&&1
  642: s&2&3&forw.gif&forward[_1]&&gopost('/adm/flip','forward:'+currentURL)&Go to the next resource in the course sequence&&3
  643: c&6&3
  644: c&8&1
  645: c&8&2
  646: s&8&3&prt.gif&prepare[_1]&printout[_1]&gopost('/adm/printout',currentURL)&Prepare a printable document
  647: s&9&1&sbkm.gif&set[_1]&bookmark[_2]&set_bookmark()&Set a bookmark for this resource&&1
  648: ENDMENUITEMS
  649: 
  650: my $currentURL = &Apache::loncommon::get_symb();
  651: my ($symb_old,$symb_old_enc) = &Apache::loncommon::clean_symb($currentURL);
  652: my $annotation = &Apache::loncommon::get_annotation($symb_old,$symb_old_enc);
  653: $menuitems.="s&9&3&";
  654: if(length($annotation) > 0){
  655: 	$menuitems.="anot2.gif";
  656: }else{
  657: 	$menuitems.="anot.gif";
  658: }
  659: $menuitems.="&anno-[_1]&tations[_1]&annotate()&";
  660: $menuitems.="Make notes and annotations about this resource&&1\n";
  661: 
  662:             unless ($env{'request.noversionuri'}=~/\/(bulletinboard|smppg|navmaps|syllabus|aboutme)(\?|$)/) {
  663: 		if (!$env{'request.enc'}) {
  664: 		    $menuitems.=(<<ENDREALRES);
  665: s&6&3&catalog.gif&catalog[_1]&info[_1]&catalog_info()&Show Metadata
  666: ENDREALRES
  667:                 }
  668: 	        $menuitems.=(<<ENDREALRES);
  669: s&8&1&eval.gif&evaluate[_1]&this[_1]&gopost('/adm/evaluate',currentURL,1)&Provide my evaluation of this resource
  670: s&8&2&fdbk.gif&feedback[_1]&discuss[_1]&gopost('/adm/feedback',currentURL,1)&Provide feedback messages or contribute to the course discussion about this resource
  671: ENDREALRES
  672: 	    }
  673:         }
  674: 	if ($env{'request.uri'} =~ /^\/res/) {
  675: 	    $menuitems .= (<<ENDMENUITEMS);
  676: s&8&3&prt.gif&prepare[_1]&printout[_1]&gopost('/adm/printout',currentURL)&Prepare a printable document
  677: ENDMENUITEMS
  678: 	}
  679:         my $buttons='';
  680:         foreach (split(/\n/,$menuitems)) {
  681: 	    my ($command,@rest)=split(/\&/,$_);
  682:             my $idx=10*$rest[0]+$rest[1];
  683:             if (&hidden_button_check() eq 'yes') {
  684:                 if ($idx == 21 ||$idx == 23) {
  685:                     $buttons.=&switch('','',@rest);
  686:                 } else {
  687:                     $buttons.=&clear(@rest);
  688:                 }
  689:             } else {  
  690:                 if ($command eq 's') {
  691: 	            $buttons.=&switch('','',@rest);
  692:                 } else {
  693:                     $buttons.=&clear(@rest);
  694:                 }
  695:             }
  696:         }
  697: 
  698:         if ($textual) {
  699: 	    my $addremote=0;
  700: 	    foreach (@inlineremote) { if ($_ ne '') { $addremote=1; } }
  701: 	    my $inlinebuttons='';
  702: 	    if ($addremote) {
  703: # Registered, textual output
  704: 		if ($env{'browser.interface'} eq 'textual') {
  705: 		    $inlinebuttons=
  706:                         join('',map { (defined($_)?$_:'') } @inlineremote);
  707: 		} else {
  708:                     if ($env{'environment.icons'} eq 'iconsonly') {
  709:                         $inlinebuttons=(<<ENDARROWSINLINE);
  710: <tr><td>
  711: $inlineremote[21] $inlineremote[23]
  712: ENDARROWSINLINE
  713:                         if (&hidden_button_check() ne 'yes') {
  714:                             $inlinebuttons .= (<<ENDINLINEICONS);
  715: $inlineremote[61] $inlineremote[63]
  716: $inlineremote[71] $inlineremote[72] $inlineremote[73]
  717: $inlineremote[81] $inlineremote[82] $inlineremote[83]
  718: $inlineremote[91] $inlineremote[92] $inlineremote[93]</td></tr>
  719: ENDINLINEICONS
  720:                         }
  721:                     } else {
  722: 			if ($inlineremote[21] ne '' || $inlineremote[23] ne '') {
  723: 			    $inlinebuttons=(<<ENDFIRSTLINE);
  724: <tr><td>$inlineremote[21]</td><td>&nbsp;</td><td>$inlineremote[23]</td></tr>
  725: ENDFIRSTLINE
  726:                         }
  727:                         if (&hidden_button_check() ne 'yes') { 
  728: 			    foreach my $row (6..9) {
  729: 				if ($inlineremote[${row}.'1'] ne ''
  730: 				    || $inlineremote[$row.'2'] ne ''
  731: 				    || $inlineremote[$row.'3'] ne '') {
  732: 				    $inlinebuttons .= <<"ENDLINE";
  733: <tr><td>$inlineremote["${row}1"]</td><td>$inlineremote["${row}2"]</td><td>$inlineremote["${row}3"]</td></tr>
  734: ENDLINE
  735: 				}
  736: 			    }
  737: 			}
  738: 		    }
  739: 		}
  740: 	    }
  741: 	    $result =(<<ENDREGTEXT);
  742: <script type="text/javascript">
  743: // BEGIN LON-CAPA Internal
  744: </script>
  745: $timesync
  746: $tablestart
  747: $inlinebuttons
  748: $tableend
  749: $newmail
  750: <script type="text/javascript">
  751: // END LON-CAPA Internal
  752: </script>
  753: 
  754: ENDREGTEXT
  755: # Registered, graphical output
  756:         } else {
  757: 	    my $requri=&Apache::lonnet::clutter(&Apache::lonnet::fixversion((split(/\?/,$env{'request.noversionuri'}))[0]));
  758: 	    $requri=&Apache::lonenc::check_encrypt(&unescape($requri));
  759: 	    my $cursymb=&Apache::lonenc::check_encrypt($env{'request.symb'});
  760: 	    my $navstatus=&get_nav_status();
  761: 	    my $clearcstr;
  762: 
  763: 	    if ($env{'user.adv'}) { $clearcstr='clearbut(6,1)'; }
  764: 	    $result = (<<ENDREGTHIS);
  765:      
  766: <script type="text/javascript">
  767: // BEGIN LON-CAPA Internal
  768: var swmenu=null;
  769: 
  770:     function LONCAPAreg() {
  771: 	  swmenu=$reopen;
  772:           swmenu.clearTimeout(swmenu.menucltim);
  773:           $timesync
  774:           $newmail
  775:           $buttons
  776: 	  swmenu.currentURL="$requri";
  777:           swmenu.reloadURL=swmenu.currentURL+window.location.search;
  778:           swmenu.currentSymb="$cursymb";
  779:           swmenu.reloadSymb="$cursymb";
  780:           swmenu.currentStale=0;
  781: 	  $navstatus
  782:           $hwkadd
  783:           $editbutton
  784:     }
  785: 
  786:     function LONCAPAstale() {
  787: 	  swmenu=$reopen
  788:           swmenu.currentStale=1;
  789:           if (swmenu.reloadURL!='' && swmenu.reloadURL!= null) { 
  790:              swmenu.switchbutton
  791:              (3,1,'reload.gif','return','location','go(reloadURL)','Return to the last known location in the course sequence');
  792: 	  }
  793:           swmenu.clearbut(7,2);
  794:           swmenu.clearbut(7,3);
  795:           swmenu.menucltim=swmenu.setTimeout(
  796:  'clearbut(2,1);clearbut(2,3);clearbut(8,1);clearbut(8,2);clearbut(8,3);'+
  797:  'clearbut(9,1);clearbut(9,3);clearbut(6,3);$clearcstr',
  798: 			  2000);
  799:       }
  800: 
  801: // END LON-CAPA Internal 
  802: </script>
  803: ENDREGTHIS
  804:         }
  805: # =============================================================================
  806:     } else {
  807: # ========================================== This can or will not be registered
  808:         if ($textual) {
  809: # Not registered, textual
  810: 	    $result= (<<ENDDONOTREGTEXT);
  811: ENDDONOTREGTEXT
  812:         } else {
  813: # Not registered, graphical
  814:            $result = (<<ENDDONOTREGTHIS);
  815: 
  816: <script type="text/javascript">
  817: // BEGIN LON-CAPA Internal
  818: var swmenu=null;
  819: 
  820:     function LONCAPAreg() {
  821: 	  swmenu=$reopen
  822:           $timesync
  823:           swmenu.currentStale=1;
  824:           swmenu.clearbut(2,1);
  825:           swmenu.clearbut(2,3);
  826:           swmenu.clearbut(8,1);
  827:           swmenu.clearbut(8,2);
  828:           swmenu.clearbut(8,3);
  829:           if (swmenu.currentURL) {
  830:              swmenu.switchbutton
  831:               (3,1,'reload.gif','return','location','go(currentURL)');
  832:  	  } else {
  833: 	      swmenu.clearbut(3,1);
  834:           }
  835:     }
  836: 
  837:     function LONCAPAstale() {
  838:     }
  839: 
  840: // END LON-CAPA Internal
  841: </script>
  842: ENDDONOTREGTHIS
  843:        }
  844: # =============================================================================
  845:     }
  846:     return $result;
  847: }
  848: 
  849: sub is_course_upload {
  850:     my ($file,$cnum,$cdom) = @_;
  851:     my $uploadpath = &LONCAPA::propath($cdom,$cnum);
  852:     $uploadpath =~ s{^\/}{};
  853:     if (($file =~ m{^\Q$uploadpath\E/userfiles/docs/}) ||
  854:         ($file =~ m{^userfiles/\Q$cdom\E/\Q$cnum\E/docs/})) {
  855:         return 1;
  856:     }
  857:     return;
  858: }
  859: 
  860: sub edit_course_upload {
  861:     my ($file,$cnum,$cdom) = @_;
  862:     my $cfile;
  863:     if ($file =~/\.(htm|html|css|js|txt)$/) {
  864:         my $ext = $1;
  865:         my $url = &Apache::lonnet::hreflocation('',$file);
  866:         my $home = &Apache::lonnet::homeserver($cnum,$cdom);
  867:         my @ids=&Apache::lonnet::current_machine_ids();
  868:         my $dest;
  869:         if ($home && grep(/^\Q$home\E$/,@ids)) {
  870:             $dest = $url.'?forceedit=1';
  871:         } else {
  872:             unless (&Apache::lonnet::get_locks()) {
  873:                 $dest = '/adm/switchserver?otherserver='.
  874:                         $home.'&role='.$env{'request.role'}.
  875:                         '&url='.$url.'&forceedit=1';
  876:             }
  877:         }
  878:         if ($dest) {
  879:             $cfile = &HTML::Entities::encode($dest,'"<>&');
  880:         }
  881:     }
  882:     return $cfile;
  883: }
  884: 
  885: sub loadevents() {
  886:     if ($env{'request.state'} eq 'construct' ||
  887: 	$env{'request.noversionuri'} =~ m{^/res/adm/pages/}) { return ''; }
  888:     return 'LONCAPAreg();';
  889: }
  890: 
  891: sub unloadevents() {
  892:     if ($env{'request.state'} eq 'construct' ||
  893: 	$env{'request.noversionuri'} =~ m{^/res/adm/pages/}) { return ''; }
  894:     return 'LONCAPAstale();';
  895: }
  896: 
  897: 
  898: sub startupremote {
  899:     my ($lowerurl)=@_;
  900:     if (($env{'browser.interface'} eq 'textual') ||
  901:         ($env{'environment.remote'} eq 'off')) {
  902:      return ('<meta HTTP-EQUIV="Refresh" CONTENT="0.5; url='.$lowerurl.'" />');
  903:     }
  904: #
  905: # The Remote actually gets launched!
  906: #
  907:     my $configmenu=&rawconfig();
  908:     my $esclowerurl=&escape($lowerurl);
  909:     my $message=&mt('"Waiting for Remote Control window to load: "+[_1]','waited');
  910:     return(<<ENDREMOTESTARTUP);
  911: <script type="text/javascript">
  912: var timestart;
  913: function wheelswitch() {
  914:     if (typeof(document.wheel) != 'undefined') {
  915: 	if (typeof(document.wheel.spin) != 'undefined') {
  916: 	    var date=new Date();
  917: 	    var waited=Math.round(30-((date.getTime()-timestart)/1000));
  918: 	    document.wheel.spin.value=$message;
  919: 	}
  920:     }
  921:    if (window.status=='|') { 
  922:       window.status='/'; 
  923:    } else {
  924:       if (window.status=='/') {
  925:          window.status='-';
  926:       } else {
  927:          if (window.status=='-') { 
  928:             window.status='\\\\'; 
  929:          } else {
  930:             if (window.status=='\\\\') { window.status='|'; }
  931:          }
  932:       }
  933:    } 
  934: }
  935: 
  936: // ---------------------------------------------------------- The wait function
  937: var canceltim;
  938: function wait() {
  939:    if ((menuloaded==1) || (tim==1)) {
  940:       window.status='Done.';
  941:       if (tim==0) {
  942:          clearTimeout(canceltim);
  943:          $configmenu
  944:          window.location='$lowerurl';  
  945:       } else {
  946: 	  window.location='/adm/remote?action=collapse&url=$esclowerurl';
  947:       }
  948:    } else {
  949:       wheelswitch();
  950:       setTimeout('wait();',200);
  951:    }
  952: }
  953: 
  954: function main() {
  955:    canceltim=setTimeout('tim=1;',30000);
  956:    window.status='-';
  957:    var date=new Date();
  958:    timestart=date.getTime();
  959:    wait();
  960: }
  961: 
  962: </script>
  963: ENDREMOTESTARTUP
  964: }
  965: 
  966: sub setflags() {
  967:     return(<<ENDSETFLAGS);
  968: <script type="text/javascript">
  969:     menuloaded=0;
  970:     tim=0;
  971: </script>
  972: ENDSETFLAGS
  973: }
  974: 
  975: sub maincall() {
  976:     if (($env{'browser.interface'} eq 'textual') ||
  977:         ($env{'environment.remote'} eq 'off')) { return ''; }
  978:     return(<<ENDMAINCALL);
  979: <script type="text/javascript">
  980:     main();
  981: </script>
  982: ENDMAINCALL
  983: }
  984: 
  985: sub load_remote_msg {
  986:     my ($lowerurl)=@_;
  987: 
  988:     if (($env{'browser.interface'} eq 'textual') ||
  989:         ($env{'environment.remote'} eq 'off')) { return ''; }
  990: 
  991:     my $esclowerurl=&escape($lowerurl);
  992:     my $link=&mt('<a href="[_1]">Continue</a> on in Inline Menu mode',
  993: 		 "/adm/remote?action=collapse&amp;url=$esclowerurl");
  994:     return(<<ENDREMOTEFORM);
  995: <p>
  996: <form name="wheel">
  997: <input name="spin" type="text" size="60" />
  998: </form>
  999: </p>
 1000: <p>$link</p>
 1001: ENDREMOTEFORM
 1002: }
 1003: 
 1004: sub get_menu_name {
 1005:     my $hostid = $Apache::lonnet::perlvar{'lonHostID'};
 1006:     $hostid =~ s/\W//g;
 1007:     return 'LCmenu'.$hostid;
 1008: }
 1009: 
 1010: 
 1011: sub reopenmenu {
 1012:    if (($env{'browser.interface'} eq 'textual') ||
 1013:        ($env{'environment.remote'} eq 'off')) { return ''; }
 1014:    my $menuname = &get_menu_name();
 1015:    my $nothing = &Apache::lonhtmlcommon::javascript_nothing();
 1016:    return('window.open('.$nothing.',"'.$menuname.'","",false);');
 1017: } 
 1018: 
 1019: 
 1020: sub open {
 1021:     my $returnval='';
 1022:     if (($env{'browser.interface'} eq 'textual') ||
 1023:         ($env{'environment.remote'} eq 'off')) { 
 1024: 	return '<script type="text/javascript">self.name="loncapaclient";</script>';
 1025:     }
 1026:     my $menuname = &get_menu_name();
 1027:     
 1028: #    unless (shift eq 'unix') {
 1029: # resizing does not work on linux because of virtual desktop sizes
 1030: #       $returnval.=(<<ENDRESIZE);
 1031: #if (window.screen) {
 1032: #    self.resizeTo(screen.availWidth-215,screen.availHeight-55);
 1033: #    self.moveTo(190,15);
 1034: #}
 1035: #ENDRESIZE
 1036: #    }
 1037:     $returnval.=(<<ENDOPEN);
 1038: window.status='Opening LON-CAPA Remote Control';
 1039: var menu=window.open("/res/adm/pages/menu.html","$menuname",
 1040: "height=375,width=150,scrollbars=no,menubar=no,top=5,left=5,screenX=5,screenY=5");
 1041: self.name='loncapaclient';
 1042: ENDOPEN
 1043:     return '<script type="text/javascript">'.$returnval.'</script>';
 1044: }
 1045: 
 1046: 
 1047: # ================================================================== Raw Config
 1048: 
 1049: sub clear {
 1050:     my ($row,$col)=@_;
 1051:     unless (($env{'browser.interface'} eq 'textual') ||
 1052:             ($env{'environment.remote'} eq 'off')) {
 1053:        return "\n".qq(window.status+='.';swmenu.clearbut($row,$col););
 1054:    } else { 
 1055:        $inlineremote[10*$row+$col]='';
 1056:        return ''; 
 1057:    }
 1058: }
 1059: 
 1060: # ============================================ Switch a button or create a link
 1061: # Switch acts on the javascript that is executed when a button is clicked.  
 1062: # The javascript is usually similar to "go('/adm/roles')" or "cstrgo(..)".
 1063: 
 1064: sub switch {
 1065:     my ($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat,$nobreak)=@_;
 1066:     $act=~s/\$uname/$uname/g;
 1067:     $act=~s/\$udom/$udom/g;
 1068:     $top=&mt($top);
 1069:     $bot=&mt($bot);
 1070:     $desc=&mt($desc);
 1071:     if (($env{'environment.remote'} ne 'off') || ($env{'environment.icons'} eq 'classic')) {
 1072:        $img=&mt($img);
 1073:     }
 1074:     my $idx=10*$row+$col;
 1075:     $category_members{$cat}.=':'.$idx;
 1076: 
 1077:     unless (($env{'browser.interface'} eq 'textual')  ||
 1078:             ($env{'environment.remote'} eq 'off')) {
 1079: # Remote
 1080:        return "\n".
 1081:  qq(window.status+='.';swmenu.switchbutton($row,$col,"$img","$top","$bot","$act","$desc"););
 1082:    } elsif ($env{'browser.interface'} eq 'textual') {
 1083: # Accessibility
 1084:        if ($nobreak==2) { return ''; }
 1085:        my $text=$top.' '.$bot;
 1086:        $text=~s/\s*\-\s*//gs;
 1087:        if ($nobreak) {
 1088: 	   $inlineremote[$idx]=
 1089: 	       '<a href="javascript:'.$act.';">'.$text.'</a>';
 1090:        } else {
 1091: 	   $inlineremote[$idx]="\n<br />".
 1092: 	       $desc.' <a href="javascript:'.$act.';">'.$text.'</a>';
 1093:        }
 1094:    } else {
 1095: # Inline Remote
 1096:        if ($env{'environment.icons'} ne 'classic') {
 1097:           $img=~s/\.gif$/\.png/;
 1098:        }
 1099:        if ($nobreak==2) { return ''; }
 1100:        my $text=$top.' '.$bot;
 1101:        $text=~s/\s*\-\s*//gs;
 1102: 
 1103:        my $pic=
 1104: 	   '<img alt="'.$text.'" src="'.
 1105: 	   &Apache::loncommon::lonhttpdurl('/res/adm/pages/'.$img).
 1106: 	   '" align="'.($nobreak==3?'right':'left').'" class="LC_noBorder" />';
 1107:        if ($env{'browser.interface'} eq 'faketextual') {
 1108: # Accessibility
 1109: 	   if ($nobreak==3) {
 1110: 	       $inlineremote[$idx]="\n".
 1111: 		   '<td class="LC_menubuttons_text" align="right">'.$text.
 1112: 		   '</td><td align="left">'.
 1113: 		   '<a href="javascript:'.$act.';">'.$pic.'</a></td></tr>';
 1114: 	   } elsif ($nobreak) {
 1115: 	       $inlineremote[$idx]="\n<tr>".
 1116: 		   '<td align="left">'.
 1117: 		   '<a href="javascript:'.$act.';">'.$pic.'</a></td>
 1118:                     <td class="LC_menubuttons_text" align="left"><a class="LC_menubuttons_link" href="javascript:'.$act.';"><span class="LC_menubuttons_inline_text">'.$text.'</span></a></td>';
 1119: 	   } else {
 1120: 	       $inlineremote[$idx]="\n<tr>".
 1121: 		   '<td align="left">'.
 1122: 		   '<a href="javascript:'.$act.';">'.$pic.
 1123: 		   '</a></td><td class="LC_menubuttons_text" colspan="3">'.
 1124: 		   '<a class="LC_menubuttons_link" href="javascript:'.$act.';"><span class="LC_menubuttons_inline_text">'.$desc.'</span></a></td></tr>';
 1125: 	   }
 1126:        } else {
 1127: # Inline Menu
 1128:            if ($env{'environment.icons'} eq 'iconsonly') {
 1129:               $inlineremote[$idx]='<a title="'.$desc.'" href="javascript:'.$act.';">'.$pic.'</a>';
 1130:            } else {
 1131: 	      $inlineremote[$idx]=
 1132: 		   '<a class="LC_menubuttons_link" href="javascript:'.$act.';">'.$pic.
 1133: 		   '<span class="LC_menubuttons_inline_text">'.$desc.'</span></a>';
 1134:            }
 1135:        }
 1136:    }
 1137:     return '';
 1138: }
 1139: 
 1140: sub secondlevel {
 1141:     my $output='';
 1142:     my 
 1143:     ($uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc,$cat)=@_;
 1144:     if ($prt eq 'any') {
 1145: 	   $output.=&switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat);
 1146:     } elsif ($prt=~/^r(\w+)/) {
 1147:         if ($rol eq $1) {
 1148:            $output.=&switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat);
 1149:         }
 1150:     }
 1151:     return $output;
 1152: }
 1153: 
 1154: sub openmenu {
 1155:     my $menuname = &get_menu_name();
 1156:     if (($env{'browser.interface'} eq 'textual') ||
 1157:         ($env{'environment.remote'} eq 'off')) { return ''; }
 1158:     my $nothing = &Apache::lonhtmlcommon::javascript_nothing();
 1159:     return "window.open(".$nothing.",'".$menuname."');";
 1160: }
 1161: 
 1162: sub inlinemenu {
 1163:     undef(@inlineremote);
 1164:     undef(%category_members);
 1165:     &rawconfig(1);
 1166:     my $output='<table id="LC_mainmenu"><tr>';
 1167:     for (my $col=1; $col<=2; $col++) {
 1168:         $output.='<td class="LC_mainmenu_col_fieldset">';
 1169:         for (my $row=1; $row<=8; $row++) {
 1170:             foreach my $cat (keys(%category_members)) {
 1171:                if ($category_positions{$cat} ne "$col,$row") { next; }
 1172:                #$output.='<table><tr><td colspan="4" class="LC_menubuttons_category">'.&mt($category_names{$cat}).'</td></tr>';
 1173:                $output.='<div class="LC_ContentBoxSpecial">';
 1174: 	       $output.='<h4 class="LC_hcell">'.&mt($category_names{$cat}).'</h4>';
 1175:                $output.='<table>';
 1176:                my %active=();
 1177:                foreach my $menu_item (split(/\:/,$category_members{$cat})) {
 1178:                   if ($inlineremote[$menu_item]) {
 1179:                      $active{$menu_item}=1;
 1180:                   }
 1181:                }  
 1182:                foreach my $item (sort(keys(%active))) {
 1183:                   $output.=$inlineremote[$item];
 1184:                }
 1185:                $output.='</table>';
 1186:                $output.='</div>';
 1187:             }
 1188:          }
 1189:          $output.="</td>";
 1190:     }
 1191:     $output.="</tr></table>";
 1192:     return $output;
 1193: }
 1194: 
 1195: sub rawconfig {
 1196:     my $textualoverride=shift;
 1197:     my $output='';
 1198:     unless (($env{'browser.interface'} eq 'textual') ||
 1199:             ($env{'environment.remote'} eq 'off')) {
 1200:        $output.=
 1201:  "window.status='Opening Remote Control';var swmenu=".&openmenu().
 1202: "\nwindow.status='Configuring Remote Control ';";
 1203:     } else {
 1204:        unless ($textualoverride) { return ''; }
 1205:     }
 1206:     my $uname=$env{'user.name'};
 1207:     my $udom=$env{'user.domain'};
 1208:     my $adv=$env{'user.adv'};
 1209:     my $show_course=&show_course();
 1210:     my $author=$env{'user.author'};
 1211:     my $crs='';
 1212:     if ($env{'request.course.id'}) {
 1213:        $crs='/'.$env{'request.course.id'};
 1214:        if ($env{'request.course.sec'}) {
 1215: 	   $crs.='_'.$env{'request.course.sec'};
 1216:        }
 1217:        $crs=~s/\_/\//g;
 1218:     }
 1219:     my $pub=($env{'request.state'} eq 'published');
 1220:     my $con=($env{'request.state'} eq 'construct');
 1221:     my $rol=$env{'request.role'};
 1222:     my $requested_domain = $env{'request.role.domain'};
 1223:     foreach my $line (@desklines) {
 1224:         my ($row,$col,$pro,$prt,$img,$top,$bot,$act,$desc,$cat)=split(/\:/,$line);
 1225:         $prt=~s/\$uname/$uname/g;
 1226:         $prt=~s/\$udom/$udom/g;
 1227:         $prt=~s/\$crs/$crs/g; 
 1228:         $prt=~s/\$requested_domain/$requested_domain/g;
 1229:         if ($category_names{$cat}!~/\w/) { $cat='oth'; }
 1230:         my $type = &Apache::loncommon::course_type();
 1231:         if ($type eq 'Group') {
 1232:             $desc = &convert_menu_function($desc,$type);
 1233:         }
 1234:         if ($pro eq 'clear') {
 1235: 	    $output.=&clear($row,$col);
 1236:         } elsif ($pro eq 'any') {
 1237:                $output.=&secondlevel(
 1238: 	  $uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc,$cat);
 1239: 	} elsif ($pro eq 'smp') {
 1240:             unless ($adv) {
 1241:                $output.=&secondlevel(
 1242:           $uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc,$cat);
 1243:             }
 1244:         } elsif ($pro eq 'adv') {
 1245:             if ($adv) {
 1246:                $output.=&secondlevel(
 1247: 	  $uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc,$cat);
 1248:             }
 1249: 	} elsif ($pro eq 'shc') {
 1250:             if ($show_course) {
 1251:                $output.=&secondlevel(
 1252:           $uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc,$cat);
 1253:             }
 1254:         } elsif ($pro eq 'nsc') {
 1255:             if (!$show_course) {
 1256:                $output.=&secondlevel(
 1257: 	  $uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc,$cat);
 1258:             }
 1259:         } elsif (($pro=~/^p(\w+)/) && ($prt)) {
 1260: 	    if (&Apache::lonnet::allowed($1,$prt)) {
 1261:                $output.=&switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat);
 1262:             }
 1263:         } elsif ($pro eq 'course') {
 1264:             if ($env{'request.course.fn'}) {
 1265:                $output.=&switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat);
 1266: 	    }
 1267:         } elsif ($pro =~ /^courseenv_(.*)$/) {
 1268:             my $key = $1;
 1269:             if ($env{'course.'.$env{'request.course.id'}.'.'.$key}) {
 1270:                 $output.=&switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat);
 1271:             }
 1272:         } elsif ($pro =~ /^course_(.*)$/) {
 1273:             # Check for permissions inside of a course
 1274:             if (($env{'request.course.id'}) &&
 1275:                 (&Apache::lonnet::allowed($1,$env{'request.course.id'}.
 1276:             ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))
 1277:                  )) {
 1278:                 $output.=&switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat);
 1279: 	    }
 1280:         } elsif ($pro eq 'author') {
 1281:             if ($author) {
 1282:                 if ((($prt eq 'rca') && ($env{'request.role'}=~/^ca/)) ||
 1283:                     (($prt eq 'raa') && ($env{'request.role'}=~/^aa/)) || 
 1284:                     (($prt eq 'rau') && ($env{'request.role'}=~/^au/))) {
 1285:                     # Check that we are on the correct machine
 1286:                     my $cadom=$requested_domain;
 1287:                     my $caname=$env{'user.name'};
 1288:                     if (($prt eq 'rca') || ($prt eq 'raa')) {
 1289: 		       ($cadom,$caname)=
 1290:                                ($env{'request.role'}=~/($match_domain)\/($match_username)$/);
 1291:                     }                       
 1292:                     $act =~ s/\$caname/$caname/g;
 1293:                     my $home = &Apache::lonnet::homeserver($caname,$cadom);
 1294: 		    my $allowed=0;
 1295: 		    my @ids=&Apache::lonnet::current_machine_ids();
 1296: 		    foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } }
 1297: 		    if ($allowed) {
 1298:                         $output.=&switch($caname,$cadom,
 1299:                                         $row,$col,$img,$top,$bot,$act,$desc,$cat);
 1300:                     }
 1301:                 }
 1302:             }
 1303:         } elsif ($pro eq 'tools') {
 1304:             my @tools = ('aboutme','blog','portfolio');
 1305:             if (grep(/^\Q$prt\E$/,@tools)) {
 1306:                 if (!&Apache::lonnet::usertools_access($env{'user.name'},
 1307:                                                        $env{'user.domain'},
 1308:                                                        $prt,undef,'tools')) {
 1309:                     $output.=&clear($row,$col);
 1310:                     next;
 1311:                 }
 1312:             } elsif ($prt eq 'reqcrs') {
 1313:                 my $showreqcrs = 0;
 1314:                 foreach my $type ('official','unofficial') {
 1315:                     if (&Apache::lonnet::usertools_access($env{'user.name'},
 1316:                                                     $env{'user.domain'},
 1317:                                                     $type,undef,'requestcourses')) {
 1318:                         $showreqcrs = 1;
 1319:                         last;
 1320:                     }
 1321:                 }
 1322:                 if (!$showreqcrs) {
 1323:                     $output.=&clear($row,$col);
 1324:                     next;
 1325:                 }
 1326:             }
 1327:             $prt='any';
 1328:             $output.=&secondlevel(
 1329:           $uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc,$cat);
 1330:         }
 1331:     }
 1332:     unless (($env{'browser.interface'} eq 'textual') ||
 1333:             ($env{'environment.remote'} eq 'off')) {
 1334:        $output.="\nwindow.status='Synchronizing Time';swmenu.syncclock(1000*".time.");\nwindow.status='Remote Control Configured.';";
 1335:        if (&Apache::lonmsg::newmail()) { 
 1336: 	   $output.='swmenu.setstatus("you have","messages");';
 1337:        }
 1338:     }
 1339: 
 1340:     return $output;
 1341: }
 1342: 
 1343: # ======================================================================= Close
 1344: 
 1345: sub close {
 1346:     if (($env{'browser.interface'} eq 'textual') ||
 1347:         ($env{'environment.remote'} eq 'off')) { return ''; }
 1348:     my $menuname = &get_menu_name();
 1349:     return(<<ENDCLOSE);
 1350: <script type="text/javascript">
 1351: window.status='Accessing Remote Control';
 1352: menu=window.open("/adm/rat/empty.html","$menuname",
 1353:                  "height=350,width=150,scrollbars=no,menubar=no");
 1354: window.status='Disabling Remote Control';
 1355: menu.active=0;
 1356: menu.autologout=0;
 1357: window.status='Closing Remote Control';
 1358: menu.close();
 1359: window.status='Done.';
 1360: </script>
 1361: ENDCLOSE
 1362: }
 1363: 
 1364: # ====================================================================== Footer
 1365: 
 1366: sub footer {
 1367: 
 1368: }
 1369: 
 1370: sub nav_control_js {
 1371:     my $nav=($env{'environment.remotenavmap'} eq 'on');
 1372:     return (<<NAVCONTROL);
 1373:     var w_loncapanav_flag="$nav";
 1374: 
 1375: 
 1376: function gonav(url) {
 1377:    if (w_loncapanav_flag != 1) {
 1378:       gopost(url,'');
 1379:    }  else {
 1380:       navwindow=window.open(url,
 1381:                   "loncapanav","height=600,width=400,scrollbars=1"); 
 1382:    }
 1383: }
 1384: NAVCONTROL
 1385: }
 1386: 
 1387: sub utilityfunctions {
 1388:     my $caller = shift;
 1389:     unless (($env{'browser.interface'} eq 'textual')  ||
 1390:         ($env{'environment.remote'} eq 'off') || ($caller eq '/adm/menu')) { return ''; }
 1391:     my $currenturl=&Apache::lonnet::clutter(&Apache::lonnet::fixversion((split(/\?/,$env{'request.noversionuri'}))[0]));
 1392:     $currenturl=&Apache::lonenc::check_encrypt(&unescape($currenturl));
 1393:     
 1394:     my $currentsymb=&Apache::lonenc::check_encrypt($env{'request.symb'});
 1395:     my $nav_control=&nav_control_js();
 1396: 
 1397:     my $start_page_annotate = 
 1398:         &Apache::loncommon::start_page('Annotator',undef,
 1399: 				       {'only_body' => 1,
 1400: 					'js_ready'  => 1,
 1401: 					'bgcolor'   => '#BBBBBB',
 1402: 					'add_entries' => {
 1403: 					    'onload' => 'javascript:document.goannotate.submit();'}});
 1404: 
 1405:     my $end_page_annotate = 
 1406:         &Apache::loncommon::end_page({'js_ready' => 1});
 1407: 
 1408:     my $start_page_bookmark = 
 1409:         &Apache::loncommon::start_page('Bookmarks',undef,
 1410: 				       {'only_body' => 1,
 1411: 					'js_ready'  => 1,
 1412: 					'bgcolor'   => '#BBBBBB',});
 1413: 
 1414:     my $end_page_bookmark = 
 1415:         &Apache::loncommon::end_page({'js_ready' => 1});
 1416: 
 1417: return (<<ENDUTILITY)
 1418: 
 1419:     var currentURL="$currenturl";
 1420:     var reloadURL="$currenturl";
 1421:     var currentSymb="$currentsymb";
 1422: 
 1423: $nav_control
 1424: 
 1425: function go(url) {
 1426:    if (url!='' && url!= null) {
 1427:        currentURL = null;
 1428:        currentSymb= null;
 1429:        window.location.href=url;
 1430:    }
 1431: }
 1432: 
 1433: function gopost(url,postdata) {
 1434:    if (url!='') {
 1435:       this.document.server.action=url;
 1436:       this.document.server.postdata.value=postdata;
 1437:       this.document.server.command.value='';
 1438:       this.document.server.url.value='';
 1439:       this.document.server.symb.value='';
 1440:       this.document.server.submit();
 1441:    }
 1442: }
 1443: 
 1444: function gocmd(url,cmd) {
 1445:    if (url!='') {
 1446:       this.document.server.action=url;
 1447:       this.document.server.postdata.value='';
 1448:       this.document.server.command.value=cmd;
 1449:       this.document.server.url.value=currentURL;
 1450:       this.document.server.symb.value=currentSymb;
 1451:       this.document.server.submit();
 1452:    }
 1453: }
 1454: 
 1455: function gocstr(url,filename) {
 1456:     if (url == '/adm/cfile?action=delete') {
 1457:         this.document.cstrdelete.filename.value = filename
 1458:         this.document.cstrdelete.submit();
 1459:         return;
 1460:     }
 1461:     if (url == '/adm/printout') {
 1462:         this.document.cstrprint.postdata.value = filename
 1463:         this.document.cstrprint.curseed.value = 0;
 1464:         this.document.cstrprint.problemtype.value = 0;
 1465:         if (this.document.lonhomework) {
 1466:             if ((this.document.lonhomework.rndseed) && (this.document.lonhomework.rndseed.value != null) && (this.document.lonhomework.rndseed.value != '')) {
 1467:                 this.document.cstrprint.curseed.value = this.document.lonhomework.rndseed.value
 1468:             }
 1469:             if (this.document.lonhomework.problemtype) {
 1470: 		if (this.document.lonhomework.problemtype.value) {
 1471: 		    this.document.cstrprint.problemtype.value = 
 1472: 			this.document.lonhomework.problemtype.value;
 1473: 		} else if (this.document.lonhomework.problemtype.options) {
 1474: 		    for (var i=0; i<this.document.lonhomework.problemtype.options.length; i++) {
 1475: 			if (this.document.lonhomework.problemtype.options[i].selected) {
 1476: 			    if (this.document.lonhomework.problemtype.options[i].value != null && this.document.lonhomework.problemtype.options[i].value != '') { 
 1477: 				this.document.cstrprint.problemtype.value = this.document.lonhomework.problemtype.options[i].value
 1478: 				}
 1479: 			}
 1480: 		    }
 1481: 		}
 1482: 	    }
 1483: 	}
 1484:         this.document.cstrprint.submit();
 1485:         return;
 1486:     }
 1487:     if (url !='') {
 1488:         this.document.constspace.filename.value = filename;
 1489:         this.document.constspace.action = url;
 1490:         this.document.constspace.submit();
 1491:     }
 1492: }
 1493: 
 1494: function golist(url) {
 1495:    if (url!='' && url!= null) {
 1496:        currentURL = null;
 1497:        currentSymb= null;
 1498:        top.location.href=url;
 1499:    }
 1500: }
 1501: 
 1502: 
 1503: 
 1504: function catalog_info() {
 1505:    loncatinfo=window.open(window.location.pathname+'.meta',"LONcatInfo",'height=320,width=280,resizable=yes,scrollbars=yes,location=no,menubar=no,toolbar=no');
 1506: }
 1507: 
 1508: function chat_win() {
 1509:    lonchat=window.open('/res/adm/pages/chatroom.html',"LONchat",'height=320,width=280,resizable=yes,location=no,menubar=no,toolbar=no');
 1510: }
 1511: 
 1512: function group_chat(group) {
 1513:    var url = '/adm/groupchat?group='+group;
 1514:    var winName = 'LONchat_'+group;
 1515:    grpchat=window.open(url,winName,'height=320,width=280,resizable=yes,location=no,menubar=no,toolbar=no');
 1516: }
 1517: 
 1518: function edit_bookmarks() {
 1519:    go('');
 1520:    w_BookmarkPal_flag=1;
 1521:    bookmarkpal=window.open("/adm/bookmarks",
 1522:                "BookmarkPal", "width=400,height=505,scrollbars=0");
 1523: }
 1524: 
 1525: function annotate() {
 1526:    w_Annotator_flag=1;
 1527:    annotator=window.open('','Annotator','width=365,height=265,scrollbars=0');
 1528:    annotator.document.write(
 1529:    '$start_page_annotate'
 1530:   +"<form name='goannotate' target='Annotator' method='post' "
 1531:   +"action='/adm/annotations'>"
 1532:   +"<input type='hidden' name='symbnew' value='"+currentSymb+"' />"
 1533:   +"<\\/form>"
 1534:   +'$end_page_annotate');
 1535:    annotator.document.close();
 1536: }
 1537: 
 1538: function set_bookmark() {
 1539:    go('');
 1540:    clienttitle=document.title;
 1541:    clienthref=location.pathname;
 1542:    w_bmquery_flag=1;
 1543:    bmquery=window.open('','bmquery','width=365,height=165,scrollbars=0');
 1544:    bmquery.document.write(
 1545:    '$start_page_bookmark'
 1546:    +"<center><form method='post'"
 1547:    +" name='newlink' action='/adm/bookmarks' target='bmquery' "
 1548:    +">\\n <table width=340 height=150 "
 1549:    +"bgcolor='ffffff' align=center><tr><td>Link Name:<br /><input "
 1550:    +"type='text' name='title' size=45 value='"+clienttitle+"' />"
 1551:    +"<br />Address:<br /><input type='text' name='address' size='45' "
 1552:    +"value='"+clienthref+"' /><br /><center><input type='submit' "
 1553:    +"value='Save' /> <input type='button' value='Close' "
 1554:    +"onclick='javascript:window.close();' /><\\/center><\\/td>"
 1555:    +"<\\/tr><\\/table><\\/form><\\/center>"
 1556:    +'$end_page_bookmark' );
 1557:    bmquery.document.close();
 1558: }
 1559: 
 1560: ENDUTILITY
 1561: }
 1562: 
 1563: sub serverform {
 1564:     return(<<ENDSERVERFORM);
 1565: <form name="server" action="/adm/logout" method="post" target="_top">
 1566: <input type="hidden" name="postdata" value="none" />
 1567: <input type="hidden" name="command" value="none" />
 1568: <input type="hidden" name="url" value="none" />
 1569: <input type="hidden" name="symb" value="none" />
 1570: </form>
 1571: ENDSERVERFORM
 1572: }
 1573: 
 1574: sub constspaceform {
 1575:     return(<<ENDCONSTSPACEFORM);
 1576: <form name="constspace" action="/adm/logout" method="post" target="_top">
 1577: <input type="hidden" name="filename" value="" />
 1578: </form>
 1579: <form name="cstrdelete" action="/adm/cfile" method="post" target="_top">
 1580: <input type="hidden" name="action" value="delete" /> 
 1581: <input type="hidden" name="filename" value="" />
 1582: </form>
 1583: <form name="cstrprint" action="/adm/printout" target="_parent" method="post">
 1584: <input type="hidden" name="postdata" value="" />
 1585: <input type="hidden" name="curseed" value="" />
 1586: <input type="hidden" name="problemtype" value="" />
 1587: </form>
 1588: 
 1589: ENDCONSTSPACEFORM
 1590: }
 1591: 
 1592: 
 1593: sub get_nav_status {
 1594:     my $navstatus="swmenu.w_loncapanav_flag=";
 1595:     if ($env{'environment.remotenavmap'} eq 'on') {
 1596: 	$navstatus.="1";
 1597:     } else {
 1598: 	$navstatus.="-1";
 1599:     }
 1600:     return $navstatus;
 1601: }
 1602: 
 1603: #FIXME this needs to move into mydesktab and the other locations 
 1604: # the text is generated
 1605: sub convert_menu_function {
 1606:     my ($rolename,$type) = @_;
 1607:     if ($type eq 'Group') {
 1608:         $rolename =~ s/student/member/g;
 1609:         $rolename =~ s/group/team/g;
 1610:         $rolename =~ s/course/group/g;
 1611:         $rolename =~ s/Course/Group/g;
 1612:     }
 1613:     return $rolename;
 1614: }
 1615: 
 1616: sub hidden_button_check {
 1617:     my $hidden;
 1618:     if ($env{'request.course.id'} eq '') {
 1619:         return;
 1620:     }
 1621:     if ($env{'request.role.adv'}) {
 1622:         return;
 1623:     }
 1624:     my $buttonshide = &Apache::lonnet::EXT('resource.0.buttonshide');
 1625:     return $buttonshide; 
 1626: }
 1627: 
 1628: sub roles_selector {
 1629:     my ($cdom,$cnum) = @_;
 1630:     my $now = time;
 1631:     my (%courseroles,%seccount,%gotnosection);
 1632:     my $is_cc;
 1633:     my $role_selector;
 1634:     if ($env{'user.role.cc./'.$cdom.'/'.$cnum}) {
 1635:         my ($start,$end) = split(/\./,$env{'user.role.cc./'.$cdom.'/'.$cnum});
 1636:         
 1637:         if ((($start) && ($start<0)) || 
 1638:             (($end) && ($end<$now))  ||
 1639:             (($start) && ($now<$start))) {
 1640:             $is_cc = 0;
 1641:         } else {
 1642:             $is_cc = 1;
 1643:         }
 1644:     }
 1645:     if ($is_cc) {
 1646:         my %adv_roles =
 1647:              &Apache::lonnet::get_course_adv_roles($env{'request.course.id'},1);
 1648:         foreach my $role (keys(%adv_roles)) {
 1649:             my ($urole,$usec) = split(/:/,$role);
 1650:             if (!$gotnosection{$urole}) {
 1651:                 $seccount{$urole} ++;
 1652:                 $gotnosection{$urole} = 1;
 1653:             }
 1654:             if (ref($courseroles{$urole}) eq 'ARRAY') {
 1655:                 if ($usec ne '') {
 1656:                     if (!grep(/^Q$usec\E$/,@{$courseroles{$urole}})) {
 1657:                         push(@{$courseroles{$urole}},$usec);
 1658:                         $seccount{$urole} ++;
 1659:                     }
 1660:                 }
 1661:             } else {
 1662:                 @{$courseroles{$urole}} = ();
 1663:                 if ($usec ne '') {
 1664:                     $seccount{$urole} ++;
 1665:                     push(@{$courseroles{$urole}},$usec);
 1666:                 }
 1667:             }
 1668:         }
 1669:         my %sections_count = &Apache::loncommon::get_sections($cdom,$cnum);
 1670:         @{$courseroles{'st'}} = ();
 1671:         if (keys(%sections_count) > 0) {
 1672:             push(@{$courseroles{'st'}},keys(%sections_count));
 1673:         }
 1674:     } else {
 1675:         foreach my $item (keys(%env)) {
 1676:             if ($item =~ m-^user\.role\.([^.]+)\./\Q$cdom\E/\Q$cnum\E/?(\w*)$-) {
 1677:                 my $role = $1;
 1678:                 my $sec = $2;
 1679:                 next if ($role eq 'gr');
 1680:                 my ($start,$end) = split(/\./,$env{$item});
 1681:                 next if (($start && $start > $now) || ($end && $end < $now));
 1682:                 if ($sec eq '') {
 1683:                     if (!$gotnosection{$role}) {
 1684:                         $seccount{$role} ++;
 1685:                         $gotnosection{$role} = 1;
 1686:                     }
 1687:                 }
 1688:                 if (ref($courseroles{$role}) eq 'ARRAY') {
 1689:                     if ($sec ne '') {
 1690:                         if (!grep(/^Q$sec\E$/,@{$courseroles{$role}})) {
 1691:                             push(@{$courseroles{$role}},$sec);
 1692:                             $seccount{$role} ++;
 1693:                         }
 1694:                     }
 1695:                 } else {
 1696:                     @{$courseroles{$role}} = ();
 1697:                     if ($sec ne '') {
 1698:                         $seccount{$role} ++;
 1699:                         push(@{$courseroles{$role}},$sec);
 1700:                     }
 1701:                 }
 1702:             }
 1703:         }
 1704:     }
 1705:     my @roles_order = ('cc','in','ta','ep','ad','st');
 1706:     if (keys(%courseroles) > 1) {
 1707:         $role_selector = &jump_to_role($cdom,$cnum,\%seccount,\%courseroles);
 1708:         $role_selector .= '<form name="rolechooser" method="post" action="/adm/roles">
 1709:                           <select name="switchrole" onchange="javascript:adhocRole('."'switchrole'".')">';
 1710:         $role_selector .= '<option value="">'.&mt('Switch course role to...').'</option>';
 1711:         foreach my $role (@roles_order) {
 1712:             if (defined($courseroles{$role})) {
 1713:                 $role_selector .= "\n".'<option value="'.$role.'">'.&Apache::lonnet::plaintext($role).'</option>'; 
 1714:             }
 1715:         }
 1716:         foreach my $role (sort(keys(%courseroles))) {
 1717:             if ($role =~ /^cr/) {
 1718:                 $role_selector .= "\n".'<option value="'.$role.'">'.&Apache::lonnet::plaintext($role).'</option>'; 
 1719:             }
 1720:         }
 1721:         $role_selector .= '</select>'."\n".
 1722:                '<input type="hidden" name="destinationurl" value="'.
 1723:                $ENV{'REQUEST_URI'}.'" />'."\n".
 1724:                '<input type="hidden" name="gotorole" value="1" />'."\n".
 1725:                '<input type="hidden" name="selectrole" value="" />'."\n".
 1726:                '<input type="hidden" name="switch" value="1" />'."\n".
 1727:                '</form>';
 1728:     }
 1729:     return $role_selector;
 1730: }
 1731: 
 1732: sub jump_to_role {
 1733:     my ($cdom,$cnum,$seccount,$courseroles) = @_;
 1734:     my %lt = &Apache::lonlocal::texthash(
 1735:                 this => 'This role has section(s) associated with it.',
 1736:                 ente => 'Enter a specific section.',
 1737:                 orlb => 'Enter a specific section, or leave blank for no section.',
 1738:                 avai => 'Available sections are:',
 1739:                 youe => 'You entered an invalid section choice:',
 1740:                 plst => 'Please try again',
 1741:     );
 1742:     my $js;
 1743:     if (ref($courseroles) eq 'HASH') {
 1744:         $js = '    var secpick = new Array("'.$lt{'ente'}.'","'.$lt{'orlb'}.'");'."\n". 
 1745:               '    var numsec = new Array();'."\n".
 1746:               '    var rolesections = new Array();'."\n".
 1747:               '    var rolenames = new Array();'."\n".
 1748:               '    var roleseclist = new Array();'."\n";
 1749:         my @items = keys(%{$courseroles});
 1750:         for (my $i=0; $i<@items; $i++) {
 1751:             $js .= '    rolenames['.$i.'] = "'.$items[$i].'";'."\n";
 1752:             my ($secs,$secstr);
 1753:             if (ref($courseroles->{$items[$i]}) eq 'ARRAY') {
 1754:                 my @sections = sort { $a <=> $b } @{$courseroles->{$items[$i]}};
 1755:                 $secs = join('","',@sections);
 1756:                 $secstr = join(', ',@sections);
 1757:             }
 1758:             $js .= '    rolesections['.$i.'] = new Array("'.$secs.'");'."\n".
 1759:                    '    roleseclist['.$i.'] = "'.$secstr.'";'."\n".
 1760:                    '    numsec['.$i.'] = "'.$seccount->{$items[$i]}.'";'."\n";
 1761:         }
 1762:     }
 1763:     my $output = <<"END";
 1764: <script type="text/javascript">
 1765: function adhocRole(roleitem) {
 1766:     $js
 1767:     var newrole =  document.rolechooser.elements[roleitem].options[document.rolechooser.elements[roleitem].selectedIndex].value;
 1768:     if (newrole == '') {
 1769:         return; 
 1770:     } 
 1771:     var fullrole = newrole+'./$cdom/$cnum';
 1772:     var selidx = '';
 1773:     for (var i=0; i<rolenames.length; i++) {
 1774:         if (rolenames[i] == newrole) {
 1775:             selidx = i;
 1776:         }
 1777:     }
 1778:     var secok = 1;
 1779:     var secchoice = '';
 1780:     if (selidx >= 0) {
 1781:         if (numsec[selidx] > 1) {
 1782:             secok = 0;
 1783:             var numrolesec = rolesections[selidx].length;
 1784:             var msgidx = numsec[selidx] - numrolesec;
 1785:             secchoice = prompt("$lt{'this'}\\n"+secpick[msgidx]+"\\n$lt{'avai'} "+roleseclist[selidx],"");
 1786:             if (secchoice == '') {
 1787:                 if (msgidx > 0) {
 1788:                     secok = 1;
 1789:                 }
 1790:             } else {
 1791:                 for (var j=0; j<rolesections[selidx].length; j++) {
 1792:                     if (rolesections[selidx][j] == secchoice) {
 1793:                         secok = 1;
 1794:                     }
 1795:                 }
 1796:             }
 1797:         } else {
 1798:             if (rolesections[selidx].length == 1) {
 1799:                 secchoice = rolesections[selidx][0];
 1800:             }
 1801:         }
 1802:     }
 1803:     if (secok == 1) {
 1804:         if (secchoice != '') {
 1805:             fullrole += '/'+secchoice;
 1806:         }
 1807:     } else {
 1808:         document.rolechooser.elements[roleitem].selectedIndex = 0;
 1809:         if (secchoice != null) {
 1810:             alert("$lt{'youe'} \\""+secchoice+"\\".\\n $lt{'plst'}");
 1811:         }
 1812:         return;
 1813:     }
 1814:     if (fullrole == "$env{'request.role'}") {
 1815:         return;
 1816:     }
 1817:     itemid = retrieveIndex('gotorole');
 1818:     if (itemid != -1) {
 1819:         document.rolechooser.elements[itemid].name = fullrole;
 1820:     }
 1821:     document.rolechooser.elements[roleitem].options[document.rolechooser.elements[roleitem].selectedIndex].value = fullrole;
 1822:     document.rolechooser.selectrole.value = '1';
 1823:     document.rolechooser.submit();
 1824:     return;
 1825: }
 1826: 
 1827: function retrieveIndex(item) {
 1828:     for (var i=0;i<document.rolechooser.elements.length;i++) {
 1829:         if (document.rolechooser.elements[i].name == item) {
 1830:             return i;
 1831:         }
 1832:     }
 1833:     return -1;
 1834: }
 1835: 
 1836: 
 1837: </script>
 1838: END
 1839:     return $output;
 1840: }
 1841: 
 1842: 
 1843: # ================================================================ Main Program
 1844: 
 1845: BEGIN {
 1846:     if (! defined($readdesk)) {
 1847: 	{
 1848: 	    my $tabfile = $Apache::lonnet::perlvar{'lonTabDir'}.'/mydesk.tab';
 1849: 	    if ( CORE::open( my $config,"<$tabfile") ) {
 1850: 		while (my $configline=<$config>) {
 1851: 		    $configline=(split(/\#/,$configline))[0];
 1852: 		    $configline=~s/^\s+//;
 1853: 		    chomp($configline);
 1854:                     if ($configline=~/^cat\:/) {
 1855:                        my @entries=split(/\:/,$configline);
 1856:                        $category_positions{$entries[2]}=$entries[1];
 1857:                        $category_names{$entries[2]}=$entries[3];
 1858: 		    } elsif ($configline) {
 1859: 			push(@desklines,$configline);
 1860: 		    }
 1861: 		}
 1862: 		CORE::close($config);
 1863: 	    }
 1864: 	}
 1865: 	$readdesk='done';
 1866:     }
 1867: }
 1868: 
 1869: 1;
 1870: __END__
 1871: 
 1872: 
 1873: 
 1874: 
 1875: 
 1876: 
 1877: 

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