Annotation of loncom/interface/lonmenu.pm, revision 1.431.2.2

1.1       www         1: # The LearningOnline Network with CAPA
                      2: # Routines to control the menu
                      3: #
1.431.2.2! musolffc    4: # $Id: lonmenu.pm,v 1.431.2.1 2015/03/03 16:53:59 musolffc Exp $
1.11      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.1       www        28: #
                     29: 
1.244     jms        30: =head1 NAME
                     31: 
                     32: Apache::lonmenu
                     33: 
                     34: =head1 SYNOPSIS
                     35: 
1.371     raeburn    36: Loads contents of /home/httpd/lonTabs/mydesk.tab, 
                     37: used to generate inline menu, and Main Menu page. 
1.244     jms        38: 
                     39: This is part of the LearningOnline Network with CAPA project
                     40: described at http://www.lon-capa.org.
                     41: 
1.314     droeschl   42: =head1 GLOBAL VARIABLES
                     43: 
                     44: =over
                     45: 
                     46: =item @desklines
                     47: 
                     48: Each element of this array contains a line of mydesk.tab that doesn't start with
                     49: cat, prim or scnd. 
                     50: It gets filled in the BEGIN block of this module.
                     51: 
                     52: =item %category_names
                     53: 
                     54: The keys of this hash are the abbreviations used in mydesk.tab in those lines that 
                     55: start with cat, the values are strings representing titles. 
                     56: It gets filled in the BEGIN block of this module.
                     57: 
                     58: =item %category_members
                     59: 
                     60: TODO 
                     61: 
                     62: =item %category_positions
                     63: 
                     64: The keys of this hash are the abbreviations used in mydesk.tab in those lines that
                     65: start with cat, its values are position vectors (column, row). 
                     66: It gets filled in the BEGIN block of this module.
                     67: 
                     68: =item $readdesk
                     69: 
                     70: Indicates that mydesk.tab has been read. 
                     71: It is set to 'done' in the BEGIN block of this module.
                     72: 
                     73: =item @primary_menu
                     74: 
                     75: The elements of this array reference arrays that are made up of the components
1.371     raeburn    76: of those lines of mydesk.tab that start with prim:.
1.314     droeschl   77: It is used by primary_menu() to generate the corresponding menu.
                     78: It gets filled in the BEGIN block of this module.
                     79: 
1.371     raeburn    80: =item %primary_sub_menu
                     81: 
                     82: The keys of this hash reference are the names of items in the primary_menu array 
                     83: which have sub-menus.  For each key, the corresponding value is a reference to
                     84: an array containing components extracted from lines in mydesk.tab which begin
                     85: with primsub:.
                     86: This hash, which is used by primary_menu to generate sub-menus, is populated in
                     87: the BEGIN block.
                     88: 
1.314     droeschl   89: =item @secondary_menu
                     90: 
                     91: The elements of this array reference arrays that are made up of the components
                     92: of those lines of mydesk.tab that start with scnd.
                     93: It is used by secondary_menu() to generate the corresponding menu.
                     94: It gets filled in the BEGIN block of this module.
                     95: 
                     96: =back
                     97: 
1.244     jms        98: =head1 SUBROUTINES
                     99: 
                    100: =over
                    101: 
1.314     droeschl  102: =item prep_menuitems(\@menuitem)
                    103: 
                    104: This routine wraps a menuitem in proper HTML. It is used by primary_menu() and 
                    105: secondary_menu().
                    106: 
                    107: =item primary_menu()
                    108: 
1.415     raeburn   109: This routine evaluates @primary_menu and returns a two item array, 
                    110: with the array elements containing XHTML for the left and right sides of 
                    111: the menu that contains the following links: About, Message, Roles, Help, Logout 
1.314     droeschl  112: @primary_menu is filled within the BEGIN block of this module with 
1.415     raeburn   113: entries from mydesk.tab
1.314     droeschl  114: 
                    115: =item secondary_menu()
                    116: 
                    117: Same as primary_menu() but operates on @secondary_menu.
                    118: 
1.375     raeburn   119: =item create_submenu()
                    120: 
                    121: Creates XHTML for unordered list of sub-menu items which belong to a 
                    122: particular top-level menu item. Uses hover pseudo class in css to display
                    123: dropdown list when mouse hovers over top-level item. Support for IE6 
                    124: (no hover psuedo class) via LC_hoverable class for <li> tag for top-
                    125: level item, which employs jQuery to handle behavior on mouseover.
                    126: 
                    127: Inputs: 4 - (a) link and (b) target for anchor href in top level item,
                    128:             (c) title for text wrapped by anchor tag in top level item.
                    129:             (d) reference to array of arrays of sub-menu items.
                    130: 
1.431     golterma  131:  The underlying datastructure used in (d) contains data from mydesk.tab.
                    132:  It consists of an array which has an array for each item appearing in
                    133:  the menu (e.g. [["link", "title", "condition"]] for a single-item menu).
                    134:  create_submenu() supports also the creation of XHTML for nested dropdown
                    135:  menus represented by unordered lists. This is done by replacing the
                    136:  scalar used for the link with an arrayreference containing the menuitems
                    137:  for the nested menu. This can be done recursively so that the next menu
                    138:  may also contain nested submenus.
                    139: 
                    140:  Example:
                    141:  [											# begin of datastructure
                    142: 	["/home/", "Home", "condition1"], 		# 1st item of the 1st layer menu
                    143: 	[										# 2nd item of the 1st layer menu
                    144: 		[									# anon. array for nested menu
                    145: 			["/path1", "Path1", undef], 	# 1st item of the 2nd layer menu
                    146: 			["/path2", "Path2", undef], 	# 2nd item of the 2nd layer menu
                    147: 			[								# 3rd item of the 2nd layer menu
                    148: 				[[...], [...], ..., [...]],	# containing another menu layer
                    149: 				"Sub-Sub-Menu",				# title for this container
                    150: 				undef
                    151: 			]
                    152: 		],									# end of array/nested menu
                    153: 		"Sub-Menu",							# title for the container item
                    154: 		undef
                    155: 	]										# end of 2nd item of the 1st layer menu
                    156: ]
                    157: 
1.244     jms       158: =item innerregister()
                    159: 
1.320     droeschl  160: This gets called in order to register a URL in the body of the document
1.244     jms       161: 
                    162: =item clear()
                    163: 
                    164: =item switch()
                    165: 
                    166: Switch a button or create a link
                    167: Switch acts on the javascript that is executed when a button is clicked.  
                    168: The javascript is usually similar to "go('/adm/roles')" or "cstrgo(..)".
                    169: 
                    170: =item secondlevel()
                    171: 
                    172: =item openmenu()
                    173: 
                    174: =item inlinemenu()
                    175: 
                    176: =item rawconfig()
                    177: 
                    178: =item utilityfunctions()
                    179: 
1.371     raeburn   180: Output from this routine is a number of javascript functions called by
                    181: items in the inline menu, and in some cases items in the Main Menu page. 
                    182: 
1.244     jms       183: =item serverform()
                    184: 
                    185: =item constspaceform()
                    186: 
                    187: =item get_nav_status()
                    188: 
                    189: =item hidden_button_check()
                    190: 
                    191: =item roles_selector()
                    192: 
                    193: =item jump_to_role()
                    194: 
                    195: =back
                    196: 
                    197: =cut
                    198: 
1.1       www       199: package Apache::lonmenu;
                    200: 
                    201: use strict;
1.152     albertel  202: use Apache::lonnet;
1.47      matthew   203: use Apache::lonhtmlcommon();
1.115     albertel  204: use Apache::loncommon();
1.127     albertel  205: use Apache::lonenc();
1.88      www       206: use Apache::lonlocal;
1.361     raeburn   207: use Apache::lonmsg();
1.207     foxr      208: use LONCAPA qw(:DEFAULT :match);
1.282     amueller  209: use HTML::Entities();
1.346     wenzelju  210: use Apache::lonwishlist();
1.88      www       211: 
1.283     droeschl  212: use vars qw(@desklines %category_names %category_members %category_positions 
1.371     raeburn   213:             $readdesk @primary_menu %primary_submenu @secondary_menu);
1.88      www       214: 
1.56      www       215: my @inlineremote;
1.38      www       216: 
1.283     droeschl  217: sub prep_menuitem {
1.291     raeburn   218:     my ($menuitem) = @_;
                    219:     return '' unless(ref($menuitem) eq 'ARRAY');
1.283     droeschl  220:     my $link;
                    221:     if ($$menuitem[1]) { # graphical Link
                    222:         $link = "<img class=\"LC_noBorder\""
1.291     raeburn   223:               . " src=\"" . &Apache::loncommon::lonhttpdurl($$menuitem[1]) . "\"" 
                    224:               . " alt=\"" . &mt($$menuitem[2]) . "\" />";
1.283     droeschl  225:     } else {             # textual Link
1.291     raeburn   226:         $link = &mt($$menuitem[3]);
                    227:     }
1.316     droeschl  228:     return '<li><a' 
                    229:            # highlighting for new messages
                    230:            . ( $$menuitem[4] eq 'newmsg' ? ' class="LC_new_message"' : '') 
1.325     droeschl  231:            . qq| href="$$menuitem[0]" target="_top">$link</a></li>|;
1.283     droeschl  232: }
                    233: 
1.415     raeburn   234: # primary_menu() evaluates @primary_menu and returns a two item array,
                    235: # with the array elements containing XHTML for the left and right sides of 
                    236: # the menu that contains the following links:
                    237: # Personal, About, Message, Roles, Help, Logout
1.283     droeschl  238: # @primary_menu is filled within the BEGIN block of this module with 
                    239: # entries from mydesk.tab
                    240: sub primary_menu {
1.415     raeburn   241:     my (%menu);
1.283     droeschl  242:     # each element of @primary contains following array:
1.415     raeburn   243:     # (link url, icon path, alt text, link text, condition, position)
1.319     raeburn   244:     my $public;
                    245:     if ((($env{'user.name'} eq 'public') && ($env{'user.domain'} eq 'public'))
                    246:         || (($env{'user.name'} eq '') && ($env{'user.domain'} eq ''))) {
                    247:         $public = 1;
                    248:     }
1.283     droeschl  249:     foreach my $menuitem (@primary_menu) {
                    250:         # evaluate conditions 
1.296     droeschl  251:         next if    ref($menuitem)       ne 'ARRAY';    #
1.283     droeschl  252:         next if    $$menuitem[4]        eq 'nonewmsg'  # show links depending on
1.291     raeburn   253:                 && &Apache::lonmsg::mynewmail();       # whether a new msg 
1.283     droeschl  254:         next if    $$menuitem[4]        eq 'newmsg'    # arrived or not
1.291     raeburn   255:                 && !&Apache::lonmsg::mynewmail();      # 
1.319     raeburn   256:         next if    $$menuitem[4]        !~ /public/    ##we've a public user,
                    257:                 && $public;                            ##who should not see all
                    258:                                                        ##links
1.283     droeschl  259:         next if    $$menuitem[4]        eq 'onlypublic'# hide links which are 
1.319     raeburn   260:                 && !$public;                           # only visible to public
                    261:                                                        # users
1.283     droeschl  262:         next if    $$menuitem[4]        eq 'roles'     ##show links depending on
1.291     raeburn   263:                 && &Apache::loncommon::show_course();  ##term 'Courses' or 
1.283     droeschl  264:         next if    $$menuitem[4]        eq 'courses'   ##'Roles' wanted
1.291     raeburn   265:                 && !&Apache::loncommon::show_course(); ##
                    266:         
1.371     raeburn   267:         my $title = $menuitem->[3];
1.415     raeburn   268:         my $position = $menuitem->[5];
                    269:         if ($position eq '') {
                    270:             $position = 'right';
                    271:         }
1.371     raeburn   272:         if (defined($primary_submenu{$title})) {
1.375     raeburn   273:             my ($link,$target);
1.371     raeburn   274:             if ($menuitem->[0] ne '') {
                    275:                 $link = $menuitem->[0];
                    276:                 $target = '_top';
                    277:             } else {
                    278:                 $link = '#';
                    279:             }
1.375     raeburn   280:             my @primsub;
1.371     raeburn   281:             if (ref($primary_submenu{$title}) eq 'ARRAY') {
1.375     raeburn   282:                 foreach my $item (@{$primary_submenu{$title}}) {
1.383     raeburn   283:                     next if (($item->[2] eq 'wishlist') && (!$env{'user.adv'}));
1.375     raeburn   284:                     next if ((($item->[2] eq 'portfolio') ||
                    285:                              ($item->[2] eq 'blog')) &&
                    286:                              (!&Apache::lonnet::usertools_access('','',$item->[2],
                    287:                                                            undef,'tools')));
                    288:                     push(@primsub,$item);
                    289:                 }
                    290:                 if (@primsub > 0) {
1.419     bisitz    291:                     $menu{$position} .= &create_submenu($link,$target,$title,\@primsub,1);
1.375     raeburn   292:                 } elsif ($link) {
1.415     raeburn   293:                     $menu{$position} .= '<li><a href="'.$link.'" target="'.$target.'">'.&mt($title).'</a></li>';
1.371     raeburn   294:                 }
                    295:             }
                    296:         } elsif ($$menuitem[3] eq 'Help') { # special treatment for helplink
1.340     raeburn   297:             if ($public) {
                    298:                 my $origmail = $Apache::lonnet::perlvar{'lonSupportEMail'};
                    299:                 my $defdom = &Apache::lonnet::default_login_domain();
                    300:                 my $to = &Apache::loncommon::build_recipient_list(undef,
                    301:                                                                   'helpdeskmail',
                    302:                                                                   $defdom,$origmail);
                    303:                 if ($to ne '') {
1.415     raeburn   304:                     $menu{$position} .= &prep_menuitem($menuitem); 
1.340     raeburn   305:                 }
                    306:             } else {
1.415     raeburn   307:                 $menu{$position} .= '<li>'.&Apache::loncommon::top_nav_help('Help').'</li>';
1.340     raeburn   308:             }
1.283     droeschl  309:         } else {
1.415     raeburn   310:             $menu{$position} .= prep_menuitem($menuitem);
1.283     droeschl  311:         }
1.291     raeburn   312:     }
1.423     raeburn   313:     my @output = ('','');
                    314:     if ($menu{'left'} ne '') {
                    315:         $output[0] = "<ol class=\"LC_primary_menu LC_floatleft\">$menu{'left'}</ol>";
                    316:     }
                    317:     if ($menu{'right'} ne '') {
                    318:         $output[1] = "<ol class=\"LC_primary_menu LC_floatright LC_right\">$menu{'right'}</ol>";
                    319:     }
                    320:     return @output;
1.283     droeschl  321: }
                    322: 
1.329     droeschl  323: #returns hashref {user=>'',dom=>''} containing:
                    324: #   own name, domain if user is au
                    325: #   name, domain of parent author if user is ca or aa
                    326: #empty return if user is not an author or not on homeserver
                    327: #
                    328: #TODO this should probably be moved somewhere more central
                    329: #since it can be used by different parts of the system
                    330: sub getauthor{
                    331:     return unless $env{'request.role'}=~/^(ca|aa|au)/; #nothing to do if user isn't some kind of author
                    332: 
                    333:                         #co- or assistent author?
                    334:     my ($dom, $user) = ($env{'request.role'} =~ /^(?:ca|aa)\.\/($match_domain)\/($match_username)$/)
                    335:                        ? ($1, $2) #domain, username of the parent author
                    336:                        : @env{ ('request.role.domain', 'user.name') }; #own domain, username
                    337: 
                    338:     # current server == home server?
                    339:     my $home =  &Apache::lonnet::homeserver($user,$dom);
                    340:     foreach (&Apache::lonnet::current_machine_ids()){
                    341:         return {user => $user, dom => $dom} if $_ eq $home;
                    342:     }
                    343: 
                    344:     # if wrong server
                    345:     return;
                    346: }
1.283     droeschl  347: 
                    348: sub secondary_menu {
1.421     raeburn   349:     my ($httphost) = @_;
1.283     droeschl  350:     my $menu;
                    351: 
1.286     raeburn   352:     my $crstype = &Apache::loncommon::course_type();
1.327     droeschl  353:     my $crs_sec = $env{'request.course.id'} . ($env{'request.course.sec'} 
                    354:                                                ? "/$env{'request.course.sec'}"
                    355:                                                : '');
                    356:     my $canedit       = &Apache::lonnet::allowed('mdc', $env{'request.course.id'});
1.376     raeburn   357:     my $canviewroster = $env{'course.'.$env{'request.course.id'}.'.student_classlist_view'};
1.418     raeburn   358:     if ($canviewroster eq 'disabled') {
                    359:         undef($canviewroster);
                    360:     }
1.327     droeschl  361:     my $canviewgrps   = &Apache::lonnet::allowed('vcg', $crs_sec); 
                    362:     my $canmodifyuser = &Apache::lonnet::allowed('cst', $crs_sec); 
                    363:     my $canviewwnew   = &Apache::lonnet::allowed('whn', $crs_sec); 
1.341     www       364:     my $canmodpara    = &Apache::lonnet::allowed('opa', $crs_sec);
1.343     www       365:     my $canvgr        = &Apache::lonnet::allowed('vgr', $crs_sec);
                    366:     my $canmgr        = &Apache::lonnet::allowed('mgr', $crs_sec); 
                    367:     my $author        = &getauthor();
1.327     droeschl  368: 
1.417     raeburn   369:     my ($cdom,$cnum,$showsyllabus,$showfeeds,$showresv);
1.413     raeburn   370:     if ($env{'request.course.id'}) {
                    371:         $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                    372:         $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                    373:         if ($canedit) {
                    374:             $showsyllabus = 1;
                    375:             $showfeeds = 1;
                    376:         } else {
1.414     raeburn   377:             unless (&Apache::lonnet::is_on_map("public/$cdom/$cnum/syllabus")) {
                    378:                 if (($env{'course.'.$env{'request.course.id'}.'.externalsyllabus'}) ||
                    379:                     ($env{'course.'.$env{'request.course.id'}.'.uploadedsyllabus'}) ||
                    380:                     ($env{'course.'.$env{'request.course.id'}.'.updatedsyllabus'}) ||
                    381:                     ($env{'request.course.syllabustime'})) {
                    382:                     $showsyllabus = 1;
                    383:                 }
                    384:             }
                    385:             if ($env{'request.course.feeds'}) {
                    386:                 $showfeeds = 1;
1.413     raeburn   387:             }
                    388:         }
1.417     raeburn   389:         unless ($canmgr) {
                    390:             my %slots = &Apache::lonnet::get_course_slots($cnum,$cdom);
                    391:             if (keys(%slots) > 0) {
                    392:                 $showresv = 1;
                    393:             }
                    394:         }
1.413     raeburn   395:     }
                    396: 
1.404     raeburn   397:     my ($canmodifycoauthor); 
                    398:     if ($env{'request.role'} eq "au./$env{'user.domain'}/") {
                    399:         my $extent = "$env{'user.domain'}/$env{'user.name'}";
                    400:         if ((&Apache::lonnet::allowed('cca',$extent)) ||
                    401:             (&Apache::lonnet::allowed('caa',$extent))) {
                    402:             $canmodifycoauthor = 1;
                    403:         }
                    404:     }
                    405: 
1.286     raeburn   406:     my %groups = &Apache::lonnet::get_active_groups(
                    407:                      $env{'user.domain'}, $env{'user.name'},
                    408:                      $env{'course.' . $env{'request.course.id'} . '.domain'},
                    409:                      $env{'course.' . $env{'request.course.id'} . '.num'});
1.327     droeschl  410: 
1.401     raeburn   411:     my ($roleswitcher_js,$roleswitcher_form);
                    412: 
1.283     droeschl  413:     foreach my $menuitem (@secondary_menu) {
                    414:         # evaluate conditions 
1.296     droeschl  415:         next if    ref($menuitem)  ne 'ARRAY';
1.283     droeschl  416:         next if    $$menuitem[4]   ne 'always'
1.404     raeburn   417:                 && ($$menuitem[4]   ne 'author' && $$menuitem[4] ne 'cca')
1.283     droeschl  418:                 && !$env{'request.course.id'};
                    419:         next if    $$menuitem[4]   =~ /^mdc/
1.286     raeburn   420:                 && !$canedit;
1.341     www       421:         next if    $$menuitem[4]  eq 'nvgr'
                    422:                 && $canvgr;
                    423:         next if    $$menuitem[4]  eq 'vgr'
                    424:                 && !$canvgr;
1.327     droeschl  425:         next if    $$menuitem[4]   eq 'cst'
                    426:                 && !$canmodifyuser;
1.343     www       427:         next if    $$menuitem[4]   eq 'ncst'
1.376     raeburn   428:                 && ($canmodifyuser || !$canviewroster);
1.343     www       429:         next if    $$menuitem[4]   eq 'mgr'
                    430:                 && !$canmgr;
1.417     raeburn   431:         next if    $$menuitem[4]   eq 'showresv'
                    432:                 && !$showresv;
1.327     droeschl  433:         next if    $$menuitem[4]   eq 'whn'
                    434:                 && !$canviewwnew;
                    435:         next if    $$menuitem[4]   eq 'opa'
                    436:                 && !$canmodpara;
1.283     droeschl  437:         next if    $$menuitem[4]   =~ /showgroups$/
1.300     raeburn   438:                 && !$canviewgrps
1.286     raeburn   439:                 && !%groups;
1.413     raeburn   440:         next if    $$menuitem[4]   eq 'showsyllabus'
                    441:                 && !$showsyllabus;
                    442:         next if    $$menuitem[4]   eq 'showfeeds'
                    443:                 && !$showfeeds;
1.329     droeschl  444:         next if    $$menuitem[4]    eq 'author'
                    445:                 && !$author;
1.404     raeburn   446:         next if    $$menuitem[4]    eq 'cca'
                    447:                 && !$canmodifycoauthor;
1.283     droeschl  448: 
1.286     raeburn   449:         if ($$menuitem[3] eq 'Roles' && $env{'request.course.id'}) {
1.283     droeschl  450:             # special treatment for role selector
1.401     raeburn   451:             ($roleswitcher_js,$roleswitcher_form,my $switcher) =
                    452:                 &roles_selector(
1.283     droeschl  453:                         $env{'course.' . $env{'request.course.id'} . '.domain'},
1.421     raeburn   454:                         $env{'course.' . $env{'request.course.id'} . '.num'},
                    455:                         $httphost
1.401     raeburn   456:                 );
                    457:             $menu .= $switcher;
1.296     droeschl  458:         } else {
1.414     raeburn   459:             if ($$menuitem[3] eq 'Syllabus' && $env{'request.course.id'}) {
                    460:                 my $url = $$menuitem[0];
                    461:                 $url =~ s{\[cdom\]/\[cnum\]}{$cdom/$cnum};
                    462:                 if (&Apache::lonnet::is_on_map($url)) {
                    463:                     unless ($$menuitem[0] =~ /\?register=1/) {
                    464:                         $$menuitem[0] .= '?register=1';
                    465:                     }
                    466:                 } else {
                    467:                     $$menuitem[0] =~ s{\?register=1}{};
                    468:                 }
                    469:             }
1.296     droeschl  470:             $menu .= &prep_menuitem(\@$menuitem);
1.283     droeschl  471:         }
                    472:     }
                    473:     if ($menu =~ /\[url\].*\[symb\]/) {
1.291     raeburn   474:         my $escurl  = &escape( &Apache::lonenc::check_encrypt(
                    475:                              $env{'request.noversionuri'}));
1.283     droeschl  476: 
1.291     raeburn   477:         my $escsymb = &escape( &Apache::lonenc::check_encrypt(
                    478:                              $env{'request.symb'})); 
1.283     droeschl  479: 
                    480:         if (    $env{'request.state'} eq 'construct'
                    481:             and (   $env{'request.noversionuri'} eq '' 
                    482:                  || !defined($env{'request.noversionuri'}))) 
                    483:         {
1.359     raeburn   484:             my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'};
                    485:             ($escurl = $env{'request.filename'}) =~ s{^\Q$londocroot\E}{};
1.291     raeburn   486:             $escurl  = &escape($escurl);
1.283     droeschl  487:         }    
                    488:         $menu =~ s/\[url\]/$escurl/g;
                    489:         $menu =~ s/\[symb\]/$escsymb/g;
                    490:     }
1.329     droeschl  491:     $menu =~ s/\[uname\]/$$author{user}/g;
                    492:     $menu =~ s/\[udom\]/$$author{dom}/g;
1.413     raeburn   493:     if ($showsyllabus || $showfeeds) {
                    494:         $menu =~ s/\[cnum\]/$cnum/g;
                    495:         $menu =~ s/\[cdom\]/$cdom/g;
                    496:     }
1.385     raeburn   497:     if ($menu) {
                    498:         $menu = "<ul id=\"LC_secondary_menu\">$menu</ul>";
                    499:     }
1.401     raeburn   500:     if ($roleswitcher_form) {
                    501:         $menu .= "\n$roleswitcher_js\n$roleswitcher_form";
                    502:     }
1.385     raeburn   503:     return $menu;
1.283     droeschl  504: }
                    505: 
1.375     raeburn   506: sub create_submenu {
1.419     bisitz    507:     my ($link,$target,$title,$submenu,$translate) = @_;
1.375     raeburn   508:     return unless (ref($submenu) eq 'ARRAY');
1.379     raeburn   509:     my $disptarget;
                    510:     if ($target ne '') {
                    511:         $disptarget = ' target="'.$target.'"';
                    512:     }
1.415     raeburn   513:     my $name;
                    514:     if ($title eq 'Personal') {
                    515:         if ($env{'user.name'} && $env{'user.domain'}) {
                    516:             $name = &Apache::loncommon::plainname($env{'user.name'},$env{'user.domain'});
                    517:         } else {
                    518:             $name = &mt($title);
                    519:         }
                    520:     } else {
                    521:         $name = &mt($title);
                    522:     }
1.375     raeburn   523:     my $menu = '<li class="LC_hoverable">'.
1.379     raeburn   524:                '<a href="'.$link.'"'.$disptarget.'>'.
1.415     raeburn   525:                '<span class="LC_nobreak">'.$name.
1.375     raeburn   526:                '<span class="LC_fontsize_small" style="font-weight:normal;">'.
                    527:                ' &#9660;</span></span></a>'.
                    528:                '<ul>';
1.431     golterma  529: 
                    530:     # $link and $title are only used in the initial string written in $menu
                    531:     # as seen above, not needed for nested submenus
                    532:     $menu .= &build_submenu($target, $submenu, $translate, '1');
                    533:     $menu .= '</ul></li>';
                    534: 
                    535:     return $menu;
                    536: }
                    537: 
                    538: # helper routine for create_submenu
                    539: # build the dropdown (and nested submenus) recursively
                    540: # see perldoc create_submenu documentation for further information
                    541: sub build_submenu {
                    542:     my ($target, $submenu, $translate, $first_level) = @_; 
                    543:     if (!defined(@{$submenu})) {
                    544:         return '';
                    545:     }
                    546: 
                    547:     my $menu = '';
1.375     raeburn   548:     my $count = 0;
                    549:     my $numsub = scalar(@{$submenu});
                    550:     foreach my $item (@{$submenu}) {
                    551:         $count ++;
                    552:         if (ref($item) eq 'ARRAY') {
1.416     raeburn   553:             my $href = $item->[0];
1.431     golterma  554:             my $bordertop;
                    555:             my $borderbot;
                    556:             my $title;
                    557: 
                    558:             if ($translate) {
                    559:                  $title = &mt($item->[1]);
                    560:             } else {
                    561:                 $title = $item->[1];
                    562:             }
                    563: 
                    564:             if ($count == 1 && !$first_level) {
                    565:                 $bordertop = 'border-top: 1px solid black;';
1.416     raeburn   566:             }
1.375     raeburn   567:             if ($count == $numsub) {
1.431     golterma  568:                 $borderbot = 'border-bottom: 1px solid black;';
1.375     raeburn   569:             }
1.431     golterma  570: 
                    571:             # href is a reference to another submenu
                    572:             if (ref($href) eq 'ARRAY') {
                    573:                 $menu .= '<li style="margin:0;padding:0;'.$bordertop . $borderbot . '">';
                    574:                 $menu .= '<p><span class="LC_primary_menu_innertitle">'
                    575: 					. $title . '</span><span class="LC_primary_menu_innerarrow">&#9654;</span></p>';
                    576:                 $menu .= '<ul>';
                    577:                 $menu .= &build_submenu($target, $href, $translate);
                    578:                 $menu .= '</ul>';
                    579:                 $menu .= '</li>';    
                    580:             } else {    # href is the actual hyperlink and does not represent another submenu
                    581:                         # for the current menu title
                    582:                 if ($href =~ /(aboutme|rss\.html)$/) {
                    583:                     next unless (($env{'user.name'} ne '') && ($env{'user.domain'} ne ''));
                    584:                     $href =~ s/\[domain\]/$env{'user.domain'}/g;
                    585:                     $href =~ s/\[user\]/$env{'user.name'}/g;
                    586:                 }
                    587:                 unless (($href eq '') || ($href =~ /^\#/)) {
                    588:                     $target = ' target="_top"';
                    589:                 }
                    590: 
                    591:                 $menu .= '<li style="margin:0;padding:0;'. $bordertop . $borderbot .'">';
                    592:                 $menu .= '<a href="'.$href.'"'.$target.'>' .  $title . '</a>';
                    593:                 $menu .= '</li>';
1.425     raeburn   594:             }
1.375     raeburn   595:         }
                    596:     }
                    597:     return $menu;
                    598: }
                    599: 
1.40      www       600: sub innerregister {
1.390     raeburn   601:     my ($forcereg,$bread_crumbs,$group) = @_;
1.152     albertel  602:     my $const_space = ($env{'request.state'} eq 'construct');
1.131     raeburn   603:     my $is_const_dir = 0;
1.120     raeburn   604: 
1.175     albertel  605:     if ($env{'request.noversionuri'} =~ m{^/res/adm/pages/}) { return ''; }
1.40      www       606: 
1.174     albertel  607:     $env{'request.registered'} = 1;
1.40      www       608: 
1.177     albertel  609:     undef(@inlineremote);
1.56      www       610: 
1.393     raeburn   611:     my ($mapurl,$resurl);
1.390     raeburn   612: 
1.393     raeburn   613:     if ($env{'request.course.id'}) {
                    614:         if ($env{'request.symb'}) {
                    615:             ($mapurl, my $rid, $resurl) = &Apache::lonnet::decode_symb(&Apache::lonnet::symbread());
                    616:             my $coursetitle = $env{'course.'.$env{'request.course.id'}.'.description'};
1.267     droeschl  617: 
1.393     raeburn   618:             my $maptitle = &Apache::lonnet::gettitle($mapurl);
                    619:             my $restitle = &Apache::lonnet::gettitle(&Apache::lonnet::symbread());
1.318     droeschl  620: 
                    621: #SD
                    622: #course_type only Course and Community?
                    623: #
1.393     raeburn   624:             my @crumbs;
                    625:             unless (($forcereg) &&
                    626:                     ($env{'request.noversionuri'} eq '/adm/navmaps') &&
                    627:                     ($mapurl eq $env{'course.'.$env{'request.course.id'}.'.url'})) {
                    628:                 @crumbs = ({text  => Apache::loncommon::course_type() 
                    629:                                     . ' Contents', 
                    630:                             href  => "Javascript:gopost('/adm/navmaps','')"});
                    631:             }
                    632:             if ($mapurl ne $env{'course.'.$env{'request.course.id'}.'.url'}) { 
                    633:                 push(@crumbs, {text  => '...',
                    634:                                no_mt => 1});
                    635:             }
                    636: 
                    637:             push @crumbs, {text => $maptitle, no_mt => 1} if ($maptitle 
                    638:                                                        && $maptitle ne 'default.sequence' 
                    639:                                                        && $maptitle ne $coursetitle);
1.268     droeschl  640: 
1.393     raeburn   641:             push @crumbs, {text => $restitle, no_mt => 1} if $restitle; 
                    642:             &Apache::lonhtmlcommon::clear_breadcrumbs();
                    643:             &Apache::lonhtmlcommon::add_breadcrumb(@crumbs);
                    644:         } else {
                    645:             $resurl = $env{'request.noversionuri'};
                    646:             my $courseurl = &Apache::lonnet::courseid_to_courseurl($env{'request.course.id'});
                    647:             my $crstype = &Apache::loncommon::course_type();
                    648:             my $title = &mt('View Resource');
                    649:             if ($resurl =~ m{^\Q/uploaded$courseurl/supplemental/\E(default|\d+)/}) {
                    650:                 &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['folderpath','title']);
1.392     raeburn   651:                 &Apache::lonhtmlcommon::clear_breadcrumbs();
1.393     raeburn   652:                 if ($env{'form.title'}) {
                    653:                     $title = $env{'form.title'};
                    654:                 }
1.394     raeburn   655:                 my $trail;
1.393     raeburn   656:                 if ($env{'form.folderpath'}) {
1.399     raeburn   657:                     &prepare_functions($resurl,$forcereg,$group,undef,undef,1);
1.394     raeburn   658:                     ($trail) =
1.393     raeburn   659:                         &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype,undef,$title,1);
                    660:                 } else {
                    661:                     &Apache::lonhtmlcommon::add_breadcrumb(
1.392     raeburn   662:                     {text  => "Supplemental $crstype Content",
                    663:                      href  => "javascript:gopost('/adm/supplemental','')"});
1.393     raeburn   664:                     $title = &mt('View Resource');
1.394     raeburn   665:                     ($trail) = 
                    666:                         &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype,undef,$title,1);
1.392     raeburn   667:                 }
1.394     raeburn   668:                 return $trail;
1.412     raeburn   669:             } elsif ($resurl =~ m{^\Q/uploaded$courseurl/portfolio/syllabus/}) {
                    670:                 &Apache::lonhtmlcommon::clear_breadcrumbs();
                    671:                 &prepare_functions('/public'.$courseurl."/syllabus",
                    672:                                    $forcereg,$group,undef,undef,1);
                    673:                 $title = &mt('Syllabus File');
                    674:                 my ($trail) =
                    675:                     &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype,undef,$title,1);
                    676:                 return $trail;
1.392     raeburn   677:             }
1.395     raeburn   678:             unless ($env{'request.state'} eq 'construct') {
                    679:                 &Apache::lonhtmlcommon::clear_breadcrumbs();
                    680:                 &Apache::lonhtmlcommon::add_breadcrumb({text => 'View Resource'});
                    681:             }
1.392     raeburn   682:         }
1.390     raeburn   683:     } elsif (! $const_space){
1.328     droeschl  684:         #a situation when we're looking at a resource outside of context of a 
                    685:         #course or construction space (e.g. with cumulative rights)
                    686:         &Apache::lonhtmlcommon::clear_breadcrumbs();
1.390     raeburn   687:         unless ($env{'request.noversionuri'} =~ m{^/adm/$match_domain/$match_username/aboutme$}) {
                    688:             &Apache::lonhtmlcommon::add_breadcrumb({text => 'View Resource'});
                    689:         }
1.65      www       690:     }
1.41      www       691: # =============================================================================
                    692: # ============================ This is for URLs that actually can be registered
1.316     droeschl  693:     return '' unless ( ($env{'request.noversionuri'}!~m{^/(res/)*adm/}) 
                    694:                        || $forcereg );
1.390     raeburn   695:     my ($cdom,$cnum,%perms,$cfile,$switchserver,$home,$forceedit,
                    696:         $forceview,$editbutton);
1.391     raeburn   697:     if (($resurl =~ m{^/?adm/($match_domain)/($match_username)/aboutme$}) ||
                    698:         ($env{'request.role'} !~/^(aa|ca|au)/)) {
1.390     raeburn   699:         $editbutton = &prepare_functions($resurl,$forcereg,$group);
                    700:     }
                    701:     if ($editbutton eq '') {
1.399     raeburn   702:         $editbutton = &clear(6,1);
1.390     raeburn   703:     }
1.317     droeschl  704: 
1.390     raeburn   705: #
                    706: # This applies in course context
                    707: #
                    708:     if ($env{'request.course.id'}) {
                    709:         $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                    710:         $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                    711:         $perms{'mdc'} = &Apache::lonnet::allowed('mdc',$env{'request.course.id'});
                    712:         my @privs;
                    713:         if ($env{'request.symb'} ne '') {
                    714:              if ($env{'request.filename'}=~/$LONCAPA::assess_re/) {
                    715:                  push(@privs,('mgr','vgr'));
                    716:              }
                    717:              push(@privs,'opa');
                    718:         }
                    719:         foreach my $priv (@privs) {
                    720:             $perms{$priv} = &Apache::lonnet::allowed($priv,$env{'request.course.id'});
                    721:             if (!$perms{$priv} && $env{'request.course.sec'} ne '') {
                    722:                 $perms{$priv} = 
                    723:                     &Apache::lonnet::allowed($priv,"$env{'request.course.id'}/$env{'request.course.sec'}");
                    724:             }
                    725:         }
                    726: #
                    727: # Determine whether or not to show Grades and Submissions buttons
                    728: #
                    729:         if ($env{'request.symb'} ne '' &&
                    730:             $env{'request.filename'}=~/$LONCAPA::assess_re/) {
                    731:             if ($perms{'mgr'}) {
                    732:                 &switch('','',7,2,'pgrd.png','Content Grades','grades[_4]',
                    733:                         "gocmd('/adm/grades','gradingmenu')",
                    734:                         'Content Grades');
                    735:             } elsif ($perms{'vgr'}) {
                    736:                 &switch('','',7,2,'subm.png','Content Submissions','missions[_1]',
                    737:                         "gocmd('/adm/grades','submission')",
                    738:                         'Content Submissions');
                    739:              }
                    740:         }
                    741:         if (($env{'request.symb'} ne '') && ($perms{'opa'})) {
                    742:             &switch('','',7,3,'pparm.png','Content Settings','parms[_2]',
                    743:                     "gocmd('/adm/parmset','set')",
                    744:                     'Content Settings');
1.107     albertel  745: 	}
1.393     raeburn   746: # End grades/submissions check
1.107     albertel  747: 
1.274     www       748: #
1.393     raeburn   749: # This applies to items inside a folder/page modifiable in the course.
1.274     www       750: #
1.390     raeburn   751:         if (($env{'request.symb'}=~/^uploaded/) && ($perms{'mdc'})) {
1.393     raeburn   752:             my $text = 'Edit Folder';
1.395     raeburn   753:             if (($mapurl =~ /\.page$/) ||
                    754:                 ($env{'request.symb'}=~
1.396     raeburn   755:                      m{uploaded/$cdom/$cnum/default_\d+\.page$}))  {
1.393     raeburn   756:                 $text = 'Edit Page';
                    757:             }
                    758:             &switch('','',7,4,'docs-22x22.png',$text,'parms[_2]',
1.390     raeburn   759:                     "gocmd('/adm/coursedocs','direct')",
                    760:                     'Folder/Page Content');
1.258     raeburn   761:         }
1.390     raeburn   762: # End modifiable folder/page container check
                    763:     }
                    764: # End course context
                    765: 
1.41      www       766: # Prepare the rest of the buttons
1.383     raeburn   767:         my ($menuitems,$got_prt,$got_wishlist);
1.120     raeburn   768:         if ($const_space) {
1.274     www       769: #
                    770: # We are in construction space
                    771: #
1.353     www       772: 
1.355     raeburn   773:             my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'};
1.353     www       774: 	    my ($udom,$uname,$thisdisfn) =
1.355     raeburn   775: 		($env{'request.filename'}=~m{^\Q$londocroot/priv/\E([^/]+)/([^/]+)/(.*)$});
1.353     www       776:             my $currdir = '/priv/'.$udom.'/'.$uname.'/'.$thisdisfn;
1.131     raeburn   777:             if ($currdir =~ m-/$-) {
                    778:                 $is_const_dir = 1;
                    779:             } else {
1.267     droeschl  780:                 $currdir =~ s|[^/]+$||;
1.200     foxr      781: 		my $cleandisfn = &Apache::loncommon::escape_single($thisdisfn);
1.208     albertel  782: 		my $esc_currdir = &Apache::loncommon::escape_single($currdir);
1.274     www       783: #
                    784: # Probably should be in mydesk.tab
                    785: #
1.131     raeburn   786:                 $menuitems=(<<ENDMENUITEMS);
1.344     www       787: s&6&1&list.png&Directory&dir[_1]&golist('$esc_currdir')&List current directory
1.353     www       788: s&6&2&rtrv.png&Retrieve&version[_1]&gocstr('/adm/retrieve','/priv/$udom/$uname/$cleandisfn')&Retrieve old version
                    789: s&6&3&pub.png&Publish&resource[_3]&gocstr('/adm/publish','/priv/$udom/$uname/$cleandisfn')&Publish this resource
                    790: s&7&1&del.png&Delete&resource[_2]&gocstr('/adm/cfile?action=delete','/priv/$udom/$uname/$cleandisfn')&Delete this resource
                    791: s&7&2&prt.png&Print&printout[_1]&gocstr('/adm/printout','/priv/$udom/$uname/$cleandisfn')&Prepare a printable document
1.120     raeburn   792: ENDMENUITEMS
1.131     raeburn   793:             }
1.308     raeburn   794:                 if (ref($bread_crumbs) eq 'ARRAY') {
                    795:                     &Apache::lonhtmlcommon::clear_breadcrumbs();
                    796:                     foreach my $crumb (@{$bread_crumbs}){
                    797:                         &Apache::lonhtmlcommon::add_breadcrumb($crumb);
                    798:                     }
                    799:                 }
1.203     foxr      800:         } elsif ( defined($env{'request.course.id'}) && 
                    801: 		 $env{'request.symb'} ne '' ) {
1.274     www       802: #
1.383     raeburn   803: # We are in a course and looking at a registered URL
1.274     www       804: # Should probably be in mydesk.tab
                    805: #
1.120     raeburn   806: 	    $menuitems=(<<ENDMENUITEMS);
1.41      www       807: c&3&1
1.344     www       808: s&2&1&back.png&&&gopost('/adm/flip','back:'+currentURL)&Previous content resource&&1
                    809: s&2&3&forw.png&&&gopost('/adm/flip','forward:'+currentURL)&Next content resource&&3
1.77      www       810: c&6&3
                    811: c&8&1
                    812: c&8&2
1.344     www       813: s&8&3&prt.png&Print&printout[_1]&gopost('/adm/printout',currentURL)&Prepare a printable document
1.41      www       814: ENDMENUITEMS
1.383     raeburn   815:             $got_prt = 1;
                    816:             if (($env{'user.adv'}) && ($env{'request.uri'} =~ /^\/res/)
                    817:                 && (!$env{'request.enc'})) {
1.332     wenzelju  818:                 # wishlist is only available for users with access to resource-pool
                    819:                 # and links can only be set for resources within the resource-pool
                    820:                 $menuitems .= (<<ENDMENUITEMS);
1.431     golterma  821: s&9&1&wishlist-link.png&Stored Links&wishlistlink[_2]&set_wishlistlink()&Save a link for this resource in my personal Stored Links repository&&1
1.332     wenzelju  822: ENDMENUITEMS
1.383     raeburn   823:                 $got_wishlist = 1;
1.332     wenzelju  824:             }
1.216     albertel  825: 
1.243     tempelho  826: my $currentURL = &Apache::loncommon::get_symb();
                    827: my ($symb_old,$symb_old_enc) = &Apache::loncommon::clean_symb($currentURL);
                    828: my $annotation = &Apache::loncommon::get_annotation($symb_old,$symb_old_enc);
                    829: $menuitems.="s&9&3&";
                    830: if(length($annotation) > 0){
1.317     droeschl  831: 	$menuitems.="anot2.png";
1.243     tempelho  832: }else{
1.317     droeschl  833: 	$menuitems.="anot.png";
1.243     tempelho  834: }
1.344     www       835: $menuitems.="&Notes&&annotate()&";
1.243     tempelho  836: $menuitems.="Make notes and annotations about this resource&&1\n";
1.428     raeburn   837: my $is_mobile;
                    838: if ($env{'browser.mobile'}) {
                    839:     $is_mobile = 1;
                    840: }
1.243     tempelho  841: 
1.323     raeburn   842:             unless ($env{'request.noversionuri'}=~/\/(bulletinboard|smppg|navmaps|syllabus|aboutme|viewclasslist|portfolio)(\?|$)/) {
1.382     raeburn   843: 		if ((!$env{'request.enc'}) && ($env{'request.noversionuri'} !~ m{^/adm/wrapper/ext/}) && ($env{'request.noversionuri'} !~ m{^/uploaded/$match_domain/$match_courseid/docs/})) {
1.216     albertel  844: 		    $menuitems.=(<<ENDREALRES);
1.428     raeburn   845: s&6&3&catalog.png&Info&info[_1]&catalog_info('$is_mobile')&Show Metadata
1.216     albertel  846: ENDREALRES
                    847:                 }
1.422     raeburn   848:                 unless (($env{'request.noversionuri'} =~ m{^/uploaded/$match_domain/$match_courseid/docs/}) ||
                    849:                         ($env{'request.noversionuri'} =~ m{^\Q/adm/wrapper/\E(ext|uploaded)/})) {  
1.382     raeburn   850:                     $menuitems.=(<<ENDREALRES);
1.344     www       851: s&8&1&eval.png&Evaluate&this[_1]&gopost('/adm/evaluate',currentURL,1)&Provide my evaluation of this resource
1.382     raeburn   852: ENDREALRES
                    853:                 }
1.422     raeburn   854:                 unless ($env{'request.noversionuri'} =~ m{^\Q/adm/wrapper/\E(ext|uploaded)/}) {
                    855:                     $menuitems.=(<<ENDREALRES);
1.344     www       856: s&8&2&fdbk.png&Communicate&discuss[_1]&gopost('/adm/feedback',currentURL,1)&Provide feedback messages or contribute to the course discussion about this resource
1.77      www       857: ENDREALRES
1.422     raeburn   858:                 }
1.120     raeburn   859: 	    }
                    860:         }
1.203     foxr      861: 	if ($env{'request.uri'} =~ /^\/res/) {
1.383     raeburn   862:             unless ($got_prt) {
                    863: 	        $menuitems .= (<<ENDMENUITEMS);
1.344     www       864: s&8&3&prt.png&Print&printout[_1]&gopost('/adm/printout',currentURL)&Prepare a printable document
1.203     foxr      865: ENDMENUITEMS
1.384     raeburn   866:                 $got_prt = 1;
1.383     raeburn   867:             }
                    868:             unless ($got_wishlist) {
                    869:                 if (($env{'user.adv'}) && (!$env{'request.enc'})) {
                    870:                     # wishlist is only available for users with access to resource-pool
                    871:                     $menuitems .= (<<ENDMENUITEMS);
1.431     golterma  872: s&9&1&wishlist-link.png&Stored Links&wishlistlink[_2]&set_wishlistlink()&Save a link for this resource in your personal Stored Links repository&&1
1.332     wenzelju  873: ENDMENUITEMS
1.383     raeburn   874:                     $got_wishlist = 1;
                    875:                 }
                    876: 	    }
                    877:         }
1.41      www       878:         my $buttons='';
                    879:         foreach (split(/\n/,$menuitems)) {
                    880: 	    my ($command,@rest)=split(/\&/,$_);
1.220     raeburn   881:             my $idx=10*$rest[0]+$rest[1];
                    882:             if (&hidden_button_check() eq 'yes') {
                    883:                 if ($idx == 21 ||$idx == 23) {
                    884:                     $buttons.=&switch('','',@rest);
                    885:                 } else {
                    886:                     $buttons.=&clear(@rest);
                    887:                 }
                    888:             } else {  
                    889:                 if ($command eq 's') {
                    890: 	            $buttons.=&switch('','',@rest);
                    891:                 } else {
                    892:                     $buttons.=&clear(@rest);
                    893:                 }
1.41      www       894:             }
                    895:         }
1.148     albertel  896: 
                    897: 	    my $addremote=0;
1.267     droeschl  898: 	    foreach (@inlineremote) { if ($_ ne '') { $addremote=1; last;} }
1.301     droeschl  899:     if ($addremote) {
                    900: 
1.342     www       901:         &Apache::lonhtmlcommon::clear_breadcrumb_tools();
1.301     droeschl  902: 
1.342     www       903:             &Apache::lonhtmlcommon::add_breadcrumb_tool(
1.312     droeschl  904:                 'navigation', @inlineremote[21,23]);
                    905: 
1.378     raeburn   906:         my $countdown = &countdown_timer();
                    907:         if (&hidden_button_check() eq 'yes') {
                    908:             if ($countdown) {
                    909:                 &Apache::lonhtmlcommon::add_breadcrumb_tool('tools',$countdown);
                    910:             }
                    911:         } else {
                    912:             my @tools = @inlineremote[93,91,81,82,83];
                    913:             if ($countdown) {
                    914:                 unshift(@tools,$countdown);
                    915:             }
1.342     www       916:             &Apache::lonhtmlcommon::add_breadcrumb_tool(
1.378     raeburn   917:                 'tools',@tools);
1.313     droeschl  918: 
                    919:             #publish button in construction space
                    920:             if ($env{'request.state'} eq 'construct'){
1.342     www       921:                 &Apache::lonhtmlcommon::add_breadcrumb_tool(
1.349     raeburn   922:                      'advtools', $inlineremote[63]);
1.342     www       923:             } else {
                    924:                 &Apache::lonhtmlcommon::add_breadcrumb_tool(
1.349     raeburn   925:                      'tools', $inlineremote[63]);
1.313     droeschl  926:             }
1.390     raeburn   927:             &advtools_crumbs(@inlineremote);
1.301     droeschl  928:         }
1.38      www       929:     }
                    930: 
1.342     www       931:     return   &Apache::lonhtmlcommon::scripttag('', 'start')
                    932:            . &Apache::lonhtmlcommon::breadcrumbs(undef,undef,0)
                    933:            . &Apache::lonhtmlcommon::scripttag('', 'end');
1.38      www       934: }
                    935: 
1.389     raeburn   936: sub get_editbutton {
1.390     raeburn   937:     my ($cfile,$home,$switchserver,$forceedit,$forceview,$forcereg) = @_;
1.398     raeburn   938:     my $jscall;
                    939:     if (($forceview) && ($env{'form.todocs'})) {
                    940:         my ($folderpath,$command);
                    941:         if ($env{'request.symb'}) {
                    942:             $folderpath = &Apache::loncommon::symb_to_docspath($env{'request.symb'});
                    943:         } elsif ($env{'form.folderpath'} =~ /^supplemental/) {
                    944:             $folderpath = $env{'form.folderpath'};
                    945:             $command = '&forcesupplement=1';
                    946:         }
                    947:         $folderpath = &escape(&HTML::Entities::encode(&escape($folderpath),'<>&"'));
                    948:         $jscall = "go('/adm/coursedocs?folderpath=$folderpath$command')";
                    949:     } else {
                    950:         $jscall = &Apache::lonhtmlcommon::jump_to_editres($cfile,$home,$switchserver,
1.393     raeburn   951:                                                 $forceedit,$forcereg,$env{'request.symb'},
                    952:                                                 &escape($env{'form.folderpath'}),
                    953:                                                 &escape($env{'form.title'}),$env{'form.idx'},
1.398     raeburn   954:                                                 &escape($env{'form.suppurl'},$env{'form.todocs'}));
                    955:     }
1.389     raeburn   956:     if ($jscall) {
1.390     raeburn   957:         my $icon = 'pcstr.png';
                    958:         my $label = 'Edit';
                    959:         if ($forceview) {
                    960:             $icon = 'tolastloc.png';
                    961:             $label = 'Exit Editing';
                    962:         }
                    963:         &switch('','',6,1,$icon,$label,'resource[_2]',
                    964:                 $jscall,"Edit this resource");
                    965:         return 1;
                    966:     }
                    967:     return;
                    968: }
                    969: 
                    970: sub prepare_functions {
1.393     raeburn   971:     my ($resurl,$forcereg,$group,$bread_crumbs,$advtools,$docscrumbs) = @_;
1.390     raeburn   972:     unless ($env{'request.registered'}) {
                    973:         undef(@inlineremote);
                    974:     }
                    975:     my ($cdom,$cnum,%perms,$cfile,$switchserver,$home,$forceedit,
                    976:         $forceview);
                    977: 
                    978:     if ($env{'request.course.id'}) {
                    979:         $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                    980:         $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                    981:         $perms{'mdc'} = &Apache::lonnet::allowed('mdc',$env{'request.course.id'});
                    982:     }
                    983: 
                    984:     my $editbutton = '';
                    985: #
                    986: # Determine whether or not to display 'Edit' icon/button
                    987: #
                    988:     if ($resurl =~ m{^/?adm/($match_domain)/($match_username)/aboutme$}) {
                    989:         my $file=&Apache::lonnet::declutter($env{'request.filename'});
1.391     raeburn   990:         ($cfile,$home,$switchserver,$forceedit,$forceview) =
                    991:             &Apache::lonnet::can_edit_resource($file,$cnum,$cdom,
                    992:                 &Apache::lonnet::clutter($resurl),$env{'request.symb'},$group);
                    993:         if (($cfile) && ($home ne '') && ($home ne 'no_host')) {
                    994:             $editbutton = &get_editbutton($cfile,$home,$switchserver,
1.390     raeburn   995:                                           $forceedit,$forceview,$forcereg);
                    996:         }
1.391     raeburn   997:     } elsif ((!$env{'request.course.id'}) &&
1.390     raeburn   998:              ($env{'user.author'}) && ($env{'request.filename'}) &&
                    999:              ($env{'request.role'} !~/^(aa|ca|au)/)) {
                   1000: #
                   1001: # Currently do not have the role of author or co-author.
                   1002: # Do we have authoring privileges for the resource?
                   1003: #
                   1004:         my $file=&Apache::lonnet::declutter($env{'request.filename'});
                   1005:         ($cfile,$home,$switchserver,$forceedit,$forceview) =
                   1006:             &Apache::lonnet::can_edit_resource($file,$cnum,$cdom,
                   1007:                 &Apache::lonnet::clutter($resurl),$env{'request.symb'},$group);
                   1008:         if (($cfile) && ($home ne '') && ($home ne 'no_host')) {
                   1009:             $editbutton = &get_editbutton($cfile,$home,$switchserver,
                   1010:                                           $forceedit,$forceview,$forcereg);
                   1011:         }
                   1012:     } elsif ($env{'request.course.id'}) {
                   1013: #
                   1014: # This applies in course context
                   1015: #
1.412     raeburn  1016:         if (($perms{'mdc'}) &&
                   1017:             (($resurl eq "/public/$cdom/$cnum/syllabus") ||
                   1018:             ($resurl =~ m{^/uploaded/$cdom/$cnum/portfolio/syllabus/}))) {
1.411     raeburn  1019:             $cfile = $resurl;
                   1020:             $home = &Apache::lonnet::homeserver($cnum,$cdom);
                   1021:             if ($env{'form.forceedit'}) {
                   1022:                 $forceview = 1;
1.390     raeburn  1023:             } else {
1.411     raeburn  1024:                 $forceedit = 1;
1.390     raeburn  1025:             }
1.411     raeburn  1026:             $editbutton = &get_editbutton($cfile,$home,$switchserver,
                   1027:                                           $forceedit,$forceview,$forcereg);
1.393     raeburn  1028:         } elsif (($resurl eq '/adm/extresedit') &&
                   1029:                  (($env{'form.symb'}) || ($env{'form.folderpath'}))) {
                   1030:             ($cfile,$home,$switchserver,$forceedit,$forceview) =
                   1031:             &Apache::lonnet::can_edit_resource($resurl,$cnum,$cdom,$resurl,
                   1032:                                                $env{'form.symb'});
                   1033:             if ($cfile ne '') {
                   1034:                 $editbutton = &get_editbutton($cfile,$home,$switchserver,
                   1035:                                               $forceedit,$forceview,$forcereg,
                   1036:                                               $env{'form.title'},$env{'form.suppurl'});
                   1037:             }
1.406     raeburn  1038:         } elsif (($resurl =~ m{^/?adm/viewclasslist$}) &&
                   1039:                  (&Apache::lonnet::allowed('opa',$env{'request.course.id'}))) {
                   1040:             ($cfile,$home,$switchserver,$forceedit,$forceview) =
                   1041:             &Apache::lonnet::can_edit_resource($resurl,$cnum,$cdom,$resurl,
                   1042:                                                $env{'form.symb'});
                   1043:             $editbutton = &get_editbutton($cfile,$home,$switchserver,
                   1044:                                           $forceedit,$forceview,$forcereg);
1.405     raeburn  1045:         } elsif (($resurl !~ m{^/?adm/($match_domain)/($match_username)/aboutme$}) &&
                   1046:                  ($resurl ne '/cgi-bin/printout.pl')) {
1.390     raeburn  1047:             if ($env{'request.filename'}) {
                   1048:                 my $file=&Apache::lonnet::declutter($env{'request.filename'});
                   1049:                 ($cfile,$home,$switchserver,$forceedit,$forceview) =
                   1050:                     &Apache::lonnet::can_edit_resource($file,$cnum,$cdom,
                   1051:                         &Apache::lonnet::clutter($resurl),$env{'request.symb'},$group);
                   1052:                 if ($cfile ne '') {
                   1053:                     $editbutton = &get_editbutton($cfile,$home,$switchserver,
                   1054:                                                   $forceedit,$forceview,$forcereg);
                   1055:                 }
                   1056:             }
                   1057:         }
                   1058:     }
                   1059: # End determination of 'Edit' icon/button display
                   1060: 
1.393     raeburn  1061:     if ($env{'request.course.id'}) {
1.390     raeburn  1062: # This applies to about me page for users in a course
1.391     raeburn  1063:         if ($resurl =~ m{^/?adm/($match_domain)/($match_username)/aboutme$}) {
1.390     raeburn  1064:             my ($sdom,$sname) = ($1,$2);
                   1065:             unless (&Apache::lonnet::is_course($sdom,$sname)) {
                   1066:                 &switch('','',6,4,'mail-message-new-22x22.png','Message to user',
                   1067:                         '',
1.415     raeburn  1068:                         "go('/adm/email?compose=individual&amp;recname=$sname&amp;recdom=$sdom')",
1.390     raeburn  1069:                             'Send message to specific user');
                   1070:             }
1.391     raeburn  1071:             my $hideprivileged = 1;
                   1072:             if (&Apache::lonnet::in_course($sdom,$sname,$cdom,$cnum,undef,
                   1073:                                            $hideprivileged)) {
1.390     raeburn  1074:                 foreach my $priv ('vsa','vgr','srm') {
                   1075:                     $perms{$priv} = &Apache::lonnet::allowed($priv,$env{'request.course.id'});
                   1076:                     if (!$perms{$priv} && $env{'request.course.sec'} ne '') {
                   1077:                         $perms{$priv} =
                   1078:                             &Apache::lonnet::allowed($priv,"$env{'request.course.id'}/$env{'request.course.sec'}");
                   1079:                     }
                   1080:                 }
                   1081:                 if ($perms{'vsa'}) {
                   1082:                     &switch('','',6,5,'trck-22x22.png','Activity',
                   1083:                             '',
                   1084:                             "go('/adm/trackstudent?selected_student=$sname:$sdom')",
                   1085:                             'View recent activity by this person');
                   1086:                 }
                   1087:                 if ($perms{'vgr'}) {
                   1088:                     &switch('','',6,6,'rsrv-22x22.png','Reservations',
                   1089:                             '',
1.415     raeburn  1090:                             "go('/adm/slotrequest?command=showresv&amp;origin=aboutme&amp;uname=$sname&amp;udom=$sdom')",
1.390     raeburn  1091:                             'Slot reservation history');
                   1092:                 }
                   1093:                 if ($perms{'srm'}) {
                   1094:                     &switch('','',6,7,'contact-new-22x22.png','Records',
                   1095:                             '',
1.415     raeburn  1096:                             "go('/adm/email?recordftf=retrieve&amp;recname=$sname&amp;recdom=$sdom')",
1.390     raeburn  1097:                             'Add records');
                   1098:                 }
                   1099:             }
1.393     raeburn  1100:         }
                   1101:         if (($env{'form.folderpath'} =~ /^supplemental/) &&
                   1102:             (&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) &&
                   1103:             (($resurl =~ m{^/adm/wrapper/ext/}) ||
                   1104:              ($resurl =~ m{^/uploaded/$cdom/$cnum/supplemental/}) ||
1.397     raeburn  1105:              ($resurl eq '/adm/supplemental') ||
                   1106:              ($resurl =~ m{^/public/$cdom/$cnum/syllabus$}) ||
                   1107:              ($resurl =~ m{^/adm/$match_domain/$match_username/aboutme$}))) {
1.393     raeburn  1108:             my @folders=split('&',$env{'form.folderpath'});
1.394     raeburn  1109:             if ((@folders > 2) || ($resurl ne '/adm/supplemental')) {
1.393     raeburn  1110:                 my $esc_path=&escape(&HTML::Entities::encode(&escape($env{'form.folderpath'}),'<>&"'));
                   1111:                 &switch('','',7,4,'docs-22x22.png','Edit Folder','parms[_2]',
1.415     raeburn  1112:                         "location.href='/adm/coursedocs?command=direct&amp;forcesupplement=1&amp;supppath=$esc_path'",
1.393     raeburn  1113:                         'Folder/Page Content');
                   1114:             }
1.390     raeburn  1115:         }
                   1116:     }
                   1117: 
                   1118: # End checking for items for about me page for users in a course
1.393     raeburn  1119:     if ($docscrumbs) {
                   1120:         &Apache::lonhtmlcommon::clear_breadcrumb_tools();
                   1121:         &advtools_crumbs(@inlineremote);
                   1122:         return $editbutton;
                   1123:     } elsif ($env{'request.registered'}) {
1.390     raeburn  1124:         return $editbutton;
                   1125:     } else {
                   1126:         if (ref($bread_crumbs) eq 'ARRAY') {
                   1127:             if (@inlineremote > 0) {
                   1128:                 if (ref($advtools) eq 'ARRAY') {
                   1129:                     @{$advtools} = @inlineremote;
                   1130:                 }
                   1131:             }
                   1132:             return;
                   1133:         } elsif (@inlineremote > 0) {
                   1134:             &Apache::lonhtmlcommon::clear_breadcrumb_tools();
                   1135:             &advtools_crumbs(@inlineremote);
                   1136:             return   &Apache::lonhtmlcommon::scripttag('', 'start')
                   1137:                    . &Apache::lonhtmlcommon::breadcrumbs(undef,undef,0)
                   1138:                    . &Apache::lonhtmlcommon::scripttag('', 'end');
                   1139:         }
                   1140:     }
                   1141: }
                   1142: 
                   1143: sub advtools_crumbs {
                   1144:     my @funcs = @_;
                   1145:     if ($env{'request.noversionuri'} =~ m{^/adm/$match_domain/$match_username/aboutme$}) {
                   1146:         &Apache::lonhtmlcommon::add_breadcrumb_tool(
                   1147:             'advtools', @funcs[61,64,65,66,67,74]);
                   1148:     } elsif ($env{'request.noversionuri'} !~ m{^/adm/(navmaps|viewclasslist)(\?|$)}) {
                   1149:         &Apache::lonhtmlcommon::add_breadcrumb_tool(
                   1150:             'advtools', @funcs[61,71,72,73,74,92]);
1.393     raeburn  1151:     } elsif ($env{'request.noversionuri'} eq '/adm/viewclasslist') {
                   1152:         &Apache::lonhtmlcommon::add_breadcrumb_tool(
1.407     raeburn  1153:             'advtools', $funcs[61]);
1.393     raeburn  1154:     }
1.412     raeburn  1155:     return;
1.258     raeburn  1156: }
                   1157: 
1.2       www      1158: # ================================================================== Raw Config
                   1159: 
1.3       www      1160: sub clear {
                   1161:     my ($row,$col)=@_;
1.316     droeschl 1162:     $inlineremote[10*$row+$col]='';
                   1163:     return ''; 
1.3       www      1164: }
                   1165: 
1.40      www      1166: # ============================================ Switch a button or create a link
1.25      matthew  1167: # Switch acts on the javascript that is executed when a button is clicked.  
                   1168: # The javascript is usually similar to "go('/adm/roles')" or "cstrgo(..)".
1.40      www      1169: 
1.2       www      1170: sub switch {
1.209     www      1171:     my ($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat,$nobreak)=@_;
1.2       www      1172:     $act=~s/\$uname/$uname/g;
                   1173:     $act=~s/\$udom/$udom/g;
1.88      www      1174:     $top=&mt($top);
                   1175:     $bot=&mt($bot);
                   1176:     $desc=&mt($desc);
1.209     www      1177:     my $idx=10*$row+$col;
                   1178:     $category_members{$cat}.=':'.$idx;
                   1179: 
1.320     droeschl 1180: # Inline Menu
1.317     droeschl 1181:     if ($nobreak==2) { return ''; }
                   1182:     my $text=$top.' '.$bot;
                   1183:     $text=~s/\s*\-\s*//gs;
1.105     www      1184: 
1.317     droeschl 1185:     my $pic=
1.225     albertel 1186: 	   '<img alt="'.$text.'" src="'.
                   1187: 	   &Apache::loncommon::lonhttpdurl('/res/adm/pages/'.$img).
1.303     droeschl 1188: 	   '" align="'.($nobreak==3?'right':'left').'" class="LC_icon" />';
1.317     droeschl 1189:     if ($env{'browser.interface'} eq 'faketextual') {
1.274     www      1190: # Main Menu
1.103     www      1191: 	   if ($nobreak==3) {
1.209     www      1192: 	       $inlineremote[$idx]="\n".
1.177     albertel 1193: 		   '<td class="LC_menubuttons_text" align="right">'.$text.
1.247     harmsja  1194: 		   '</td><td align="left">'.
1.103     www      1195: 		   '<a href="javascript:'.$act.';">'.$pic.'</a></td></tr>';
                   1196: 	   } elsif ($nobreak) {
1.209     www      1197: 	       $inlineremote[$idx]="\n<tr>".
1.247     harmsja  1198: 		   '<td align="left">'.
1.177     albertel 1199: 		   '<a href="javascript:'.$act.';">'.$pic.'</a></td>
1.215     www      1200:                     <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>';
1.103     www      1201: 	   } else {
1.209     www      1202: 	       $inlineremote[$idx]="\n<tr>".
1.247     harmsja  1203: 		   '<td align="left">'.
1.103     www      1204: 		   '<a href="javascript:'.$act.';">'.$pic.
1.177     albertel 1205: 		   '</a></td><td class="LC_menubuttons_text" colspan="3">'.
1.215     www      1206: 		   '<a class="LC_menubuttons_link" href="javascript:'.$act.';"><span class="LC_menubuttons_inline_text">'.$desc.'</span></a></td></tr>';
1.103     www      1207: 	   }
1.317     droeschl 1208:     } else {
1.103     www      1209: # Inline Menu
1.378     raeburn  1210:         my @tools = (93,91,81,82,83);
                   1211:         unless ($env{'request.state'} eq 'construct') {
                   1212:             push(@tools,63);
                   1213:         }
                   1214:         if (($env{'environment.icons'} eq 'iconsonly') && 
                   1215:             (grep(/^$idx$/,@tools))) {
                   1216:             $inlineremote[$idx] =
                   1217:         '<a title="'.$desc.'" class="LC_menubuttons_link" href="javascript:'.$act.';">'.$pic.'</a>';
                   1218:         } else {
                   1219:             $inlineremote[$idx] =
1.317     droeschl 1220:        '<a title="'.$desc.'" class="LC_menubuttons_link" href="javascript:'.$act.';">'.$pic.
1.344     www      1221:        '<span class="LC_menubuttons_inline_text">'.$top.'&nbsp;</span></a>';
1.378     raeburn  1222:         }
1.317     droeschl 1223:     }
1.56      www      1224:     return '';
1.2       www      1225: }
                   1226: 
                   1227: sub secondlevel {
                   1228:     my $output='';
                   1229:     my 
1.209     www      1230:     ($uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc,$cat)=@_;
1.2       www      1231:     if ($prt eq 'any') {
1.209     www      1232: 	   $output.=&switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat);
1.2       www      1233:     } elsif ($prt=~/^r(\w+)/) {
                   1234:         if ($rol eq $1) {
1.209     www      1235:            $output.=&switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat);
1.2       www      1236:         }
                   1237:     }
                   1238:     return $output;
                   1239: }
                   1240: 
1.56      www      1241: sub inlinemenu {
1.210     albertel 1242:     undef(@inlineremote);
                   1243:     undef(%category_members);
1.275     www      1244: # calling rawconfig with "1" will evaluate mydesk.tab, even if there is no active remote control
1.56      www      1245:     &rawconfig(1);
1.309     bisitz   1246:     my $output='<table><tr>';
1.209     www      1247:     for (my $col=1; $col<=2; $col++) {
1.241     riegler  1248:         $output.='<td class="LC_mainmenu_col_fieldset">';
1.209     www      1249:         for (my $row=1; $row<=8; $row++) {
                   1250:             foreach my $cat (keys(%category_members)) {
                   1251:                if ($category_positions{$cat} ne "$col,$row") { next; }
1.247     harmsja  1252:                #$output.='<table><tr><td colspan="4" class="LC_menubuttons_category">'.&mt($category_names{$cat}).'</td></tr>';
1.309     bisitz   1253:                $output.='<div class="LC_Box LC_400Box">';
                   1254: 	       $output.='<h3 class="LC_hcell">'.&mt($category_names{$cat}).'</h3>';
1.247     harmsja  1255:                $output.='<table>';
1.240     riegler  1256:                my %active=();
                   1257:                foreach my $menu_item (split(/\:/,$category_members{$cat})) {
                   1258:                   if ($inlineremote[$menu_item]) {
                   1259:                      $active{$menu_item}=1;
                   1260:                   }
                   1261:                }  
                   1262:                foreach my $item (sort(keys(%active))) {
                   1263:                   $output.=$inlineremote[$item];
                   1264:                }
                   1265:                $output.='</table>';
1.245     harmsja  1266:                $output.='</div>';
1.240     riegler  1267:             }
                   1268:          }
                   1269:          $output.="</td>";
                   1270:     }
                   1271:     $output.="</tr></table>";
                   1272:     return $output;
                   1273: }
                   1274: 
1.2       www      1275: sub rawconfig {
1.274     www      1276: #
                   1277: # This evaluates mydesk.tab
                   1278: # Need to add more positions and more privileges to deal with all
                   1279: # menu items.
                   1280: #
1.34      www      1281:     my $textualoverride=shift;
                   1282:     my $output='';
1.316     droeschl 1283:     return '' unless $textualoverride;
1.152     albertel 1284:     my $uname=$env{'user.name'};
                   1285:     my $udom=$env{'user.domain'};
                   1286:     my $adv=$env{'user.adv'};
1.266     raeburn  1287:     my $show_course=&Apache::loncommon::show_course();
1.152     albertel 1288:     my $author=$env{'user.author'};
1.5       www      1289:     my $crs='';
1.295     raeburn  1290:     my $crstype='';
1.152     albertel 1291:     if ($env{'request.course.id'}) {
                   1292:        $crs='/'.$env{'request.course.id'};
                   1293:        if ($env{'request.course.sec'}) {
                   1294: 	   $crs.='_'.$env{'request.course.sec'};
1.7       www      1295:        }
1.8       www      1296:        $crs=~s/\_/\//g;
1.295     raeburn  1297:        $crstype = &Apache::loncommon::course_type();
1.5       www      1298:     }
1.152     albertel 1299:     my $pub=($env{'request.state'} eq 'published');
                   1300:     my $con=($env{'request.state'} eq 'construct');
                   1301:     my $rol=$env{'request.role'};
1.427     raeburn  1302:     my $requested_domain;
                   1303:     if ($rol) {
                   1304:        $requested_domain = $env{'request.role.domain'};
                   1305:     }
1.184     raeburn  1306:     foreach my $line (@desklines) {
1.209     www      1307:         my ($row,$col,$pro,$prt,$img,$top,$bot,$act,$desc,$cat)=split(/\:/,$line);
1.3       www      1308:         $prt=~s/\$uname/$uname/g;
                   1309:         $prt=~s/\$udom/$udom/g;
1.295     raeburn  1310:         if ($prt =~ /\$crs/) {
                   1311:             next unless ($env{'request.course.id'});
                   1312:             next if ($crstype eq 'Community');
                   1313:             $prt=~s/\$crs/$crs/g;
                   1314:         } elsif ($prt =~ /\$cmty/) {
                   1315:             next unless ($env{'request.course.id'});
                   1316:             next if ($crstype ne 'Community');
                   1317:             $prt=~s/\$cmty/$crs/g;
                   1318:         }
1.427     raeburn  1319:         if ($prt =~ m/\$requested_domain/) {
                   1320:             if ((!$requested_domain) && ($pro eq 'pbre') && ($env{'user.adv'})) {
                   1321:                 $prt=~s/\$requested_domain/$env{'user.domain'}/g;
                   1322:             } else {
                   1323:                 $prt=~s/\$requested_domain/$requested_domain/g;
                   1324:             }
                   1325:         }
1.211     www      1326:         if ($category_names{$cat}!~/\w/) { $cat='oth'; }
1.3       www      1327:         if ($pro eq 'clear') {
1.4       www      1328: 	    $output.=&clear($row,$col);
1.3       www      1329:         } elsif ($pro eq 'any') {
1.2       www      1330:                $output.=&secondlevel(
1.209     www      1331: 	  $uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc,$cat);
1.2       www      1332: 	} elsif ($pro eq 'smp') {
                   1333:             unless ($adv) {
                   1334:                $output.=&secondlevel(
1.209     www      1335:           $uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc,$cat);
1.2       www      1336:             }
                   1337:         } elsif ($pro eq 'adv') {
                   1338:             if ($adv) {
                   1339:                $output.=&secondlevel(
1.209     www      1340: 	  $uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc,$cat);
1.2       www      1341:             }
1.231     albertel 1342: 	} elsif ($pro eq 'shc') {
                   1343:             if ($show_course) {
                   1344:                $output.=&secondlevel(
                   1345:           $uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc,$cat);
                   1346:             }
                   1347:         } elsif ($pro eq 'nsc') {
                   1348:             if (!$show_course) {
                   1349:                $output.=&secondlevel(
                   1350: 	  $uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc,$cat);
                   1351:             }
1.81      matthew  1352:         } elsif (($pro=~/^p(\w+)/) && ($prt)) {
1.295     raeburn  1353:             my $priv = $1;
                   1354:             if ($priv =~ /^mdc(Course|Community)/) {
                   1355:                 if ($crstype eq $1) {
                   1356:                     $priv = 'mdc';
                   1357:                 } else {
                   1358:                     next;
                   1359:                 }
                   1360:             }
1.427     raeburn  1361:             if ((($priv eq 'bre') && (&Apache::lonnet::allowed($priv,$prt) eq 'F')) ||
                   1362:                 (($priv ne 'bre') && (&Apache::lonnet::allowed($priv,$prt)))) {
                   1363:                 $output.=&switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat);
1.4       www      1364:             }
1.295     raeburn  1365:         } elsif ($pro eq 'course')  {
                   1366:             if (($env{'request.course.fn'}) && ($crstype ne 'Community')) {
1.209     www      1367:                $output.=&switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat);
1.81      matthew  1368: 	    }
1.295     raeburn  1369:         } elsif ($pro eq 'community')  {
                   1370:             if (($env{'request.course.fn'}) && ($crstype eq 'Community')) {
                   1371:                $output.=&switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat);
                   1372:             }
1.124     matthew  1373:         } elsif ($pro =~ /^courseenv_(.*)$/) {
                   1374:             my $key = $1;
1.307     raeburn  1375:             if ($crstype ne 'Community') {
                   1376:                 my $coursepref = $env{'course.'.$env{'request.course.id'}.'.'.$key};
                   1377:                 if ($key eq 'canuse_pdfforms') {
                   1378:                     if ($env{'request.course.id'} && $coursepref eq '') {
                   1379:                         my %domdefs = &Apache::lonnet::get_domain_defaults($env{'course.'.$env{'request.course.id'}.'.domain'});
                   1380:                         $coursepref = $domdefs{'canuse_pdfforms'};
                   1381:                     }
                   1382:                 }
                   1383:                 if ($coursepref) { 
                   1384:                     $output.=&switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat);
                   1385:                 }
1.295     raeburn  1386:             }
                   1387:         } elsif ($pro =~ /^communityenv_(.*)$/) {
                   1388:             my $key = $1;
1.307     raeburn  1389:             if ($crstype eq 'Community') {
                   1390:                 my $coursepref = $env{'course.'.$env{'request.course.id'}.'.'.$key};
                   1391:                 if ($key eq 'canuse_pdfforms') {
                   1392:                     if ($env{'request.course.id'} && $coursepref eq '') {
                   1393:                         my %domdefs = &Apache::lonnet::get_domain_defaults($env{'course.'.$env{'request.course.id'}.'.domain'});
                   1394:                         $coursepref = $domdefs{'canuse_pdfforms'};
                   1395:                     }
                   1396:                 }
                   1397:                 if ($coursepref) { 
                   1398:                     $output.=&switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat);
                   1399:                 }
1.124     matthew  1400:             }
1.81      matthew  1401:         } elsif ($pro =~ /^course_(.*)$/) {
                   1402:             # Check for permissions inside of a course
1.295     raeburn  1403:             if (($env{'request.course.id'}) && ($crstype ne 'Community') && 
1.152     albertel 1404:                 (&Apache::lonnet::allowed($1,$env{'request.course.id'}.
                   1405:             ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))
1.81      matthew  1406:                  )) {
1.209     www      1407:                 $output.=&switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat);
1.26      www      1408: 	    }
1.295     raeburn  1409:         } elsif ($pro =~ /^community_(.*)$/) {
                   1410:             # Check for permissions inside of a community
                   1411:             if (($env{'request.course.id'}) && ($crstype eq 'Community') &&   
                   1412:                 (&Apache::lonnet::allowed($1,$env{'request.course.id'}.
                   1413:             ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))
                   1414:                  )) {
                   1415:                 $output.=&switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat);
                   1416:             }
1.4       www      1417:         } elsif ($pro eq 'author') {
                   1418:             if ($author) {
1.152     albertel 1419:                 if ((($prt eq 'rca') && ($env{'request.role'}=~/^ca/)) ||
1.234     raeburn  1420:                     (($prt eq 'raa') && ($env{'request.role'}=~/^aa/)) || 
1.152     albertel 1421:                     (($prt eq 'rau') && ($env{'request.role'}=~/^au/))) {
1.19      matthew  1422:                     # Check that we are on the correct machine
1.29      matthew  1423:                     my $cadom=$requested_domain;
1.152     albertel 1424:                     my $caname=$env{'user.name'};
1.234     raeburn  1425:                     if (($prt eq 'rca') || ($prt eq 'raa')) {
1.29      matthew  1426: 		       ($cadom,$caname)=
1.206     albertel 1427:                                ($env{'request.role'}=~/($match_domain)\/($match_username)$/);
1.29      matthew  1428:                     }                       
                   1429:                     $act =~ s/\$caname/$caname/g;
1.353     www      1430:                     $act =~ s/\$cadom/$cadom/g;
1.19      matthew  1431:                     my $home = &Apache::lonnet::homeserver($caname,$cadom);
1.109     albertel 1432: 		    my $allowed=0;
                   1433: 		    my @ids=&Apache::lonnet::current_machine_ids();
                   1434: 		    foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } }
                   1435: 		    if ($allowed) {
1.209     www      1436:                         $output.=&switch($caname,$cadom,
                   1437:                                         $row,$col,$img,$top,$bot,$act,$desc,$cat);
1.19      matthew  1438:                     }
1.6       www      1439:                 }
1.2       www      1440:             }
1.248     raeburn  1441:         } elsif ($pro eq 'tools') {
                   1442:             my @tools = ('aboutme','blog','portfolio');
                   1443:             if (grep(/^\Q$prt\E$/,@tools)) {
1.249     raeburn  1444:                 if (!&Apache::lonnet::usertools_access($env{'user.name'},
1.251     raeburn  1445:                                                        $env{'user.domain'},
                   1446:                                                        $prt,undef,'tools')) {
                   1447:                     $output.=&clear($row,$col);
                   1448:                     next;
                   1449:                 }
1.278     raeburn  1450:             } elsif (($prt eq 'reqcrsnsc') || ($prt eq 'reqcrsshc')) {
                   1451:                 if (($prt eq 'reqcrsnsc') && ($show_course))   {
                   1452:                     next;
                   1453:                 }
                   1454:                 if (($prt eq 'reqcrsshc') && (!$show_course)) {
                   1455:                     next;
                   1456:                 }
1.279     raeburn  1457:                 my $showreqcrs = &check_for_rcrs();
1.251     raeburn  1458:                 if (!$showreqcrs) {
1.248     raeburn  1459:                     $output.=&clear($row,$col);
                   1460:                     next;
                   1461:                 }
                   1462:             }
                   1463:             $prt='any';
                   1464:             $output.=&secondlevel(
                   1465:           $uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc,$cat);
1.2       www      1466:         }
1.13      harris41 1467:     }
1.2       www      1468:     return $output;
                   1469: }
                   1470: 
1.279     raeburn  1471: sub check_for_rcrs {
                   1472:     my $showreqcrs = 0;
1.424     raeburn  1473:     my @reqtypes = ('official','unofficial','community','textbook');
1.280     raeburn  1474:     foreach my $type (@reqtypes) {
1.279     raeburn  1475:         if (&Apache::lonnet::usertools_access($env{'user.name'},
                   1476:                                               $env{'user.domain'},
                   1477:                                               $type,undef,'requestcourses')) {
                   1478:             $showreqcrs = 1;
                   1479:             last;
                   1480:         }
                   1481:     }
1.280     raeburn  1482:     if (!$showreqcrs) {
                   1483:         foreach my $type (@reqtypes) {
                   1484:             if ($env{'environment.reqcrsotherdom.'.$type} ne '') {
                   1485:                 $showreqcrs = 1;
                   1486:                 last;
                   1487:             }
                   1488:         }
                   1489:     }
1.279     raeburn  1490:     return $showreqcrs;
                   1491: }
                   1492: 
1.306     raeburn  1493: sub dc_popup_js {
                   1494:     my %lt = &Apache::lonlocal::texthash(
                   1495:                                           more => '(More ...)',
                   1496:                                           less => '(Less ...)',
                   1497:                                         );
                   1498:     return <<"END";
                   1499: 
                   1500: function showCourseID() {
                   1501:     document.getElementById('dccid').style.display='block';
                   1502:     document.getElementById('dccid').style.textAlign='left';
1.307     raeburn  1503:     document.getElementById('dccid').style.textFace='normal';
1.369     raeburn  1504:     document.getElementById('dccidtext').innerHTML ='<a href="javascript:hideCourseID();" class="LC_menubuttons_link">$lt{'less'}</a>';
1.306     raeburn  1505:     return;
                   1506: }
                   1507: 
                   1508: function hideCourseID() {
                   1509:     document.getElementById('dccid').style.display='none';
1.369     raeburn  1510:     document.getElementById('dccidtext').innerHTML ='<a href="javascript:showCourseID()" class="LC_menubuttons_link">$lt{'more'}</a>';
1.306     raeburn  1511:     return;
                   1512: }
                   1513: 
                   1514: END
                   1515: 
                   1516: }
                   1517: 
1.378     raeburn  1518: sub countdown_toggle_js {
                   1519:     return <<"END";
                   1520: 
                   1521: function toggleCountdown() {
                   1522:     var countdownid = document.getElementById('duedatecountdown');
                   1523:     var currstyle = countdownid.style.display;
                   1524:     if (currstyle == 'inline') {
                   1525:         countdownid.style.display = 'none';
                   1526:         document.getElementById('ddcountcollapse').innerHTML='';
                   1527:         document.getElementById('ddcountexpand').innerHTML='&#9668;&nbsp;';
                   1528:     } else {
                   1529:         countdownid.style.display = 'inline';
                   1530:         document.getElementById('ddcountcollapse').innerHTML='&#9658;&nbsp;';
                   1531:         document.getElementById('ddcountexpand').innerHTML='';
                   1532:     }
                   1533:     return;
                   1534: }
                   1535: 
1.431.2.2! musolffc 1536: END
1.431.2.1  musolffc 1537: }
                   1538: 
1.431.2.2! musolffc 1539: # This creates a "done button" for timed events.  The confirmation box is a jQuerey
        !          1540: # dialog widget.  Clicking OK will set (done = 'true') which is checked in 
        !          1541: # lonhomework.pm.
        !          1542: sub done_button_js {
        !          1543:     return <<END;
        !          1544: 
        !          1545: <form method="post" name="doneButton">
        !          1546:     <input type="hidden" name="done" value=""/>
        !          1547:     <button id="done-confirm-opener" type="button">Done</button>
        !          1548: </form> 
        !          1549: 
        !          1550: <div id="done-confirm" title="WARNING!">
        !          1551:     <p></span>You are trying to end this timed event early.  Confirming that you are done will cause the time to expire and prevent you from changing any answers in the current folder.  Click "OK" if you are completely finished.  Click "Cancel" to continue working.</p>
        !          1552: </div>
        !          1553: 
        !          1554: <script>
        !          1555: \$( "#done-confirm" ).dialog({ autoOpen: false });
        !          1556: \$( "#done-confirm-opener" ).click(function() {
        !          1557:     \$( "#done-confirm" ).dialog( "open" );
        !          1558:     \$( "#done-confirm" ).dialog({
        !          1559:       resizable: false,
        !          1560:       height:320,
        !          1561:       modal: true,
        !          1562:       buttons: {
        !          1563:         "OK": function() {
        !          1564:             \$( this ).dialog( "close" );
        !          1565:             \$( '[name="done"]' )[0].value = 'true';
        !          1566:             \$( '[name="doneButton"]' )[0].submit();
        !          1567:         },
        !          1568:         Cancel: function() {
        !          1569:           \$( this ).dialog( "close" );
        !          1570:         }
        !          1571:       }    
        !          1572:     })
        !          1573: });
        !          1574: </script>
        !          1575: 
1.378     raeburn  1576: END
                   1577: }
                   1578: 
1.42      www      1579: sub utilityfunctions {
1.421     raeburn  1580:     my ($httphost) = @_;
1.152     albertel 1581:     my $currenturl=&Apache::lonnet::clutter(&Apache::lonnet::fixversion((split(/\?/,$env{'request.noversionuri'}))[0]));
1.316     droeschl 1582:     if ($currenturl =~ m{^/adm/wrapper/ext/}
                   1583:         && $env{'request.external.querystring'} ) {
1.293     raeburn  1584:             $currenturl .= ($currenturl=~/\?/)?'&':'?'.$env{'request.external.querystring'};
                   1585:     }
1.183     www      1586:     $currenturl=&Apache::lonenc::check_encrypt(&unescape($currenturl));
1.125     albertel 1587:     
1.152     albertel 1588:     my $currentsymb=&Apache::lonenc::check_encrypt($env{'request.symb'});
1.175     albertel 1589: 
1.306     raeburn  1590:     my $dc_popup_cid;
                   1591:     if ($env{'user.adv'} && exists($env{'user.role.dc./'.
                   1592:                         $env{'course.'.$env{'request.course.id'}.
                   1593:                                  '.domain'}.'/'})) {
                   1594:         $dc_popup_cid = &dc_popup_js();
                   1595:     }
                   1596: 
1.175     albertel 1597:     my $start_page_annotate = 
                   1598:         &Apache::loncommon::start_page('Annotator',undef,
                   1599: 				       {'only_body' => 1,
                   1600: 					'js_ready'  => 1,
                   1601: 					'bgcolor'   => '#BBBBBB',
                   1602: 					'add_entries' => {
                   1603: 					    'onload' => 'javascript:document.goannotate.submit();'}});
                   1604: 
1.205     albertel 1605:     my $end_page_annotate = 
                   1606:         &Apache::loncommon::end_page({'js_ready' => 1});
                   1607: 
1.389     raeburn  1608:     my $jumptores = &Apache::lonhtmlcommon::javascript_jumpto_resource();
1.336     raeburn  1609: 
1.368     www      1610:     my $esc_url=&escape($currenturl);
                   1611:     my $esc_symb=&escape($currentsymb);
1.332     wenzelju 1612: 
1.378     raeburn  1613:     my $countdown = &countdown_toggle_js();
                   1614: 
1.429     raeburn  1615:     my $hostvar = '
                   1616: function setLCHost() {
                   1617:     var lcHostname="";
                   1618: ';
                   1619:     if ($httphost =~ m{^https?\://}) {
                   1620:         $hostvar .= '    var lcServer="'.$httphost.'";'."\n".
                   1621:                     '    var hostReg = /^https?:\/\/([^\/]+)$/i;'."\n".
                   1622:                     '    var match = hostReg.exec(lcServer);'."\n".
                   1623:                     '    if (match.length) {'."\n".
                   1624:                     '        if (match[1] == location.hostname) {'."\n".
                   1625:                     '            lcHostname=lcServer;'."\n".
                   1626:                     '        }'."\n".
                   1627:                     '    }'."\n";
                   1628:     }
                   1629:     
                   1630:     $hostvar .= '    return lcHostname;'."\n".
                   1631: '}'."\n";
                   1632: 
1.42      www      1633: return (<<ENDUTILITY)
1.429     raeburn  1634:     $hostvar
1.368     www      1635:     var currentURL=unescape("$esc_url");
                   1636:     var reloadURL=unescape("$esc_url");
                   1637:     var currentSymb=unescape("$esc_symb");
1.42      www      1638: 
1.306     raeburn  1639: $dc_popup_cid
1.114     albertel 1640: 
1.389     raeburn  1641: $jumptores
1.336     raeburn  1642: 
1.42      www      1643: function gopost(url,postdata) {
                   1644:    if (url!='') {
1.429     raeburn  1645:       var lcHostname = setLCHost();
                   1646:       this.document.server.action=lcHostname+url;
1.42      www      1647:       this.document.server.postdata.value=postdata;
                   1648:       this.document.server.command.value='';
                   1649:       this.document.server.url.value='';
                   1650:       this.document.server.symb.value='';
                   1651:       this.document.server.submit();
                   1652:    }
                   1653: }
                   1654: 
                   1655: function gocmd(url,cmd) {
                   1656:    if (url!='') {
1.429     raeburn  1657:       var lcHostname = setLCHost();
                   1658:       this.document.server.action=lcHostname+url;
1.42      www      1659:       this.document.server.postdata.value='';
                   1660:       this.document.server.command.value=cmd;
                   1661:       this.document.server.url.value=currentURL;
                   1662:       this.document.server.symb.value=currentSymb;
                   1663:       this.document.server.submit();
                   1664:    }
1.57      www      1665: }
                   1666: 
1.121     raeburn  1667: function gocstr(url,filename) {
                   1668:     if (url == '/adm/cfile?action=delete') {
                   1669:         this.document.cstrdelete.filename.value = filename
                   1670:         this.document.cstrdelete.submit();
                   1671:         return;
                   1672:     }
1.137     raeburn  1673:     if (url == '/adm/printout') {
                   1674:         this.document.cstrprint.postdata.value = filename
                   1675:         this.document.cstrprint.curseed.value = 0;
                   1676:         this.document.cstrprint.problemtype.value = 0;
1.138     raeburn  1677:         if (this.document.lonhomework) {
                   1678:             if ((this.document.lonhomework.rndseed) && (this.document.lonhomework.rndseed.value != null) && (this.document.lonhomework.rndseed.value != '')) {
                   1679:                 this.document.cstrprint.curseed.value = this.document.lonhomework.rndseed.value
                   1680:             }
                   1681:             if (this.document.lonhomework.problemtype) {
1.164     albertel 1682: 		if (this.document.lonhomework.problemtype.value) {
                   1683: 		    this.document.cstrprint.problemtype.value = 
                   1684: 			this.document.lonhomework.problemtype.value;
                   1685: 		} else if (this.document.lonhomework.problemtype.options) {
                   1686: 		    for (var i=0; i<this.document.lonhomework.problemtype.options.length; i++) {
                   1687: 			if (this.document.lonhomework.problemtype.options[i].selected) {
                   1688: 			    if (this.document.lonhomework.problemtype.options[i].value != null && this.document.lonhomework.problemtype.options[i].value != '') { 
                   1689: 				this.document.cstrprint.problemtype.value = this.document.lonhomework.problemtype.options[i].value
                   1690: 				}
                   1691: 			}
                   1692: 		    }
                   1693: 		}
                   1694: 	    }
                   1695: 	}
1.137     raeburn  1696:         this.document.cstrprint.submit();
                   1697:         return;
                   1698:     }
1.121     raeburn  1699:     if (url !='') {
                   1700:         this.document.constspace.filename.value = filename;
                   1701:         this.document.constspace.action = url;
                   1702:         this.document.constspace.submit();
                   1703:     }
                   1704: }
                   1705: 
1.131     raeburn  1706: function golist(url) {
                   1707:    if (url!='' && url!= null) {
                   1708:        currentURL = null;
                   1709:        currentSymb= null;
1.429     raeburn  1710:        var lcHostname = setLCHost();
                   1711:        top.location.href=lcHostname+url;
1.131     raeburn  1712:    }
                   1713: }
                   1714: 
                   1715: 
1.121     raeburn  1716: 
1.428     raeburn  1717: function catalog_info(isMobile) {
                   1718:     if (isMobile == 1) {
                   1719:         openMyModal(window.location.pathname+'.meta?modal=1',500,400,'yes');
                   1720:     } else {
                   1721:         loncatinfo=window.open(window.location.pathname+'.meta',"LONcatInfo",'height=500,width=400,resizable=yes,scrollbars=yes,location=no,menubar=no,toolbar=no');
                   1722:     }
1.57      www      1723: }
                   1724: 
                   1725: function chat_win() {
1.429     raeburn  1726:    var lcHostname = setLCHost();
                   1727:    lonchat=window.open(lcHostname+'/res/adm/pages/chatroom.html',"LONchat",'height=320,width=480,resizable=yes,location=no,menubar=no,toolbar=no');
1.42      www      1728: }
1.169     raeburn  1729: 
                   1730: function group_chat(group) {
1.429     raeburn  1731:    var lcHostname = setLCHost();
                   1732:    var url = lcHostname+'/adm/groupchat?group='+group;
1.169     raeburn  1733:    var winName = 'LONchat_'+group;
                   1734:    grpchat=window.open(url,winName,'height=320,width=280,resizable=yes,location=no,menubar=no,toolbar=no');
                   1735: }
1.175     albertel 1736: 
                   1737: function annotate() {
                   1738:    w_Annotator_flag=1;
                   1739:    annotator=window.open('','Annotator','width=365,height=265,scrollbars=0');
                   1740:    annotator.document.write(
                   1741:    '$start_page_annotate'
                   1742:   +"<form name='goannotate' target='Annotator' method='post' "
                   1743:   +"action='/adm/annotations'>"
1.217     albertel 1744:   +"<input type='hidden' name='symbnew' value='"+currentSymb+"' />"
1.181     albertel 1745:   +"<\\/form>"
1.205     albertel 1746:   +'$end_page_annotate');
1.175     albertel 1747:    annotator.document.close();
                   1748: }
                   1749: 
1.370     raeburn  1750: function open_StoredLinks_Import(rat) {
1.335     wenzelju 1751:    var newWin;
1.429     raeburn  1752:    var lcHostname = setLCHost();
1.335     wenzelju 1753:    if (rat) {
1.429     raeburn  1754:        newWin = window.open(lcHostname+'/adm/wishlist?inhibitmenu=yes&mode=import&rat='+rat,
1.334     wenzelju 1755:                             'wishlistImport','scrollbars=1,resizable=1,menubar=0');
1.335     wenzelju 1756:    }
                   1757:    else {
1.429     raeburn  1758:        newWin = window.open(lcHostname+'/adm/wishlist?inhibitmenu=yes&mode=import',
1.335     wenzelju 1759:                             'wishlistImport','scrollbars=1,resizable=1,menubar=0');
                   1760:    }
1.334     wenzelju 1761:    newWin.focus();
                   1762: }
                   1763: 
1.372     raeburn  1764: (function (\$) {
                   1765:   \$(document).ready(function () {
                   1766:     \$.single=function(a){return function(b){a[0]=b;return a}}(\$([1]));
                   1767:     /*\@cc_on
                   1768:       if (!window.XMLHttpRequest) {
                   1769:         \$('.LC_hoverable').each(function () {
                   1770:           this.attachEvent('onmouseenter', function (evt) { \$.single(evt.srcElement).addClass('hover'); });
                   1771:           this.attachEvent('onmouseleave', function (evt) { \$.single(evt.srcElement).removeClass('hover'); });
                   1772:         });
                   1773:       }
                   1774:     \@*/
                   1775:   });
                   1776: }(jQuery));
                   1777: 
1.378     raeburn  1778: $countdown
                   1779: 
1.42      www      1780: ENDUTILITY
                   1781: }
                   1782: 
                   1783: sub serverform {
                   1784:     return(<<ENDSERVERFORM);
1.181     albertel 1785: <form name="server" action="/adm/logout" method="post" target="_top">
1.42      www      1786: <input type="hidden" name="postdata" value="none" />
                   1787: <input type="hidden" name="command" value="none" />
                   1788: <input type="hidden" name="url" value="none" />
                   1789: <input type="hidden" name="symb" value="none" />
                   1790: </form>
                   1791: ENDSERVERFORM
                   1792: }
1.113     albertel 1793: 
1.121     raeburn  1794: sub constspaceform {
                   1795:     return(<<ENDCONSTSPACEFORM);
1.181     albertel 1796: <form name="constspace" action="/adm/logout" method="post" target="_top">
1.121     raeburn  1797: <input type="hidden" name="filename" value="" />
                   1798: </form>
1.181     albertel 1799: <form name="cstrdelete" action="/adm/cfile" method="post" target="_top">
1.121     raeburn  1800: <input type="hidden" name="action" value="delete" /> 
                   1801: <input type="hidden" name="filename" value="" />
                   1802: </form>
1.181     albertel 1803: <form name="cstrprint" action="/adm/printout" target="_parent" method="post">
1.137     raeburn  1804: <input type="hidden" name="postdata" value="" />
                   1805: <input type="hidden" name="curseed" value="" />
                   1806: <input type="hidden" name="problemtype" value="" />
                   1807: </form>
                   1808: 
1.121     raeburn  1809: ENDCONSTSPACEFORM
                   1810: }
                   1811: 
1.220     raeburn  1812: sub hidden_button_check {
1.317     droeschl 1813:     if ( $env{'request.course.id'} eq ''
                   1814:          || $env{'request.role.adv'} ) {
                   1815: 
1.220     raeburn  1816:         return;
                   1817:     }
1.232     raeburn  1818:     my $buttonshide = &Apache::lonnet::EXT('resource.0.buttonshide');
                   1819:     return $buttonshide; 
1.220     raeburn  1820: }
1.184     raeburn  1821: 
1.235     raeburn  1822: sub roles_selector {
1.421     raeburn  1823:     my ($cdom,$cnum,$httphost) = @_;
1.298     raeburn  1824:     my $crstype = &Apache::loncommon::course_type();
1.235     raeburn  1825:     my $now = time;
1.350     raeburn  1826:     my (%courseroles,%seccount,%courseprivs);
1.235     raeburn  1827:     my $is_cc;
1.401     raeburn  1828:     my ($js,$form,$switcher,$switchtext);
1.298     raeburn  1829:     my $ccrole;
                   1830:     if ($crstype eq 'Community') {
                   1831:         $ccrole = 'co';
                   1832:     } else {
                   1833:         $ccrole = 'cc';
1.350     raeburn  1834:     }
1.386     raeburn  1835:     my ($priv,$gotsymb,$destsymb);
1.350     raeburn  1836:     my $destinationurl = $ENV{'REQUEST_URI'};
1.386     raeburn  1837:     if ($destinationurl =~ /\?symb=/) {
                   1838:         $gotsymb = 1;
                   1839:     } elsif ($destinationurl =~ m{^/enc/}) {
                   1840:         my $plainurl = &Apache::lonenc::unencrypted($destinationurl);
                   1841:         if ($plainurl =~ /\?symb=/) {
                   1842:             $gotsymb = 1;
                   1843:         }
                   1844:     }
                   1845:     unless ($gotsymb) {
                   1846:         $destsymb = &Apache::lonnet::symbread();
                   1847:         if ($destsymb ne '') {
                   1848:             $destsymb = &Apache::lonenc::check_encrypt($destsymb);
                   1849:         }
                   1850:     }
1.350     raeburn  1851:     my $reqprivs = &required_privs();
                   1852:     if (ref($reqprivs) eq 'HASH') {
                   1853:         my $destination = $destinationurl;
                   1854:         $destination =~ s/(\?.*)$//;
                   1855:         if (exists($reqprivs->{$destination})) {
                   1856:             $priv = $reqprivs->{$destination};
                   1857:         }
                   1858:     }
1.298     raeburn  1859:     if ($env{'user.role.'.$ccrole.'./'.$cdom.'/'.$cnum}) {
                   1860:         my ($start,$end) = split(/\./,$env{'user.role.'.$ccrole.'./'.$cdom.'/'.$cnum});
1.235     raeburn  1861:         
                   1862:         if ((($start) && ($start<0)) || 
                   1863:             (($end) && ($end<$now))  ||
                   1864:             (($start) && ($now<$start))) {
                   1865:             $is_cc = 0;
                   1866:         } else {
                   1867:             $is_cc = 1;
                   1868:         }
                   1869:     }
                   1870:     if ($is_cc) {
1.350     raeburn  1871:         &get_all_courseroles($cdom,$cnum,\%courseroles,\%seccount,\%courseprivs,$priv);
1.235     raeburn  1872:     } else {
1.262     raeburn  1873:         my %gotnosection;
1.235     raeburn  1874:         foreach my $item (keys(%env)) {
1.239     raeburn  1875:             if ($item =~ m-^user\.role\.([^.]+)\./\Q$cdom\E/\Q$cnum\E/?(\w*)$-) {
1.235     raeburn  1876:                 my $role = $1;
                   1877:                 my $sec = $2;
                   1878:                 next if ($role eq 'gr');
                   1879:                 my ($start,$end) = split(/\./,$env{$item});
                   1880:                 next if (($start && $start > $now) || ($end && $end < $now));
                   1881:                 if ($sec eq '') {
1.239     raeburn  1882:                     if (!$gotnosection{$role}) {
                   1883:                         $seccount{$role} ++;
                   1884:                         $gotnosection{$role} = 1;
                   1885:                     }
1.235     raeburn  1886:                 }
1.350     raeburn  1887:                 if ($priv ne '') {
                   1888:                     my $cnumsec = $cnum;
                   1889:                     if ($sec ne '') {
                   1890:                         $cnumsec .= "/$sec";
                   1891:                     }
                   1892:                     $courseprivs{"$role./$cdom/$cnumsec./"} =
                   1893:                         $env{"user.priv.$role./$cdom/$cnumsec./"};
                   1894:                     $courseprivs{"$role./$cdom/$cnumsec./$cdom/"} =
                   1895:                         $env{"user.priv.$role./$cdom/$cnumsec./$cdom/"};
                   1896:                     $courseprivs{"$role./$cdom/$cnumsec./$cdom/$cnumsec"} =
                   1897:                         $env{"user.priv.$role./$cdom/$cnumsec./$cdom/$cnumsec"};
                   1898:                 }
1.235     raeburn  1899:                 if (ref($courseroles{$role}) eq 'ARRAY') {
1.239     raeburn  1900:                     if ($sec ne '') {
1.264     raeburn  1901:                         if (!grep(/^\Q$sec\E$/,@{$courseroles{$role}})) {
1.239     raeburn  1902:                             push(@{$courseroles{$role}},$sec);
                   1903:                             $seccount{$role} ++;
                   1904:                         }
                   1905:                     }
                   1906:                 } else {
                   1907:                     @{$courseroles{$role}} = ();
                   1908:                     if ($sec ne '') {
                   1909:                         $seccount{$role} ++;
1.235     raeburn  1910:                         push(@{$courseroles{$role}},$sec);
                   1911:                     }
                   1912:                 }
                   1913:             }
                   1914:         }
                   1915:     }
1.419     bisitz   1916:     $switchtext = 'Switch role'; # do not translate here
1.298     raeburn  1917:     my @roles_order = ($ccrole,'in','ta','ep','ad','st');
1.402     raeburn  1918:     my $numdiffsec;
                   1919:     if (keys(%seccount) == 1) {
                   1920:         foreach my $key (keys(%seccount)) {
                   1921:             $numdiffsec = $seccount{$key};
                   1922:         }
                   1923:     }
                   1924:     if ((keys(%seccount) > 1) || ($numdiffsec > 1)) {
1.401     raeburn  1925:         my @submenu;
                   1926:         $js = &jump_to_role($cdom,$cnum,\%seccount,\%courseroles,\%courseprivs,$priv);
                   1927:         $form = 
1.421     raeburn  1928:             '<form name="rolechooser" method="post" action="'.$httphost.'/adm/roles">'."\n".
1.401     raeburn  1929:             '  <input type="hidden" name="destinationurl" value="'.
                   1930:             &HTML::Entities::encode($destinationurl).'" />'."\n".
                   1931:             '  <input type="hidden" name="gotorole" value="1" />'."\n".
                   1932:             '  <input type="hidden" name="selectrole" value="" />'."\n".
1.402     raeburn  1933:             '  <input type="hidden" name="switchrole" value="" />'."\n";
                   1934:         if ($destsymb ne '') {
                   1935:             $form .= '  <input type="hidden" name="destsymb" value="'.
                   1936:                         &HTML::Entities::encode($destsymb).'" />'."\n";
                   1937:         }
                   1938:         $form .= '</form>'."\n";
1.235     raeburn  1939:         foreach my $role (@roles_order) {
1.402     raeburn  1940:             my $include;
1.235     raeburn  1941:             if (defined($courseroles{$role})) {
1.402     raeburn  1942:                 if ($env{'request.role'} =~ m{^\Q$role\E}) {
                   1943:                     if ($seccount{$role} > 1) {
                   1944:                         $include = 1;
                   1945:                     }
                   1946:                 } else {
                   1947:                     $include = 1;
                   1948:                 }
                   1949:             }
                   1950:             if ($include) {
1.401     raeburn  1951:                 push(@submenu,['javascript:adhocRole('."'$role'".')',
                   1952:                                &Apache::lonnet::plaintext($role,$crstype)]);
1.235     raeburn  1953:             }
                   1954:         }
                   1955:         foreach my $role (sort(keys(%courseroles))) {
                   1956:             if ($role =~ /^cr/) {
1.403     raeburn  1957:                 my $include;
                   1958:                 if ($env{'request.role'} =~ m{^\Q$role\E}) {
1.402     raeburn  1959:                     if ($seccount{$role} > 1) {
                   1960:                         $include = 1;
                   1961:                     }
1.403     raeburn  1962:                 } else {
                   1963:                     $include = 1; 
                   1964:                 }
                   1965:                 if ($include) {
                   1966:                     push(@submenu,['javascript:adhocRole('."'$role'".')',
                   1967:                                    &Apache::lonnet::plaintext($role)]);
                   1968:                 }
1.235     raeburn  1969:             }
                   1970:         }
1.401     raeburn  1971:         if (@submenu > 0) {
                   1972:             $switcher = &create_submenu('','',$switchtext,\@submenu);
1.386     raeburn  1973:         }
1.235     raeburn  1974:     }
1.401     raeburn  1975:     return ($js,$form,$switcher);
1.235     raeburn  1976: }
                   1977: 
1.262     raeburn  1978: sub get_all_courseroles {
1.350     raeburn  1979:     my ($cdom,$cnum,$courseroles,$seccount,$courseprivs) = @_;
1.351     raeburn  1980:     unless ((ref($courseroles) eq 'HASH') && (ref($seccount) eq 'HASH') &&
1.350     raeburn  1981:             (ref($courseprivs) eq 'HASH')) {
1.262     raeburn  1982:         return;
                   1983:     }
                   1984:     my ($result,$cached) = 
                   1985:         &Apache::lonnet::is_cached_new('getcourseroles',$cdom.'_'.$cnum);
                   1986:     if (defined($cached)) {
                   1987:         if (ref($result) eq 'HASH') {
                   1988:             if ((ref($result->{'roles'}) eq 'HASH') && 
1.350     raeburn  1989:                 (ref($result->{'seccount'}) eq 'HASH') && 
                   1990:                 (ref($result->{'privs'}) eq 'HASH')) {
1.262     raeburn  1991:                 %{$courseroles} = %{$result->{'roles'}};
                   1992:                 %{$seccount} = %{$result->{'seccount'}};
1.350     raeburn  1993:                 %{$courseprivs} = %{$result->{'privs'}};
1.262     raeburn  1994:                 return;
                   1995:             }
                   1996:         }
                   1997:     }
                   1998:     my %gotnosection;
                   1999:     my %adv_roles =
                   2000:          &Apache::lonnet::get_course_adv_roles($env{'request.course.id'},1);
                   2001:     foreach my $role (keys(%adv_roles)) {
                   2002:         my ($urole,$usec) = split(/:/,$role);
                   2003:         if (!$gotnosection{$urole}) {
                   2004:             $seccount->{$urole} ++;
                   2005:             $gotnosection{$urole} = 1;
                   2006:         }
                   2007:         if (ref($courseroles->{$urole}) eq 'ARRAY') {
                   2008:             if ($usec ne '') {
                   2009:                 if (!grep(/^Q$usec\E$/,@{$courseroles->{$urole}})) {
                   2010:                     push(@{$courseroles->{$urole}},$usec);
                   2011:                     $seccount->{$urole} ++;
                   2012:                 }
                   2013:             }
                   2014:         } else {
                   2015:             @{$courseroles->{$urole}} = ();
                   2016:             if ($usec ne '') {
                   2017:                 $seccount->{$urole} ++;
                   2018:                 push(@{$courseroles->{$urole}},$usec);
                   2019:             }
                   2020:         }
1.350     raeburn  2021:         my $area = '/'.$cdom.'/'.$cnum;
                   2022:         if ($usec ne '') {
                   2023:             $area .= '/'.$usec;
                   2024:         }
                   2025:         if ($role =~ /^cr\//) {
                   2026:             &Apache::lonnet::custom_roleprivs($courseprivs,$urole,$cdom,$cnum,$urole.'.'.$area,$area);
                   2027:         } else {
                   2028:             &Apache::lonnet::standard_roleprivs($courseprivs,$urole,$cdom,$urole.'.'.$area,$cnum,$area);
                   2029:         }
1.262     raeburn  2030:     }
                   2031:     my %sections_count = &Apache::loncommon::get_sections($cdom,$cnum,['st']);
                   2032:     @{$courseroles->{'st'}} = ();
1.350     raeburn  2033:     &Apache::lonnet::standard_roleprivs($courseprivs,'st',$cdom,"st./$cdom/$cnum",$cnum,"/$cdom/$cnum");
1.262     raeburn  2034:     if (keys(%sections_count) > 0) {
                   2035:         push(@{$courseroles->{'st'}},keys(%sections_count));
1.350     raeburn  2036:         $seccount->{'st'} = scalar(keys(%sections_count));
1.262     raeburn  2037:     }
1.410     raeburn  2038:     $seccount->{'st'} ++; # Increment for a section-less student role.  
1.262     raeburn  2039:     my $rolehash = {
                   2040:                      'roles'    => $courseroles,
                   2041:                      'seccount' => $seccount,
1.350     raeburn  2042:                      'privs'    => $courseprivs,
1.262     raeburn  2043:                    };
                   2044:     &Apache::lonnet::do_cache_new('getcourseroles',$cdom.'_'.$cnum,$rolehash);
                   2045:     return;
                   2046: }
                   2047: 
1.235     raeburn  2048: sub jump_to_role {
1.350     raeburn  2049:     my ($cdom,$cnum,$seccount,$courseroles,$courseprivs,$priv) = @_;
1.239     raeburn  2050:     my %lt = &Apache::lonlocal::texthash(
                   2051:                 this => 'This role has section(s) associated with it.',
                   2052:                 ente => 'Enter a specific section.',
                   2053:                 orlb => 'Enter a specific section, or leave blank for no section.',
                   2054:                 avai => 'Available sections are:',
                   2055:                 youe => 'You entered an invalid section choice:',
1.352     raeburn  2056:                 plst => 'Please try again.',
1.350     raeburn  2057:                 role => 'The role you selected is not permitted to view the current page.',
                   2058:                 swit => 'Switch role, but display Main Menu page instead?',
1.239     raeburn  2059:     );
                   2060:     my $js;
                   2061:     if (ref($courseroles) eq 'HASH') {
                   2062:         $js = '    var secpick = new Array("'.$lt{'ente'}.'","'.$lt{'orlb'}.'");'."\n". 
                   2063:               '    var numsec = new Array();'."\n".
                   2064:               '    var rolesections = new Array();'."\n".
                   2065:               '    var rolenames = new Array();'."\n".
                   2066:               '    var roleseclist = new Array();'."\n";
                   2067:         my @items = keys(%{$courseroles});
                   2068:         for (my $i=0; $i<@items; $i++) {
                   2069:             $js .= '    rolenames['.$i.'] = "'.$items[$i].'";'."\n";
                   2070:             my ($secs,$secstr);
                   2071:             if (ref($courseroles->{$items[$i]}) eq 'ARRAY') {
                   2072:                 my @sections = sort { $a <=> $b } @{$courseroles->{$items[$i]}};
                   2073:                 $secs = join('","',@sections);
                   2074:                 $secstr = join(', ',@sections);
                   2075:             }
                   2076:             $js .= '    rolesections['.$i.'] = new Array("'.$secs.'");'."\n".
                   2077:                    '    roleseclist['.$i.'] = "'.$secstr.'";'."\n".
                   2078:                    '    numsec['.$i.'] = "'.$seccount->{$items[$i]}.'";'."\n";
                   2079:         }
                   2080:     }
1.350     raeburn  2081:     my $checkroles = 0;
                   2082:     if ($priv && ref($courseprivs) eq 'HASH') {
                   2083:         my (%disallowed,%allowed,@disallow);
                   2084:         foreach my $role (sort(keys(%{$courseprivs}))) {
                   2085:             my $trole;
                   2086:             if ($role =~ m{^(.+?)\Q./$cdom/$cnum\E}) {
                   2087:                 $trole = $1;
                   2088:             }
                   2089:             if (($trole ne '') && ($trole ne 'cm')) {
                   2090:                 if ($courseprivs->{$role} =~ /\Q:$priv\E($|:|\&\w+)/) {
                   2091:                     $allowed{$trole} = 1;
                   2092:                 } else {
                   2093:                     $disallowed{$trole} = 1;
                   2094:                 }
                   2095:             }
                   2096:         }
                   2097:         foreach my $trole (keys(%disallowed)) {
                   2098:             unless ($allowed{$trole}) {
                   2099:                 push(@disallow,$trole);
                   2100:             }
                   2101:         }
                   2102:         if (@disallow > 0) {
                   2103:             $checkroles = 1;
                   2104:             $js .= "    var disallow = new Array('".join("','",@disallow)."');\n".
                   2105:                    "    var rolecheck = 1;\n";
                   2106:         }
                   2107:     }
                   2108:     if (!$checkroles) {
                   2109:         $js .=  "    var disallow = new Array();\n".
                   2110:                 "    rolecheck = 0;\n";
                   2111:     }
1.273     droeschl 2112:     return <<"END";
1.235     raeburn  2113: <script type="text/javascript">
1.273     droeschl 2114: //<![CDATA[
1.401     raeburn  2115: function adhocRole(newrole) {
1.239     raeburn  2116:     $js
1.235     raeburn  2117:     if (newrole == '') {
1.350     raeburn  2118:         return;
1.235     raeburn  2119:     } 
1.239     raeburn  2120:     var fullrole = newrole+'./$cdom/$cnum';
                   2121:     var selidx = '';
                   2122:     for (var i=0; i<rolenames.length; i++) {
                   2123:         if (rolenames[i] == newrole) {
                   2124:             selidx = i;
                   2125:         }
                   2126:     }
1.350     raeburn  2127:     if (rolecheck > 0) {
                   2128:         for (var i=0; i<disallow.length; i++) {
                   2129:             if (disallow[i] == newrole) {
                   2130:                 if (confirm("$lt{'role'}\\n$lt{'swit'}")) {
                   2131:                     document.rolechooser.destinationurl.value = '/adm/menu';
                   2132:                 } else {
                   2133:                     return;
                   2134:                 }
                   2135:             }
                   2136:         }
                   2137:     }
1.239     raeburn  2138:     var secok = 1;
                   2139:     var secchoice = '';
                   2140:     if (selidx >= 0) {
                   2141:         if (numsec[selidx] > 1) {
                   2142:             secok = 0;
                   2143:             var numrolesec = rolesections[selidx].length;
                   2144:             var msgidx = numsec[selidx] - numrolesec;
1.339     raeburn  2145:             secchoice = prompt("$lt{'this'} "+secpick[msgidx]+"\\n$lt{'avai'} "+roleseclist[selidx],"");
1.239     raeburn  2146:             if (secchoice == '') {
                   2147:                 if (msgidx > 0) {
                   2148:                     secok = 1;
                   2149:                 }
                   2150:             } else {
                   2151:                 for (var j=0; j<rolesections[selidx].length; j++) {
                   2152:                     if (rolesections[selidx][j] == secchoice) {
                   2153:                         secok = 1;
                   2154:                     }
                   2155:                 }
                   2156:             }
                   2157:         } else {
                   2158:             if (rolesections[selidx].length == 1) {
                   2159:                 secchoice = rolesections[selidx][0];
                   2160:             }
                   2161:         }
                   2162:     }
                   2163:     if (secok == 1) {
                   2164:         if (secchoice != '') {
                   2165:             fullrole += '/'+secchoice;
                   2166:         }
                   2167:     } else {
                   2168:         if (secchoice != null) {
                   2169:             alert("$lt{'youe'} \\""+secchoice+"\\".\\n $lt{'plst'}");
                   2170:         }
                   2171:         return;
                   2172:     }
                   2173:     if (fullrole == "$env{'request.role'}") {
1.235     raeburn  2174:         return;
                   2175:     }
                   2176:     itemid = retrieveIndex('gotorole');
                   2177:     if (itemid != -1) {
1.239     raeburn  2178:         document.rolechooser.elements[itemid].name = fullrole;
1.235     raeburn  2179:     }
1.401     raeburn  2180:     document.rolechooser.switchrole.value = fullrole;
1.235     raeburn  2181:     document.rolechooser.selectrole.value = '1';
                   2182:     document.rolechooser.submit();
                   2183:     return;
                   2184: }
                   2185: 
                   2186: function retrieveIndex(item) {
                   2187:     for (var i=0;i<document.rolechooser.elements.length;i++) {
                   2188:         if (document.rolechooser.elements[i].name == item) {
                   2189:             return i;
                   2190:         }
                   2191:     }
                   2192:     return -1;
                   2193: }
1.273     droeschl 2194: // ]]>
1.235     raeburn  2195: </script>
                   2196: END
                   2197: }
                   2198: 
1.350     raeburn  2199: sub required_privs {
                   2200:     my $privs =  {
                   2201:              '/adm/parmset'      => 'opa',
                   2202:              '/adm/courseprefs'  => 'opa',
                   2203:              '/adm/whatsnew'     => 'whn',
                   2204:              '/adm/populate'     => 'cst',
                   2205:              '/adm/trackstudent' => 'vsa',
                   2206:              '/adm/statistics'   => 'vgr',
1.366     raeburn  2207:              '/adm/setblock'     => 'dcm',
1.367     raeburn  2208:              '/adm/coursedocs'   => 'mdc',
1.350     raeburn  2209:            };
                   2210:     unless ($env{'course.'.$env{'request.course.id'}.'.grading'} eq 'spreadsheet') {
1.364     raeburn  2211:         $privs->{'/adm/classcalc'}   = 'vgr',
                   2212:         $privs->{'/adm/assesscalc'}  = 'vgr',
                   2213:         $privs->{'/adm/studentcalc'} = 'vgr';
1.350     raeburn  2214:     }
                   2215:     return $privs;
                   2216: }
1.235     raeburn  2217: 
1.378     raeburn  2218: sub countdown_timer {
                   2219:     if (($env{'request.course.id'}) && ($env{'request.symb'} ne '') &&
1.387     raeburn  2220:         ($env{'request.filename'}=~/$LONCAPA::assess_re/)) {
                   2221:         my ($type,$hastimeleft,$slothastime);
                   2222:         my $now = time;
                   2223:         if ($env{'request.filename'} =~ /\.task$/) {
                   2224:             $type = 'Task';
                   2225:         } else {
                   2226:             $type = 'problem';
                   2227:         }
                   2228:         my ($status,$accessmsg,$slot_name,$slot) =
                   2229:             &Apache::lonhomework::check_slot_access('0',$type);
                   2230:         if ($slot_name ne '') {
                   2231:             if (ref($slot) eq 'HASH') {
                   2232:                 if (($slot->{'starttime'} < $now) &&
                   2233:                     ($slot->{'endtime'} > $now)) {
                   2234:                     $slothastime = 1;
                   2235:                 }
                   2236:             }
                   2237:         }
                   2238:         if ($status ne 'CAN_ANSWER') {
                   2239:             return;
                   2240:         }
1.378     raeburn  2241:         my $duedate = &Apache::lonnet::EXT("resource.0.duedate");
1.380     raeburn  2242:         my @interval=&Apache::lonnet::EXT("resource.0.interval");
1.381     raeburn  2243:         if (@interval > 1) {
                   2244:             my $first_access=&Apache::lonnet::get_first_access($interval[1]);
                   2245:             if ($first_access > 0) {
                   2246:                 if ($first_access+$interval[0] > time) {
                   2247:                     $hastimeleft = 1;
                   2248:                 }
                   2249:             }
                   2250:         }
1.380     raeburn  2251:         if (($duedate && $duedate > time) ||
1.387     raeburn  2252:             (!$duedate && $hastimeleft) ||
                   2253:             ($slot_name ne '' && $slothastime)) {
1.431.2.2! musolffc 2254:             my ($collapse,$expand,$alttxt,$title,$currdisp,$donebutton);
1.387     raeburn  2255:             if ((@interval > 1 && $hastimeleft) ||
                   2256:                 ($type eq 'Task' && $slothastime)) {
1.378     raeburn  2257:                 $currdisp = 'inline';
                   2258:                 $collapse = '&#9658;&nbsp;';
1.431.2.2! musolffc 2259:                 $donebutton = &done_button_js();
        !          2260: 
        !          2261: 
1.378     raeburn  2262:             } else {
                   2263:                 $currdisp = 'none';
                   2264:                 $expand = '&#9668;&nbsp;';
                   2265:             }
                   2266:             unless ($env{'environment.icons'} eq 'iconsonly') {
1.379     raeburn  2267:                 $alttxt = &mt('Timer');
                   2268:                 $title = $alttxt.'&nbsp;';
1.378     raeburn  2269:             }
                   2270:             my $desc = &mt('Countdown to due date/time');
1.431.2.2! musolffc 2271: 
1.378     raeburn  2272:             return <<END;
                   2273: 
                   2274: <a href="javascript:toggleCountdown();" class="LC_menubuttons_link">
                   2275: <span id="ddcountcollapse" class="LC_menubuttons_inline_text">
                   2276: $collapse
1.379     raeburn  2277: </span></a>
1.378     raeburn  2278: <span id="duedatecountdown" class="LC_menubuttons_inline_text" style="display: $currdisp;"></span>
                   2279: <a href="javascript:toggleCountdown();" class="LC_menubuttons_link">
                   2280: <span id="ddcountexpand" class="LC_menubuttons_inline_text" >$expand</span>
1.379     raeburn  2281: <img src="/res/adm/pages/timer.png" title="$desc" class="LC_icon" alt="$alttxt" /><span class="LC_menubuttons_inline_text">$title</span></a>
1.431.2.2! musolffc 2282: $donebutton
1.378     raeburn  2283: END
                   2284:         }
                   2285:     }
                   2286:     return;
                   2287: }
                   2288: 
1.2       www      2289: # ================================================================ Main Program
                   2290: 
1.16      harris41 2291: BEGIN {
1.166     albertel 2292:     if (! defined($readdesk)) {
1.283     droeschl 2293:         {
                   2294:             my $tabfile = $Apache::lonnet::perlvar{'lonTabDir'}.'/mydesk.tab';
                   2295:             if ( CORE::open( my $config,"<$tabfile") ) {
                   2296:                 while (my $configline=<$config>) {
                   2297:                     $configline=(split(/\#/,$configline))[0];
                   2298:                     $configline=~s/^\s+//;
                   2299:                     chomp($configline);
1.209     www      2300:                     if ($configline=~/^cat\:/) {
1.283     droeschl 2301:                         my @entries=split(/\:/,$configline);
                   2302:                         $category_positions{$entries[2]}=$entries[1];
                   2303:                         $category_names{$entries[2]}=$entries[3];
                   2304:                     } elsif ($configline=~/^prim\:/) {
1.415     raeburn  2305:                         my @entries = (split(/\:/, $configline))[1..6];
1.400     raeburn  2306:                         push(@primary_menu,\@entries);
1.371     raeburn  2307:                     } elsif ($configline=~/^primsub\:/) {
                   2308:                         my ($parent,@entries) = (split(/\:/, $configline))[1..4];
1.400     raeburn  2309:                         push(@{$primary_submenu{$parent}},\@entries);
1.283     droeschl 2310:                     } elsif ($configline=~/^scnd\:/) {
                   2311:                         my @entries = (split(/\:/, $configline))[1..5];
1.401     raeburn  2312:                         push(@secondary_menu,\@entries);
1.283     droeschl 2313:                     } elsif ($configline) {
                   2314:                         push(@desklines,$configline);
                   2315:                     }
                   2316:                 }
                   2317:                 CORE::close($config);
                   2318:             }
                   2319:         }
                   2320:         $readdesk='done';
1.2       www      2321:     }
                   2322: }
1.30      www      2323: 
1.1       www      2324: 1;
                   2325: __END__
                   2326: 

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