# The LearningOnline Network with CAPA
# Routines to control the menu
#
# $Id: lonmenu.pm,v 1.314 2010/02/24 17:38:52 droeschl Exp $
#
# Copyright Michigan State University Board of Trustees
#
# This file is part of the LearningOnline Network with CAPA (LON-CAPA).
#
# LON-CAPA is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# LON-CAPA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with LON-CAPA; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# /home/httpd/html/adm/gpl.txt
#
# http://www.lon-capa.org/
#
#
# There is one parameter controlling the action of this module:
#
# environment.remote - if this is 'on', the routines controll the remote
# control, otherwise they render the main window controls;
=head1 NAME
Apache::lonmenu
=head1 SYNOPSIS
Coordinates the response to clicking an image.
This is part of the LearningOnline Network with CAPA project
described at http://www.lon-capa.org.
=head1 GLOBAL VARIABLES
=over
=item @desklines
Each element of this array contains a line of mydesk.tab that doesn't start with
cat, prim or scnd.
It gets filled in the BEGIN block of this module.
=item %category_names
The keys of this hash are the abbreviations used in mydesk.tab in those lines that
start with cat, the values are strings representing titles.
It gets filled in the BEGIN block of this module.
=item %category_members
TODO
=item %category_positions
The keys of this hash are the abbreviations used in mydesk.tab in those lines that
start with cat, its values are position vectors (column, row).
It gets filled in the BEGIN block of this module.
=item $readdesk
Indicates that mydesk.tab has been read.
It is set to 'done' in the BEGIN block of this module.
=item @primary_menu
The elements of this array reference arrays that are made up of the components
of those lines of mydesk.tab that start with prim.
It is used by primary_menu() to generate the corresponding menu.
It gets filled in the BEGIN block of this module.
=item @secondary_menu
The elements of this array reference arrays that are made up of the components
of those lines of mydesk.tab that start with scnd.
It is used by secondary_menu() to generate the corresponding menu.
It gets filled in the BEGIN block of this module.
=back
=head1 SUBROUTINES
=over
=item prep_menuitems(\@menuitem)
This routine wraps a menuitem in proper HTML. It is used by primary_menu() and
secondary_menu().
=item primary_menu()
This routine evaluates @primary_menu and returns XHTML for the menu
that contains following links: About, Message, Roles, Help, Logout
@primary_menu is filled within the BEGIN block of this module with
entries from mydesk.tab
=item secondary_menu()
Same as primary_menu() but operates on @secondary_menu.
=item DEPRECATED: initlittle()
This routine returns a translated hash for the menu items in the top inline
menu row
=item menubuttons()
This gets called at the top of the body section
=item show_return_link()
=item registerurl()
This gets called in the header section
=item innerregister()
This gets called in order to register a URL, both with the Remote
and in the body of the document
=item loadevents()
=item unloadevents()
=item startupremote()
=item setflags()
=item maincall()
=item load_remote_msg()
=item get_menu_name()
=item reopenmenu()
=item open()
Open the menu
=item clear()
=item switch()
Switch a button or create a link
Switch acts on the javascript that is executed when a button is clicked.
The javascript is usually similar to "go('/adm/roles')" or "cstrgo(..)".
=item secondlevel()
=item openmenu()
=item inlinemenu()
=item rawconfig()
=item close()
=item footer()
=item utilityfunctions()
=item serverform()
=item constspaceform()
=item get_nav_status()
=item hidden_button_check()
=item roles_selector()
=item jump_to_role()
=back
=cut
package Apache::lonmenu;
use strict;
use Apache::lonnet;
use Apache::lonhtmlcommon();
use Apache::loncommon();
use Apache::lonenc();
use Apache::lonlocal;
use LONCAPA qw(:DEFAULT :match);
use HTML::Entities();
use vars qw(@desklines %category_names %category_members %category_positions
$readdesk @primary_menu @secondary_menu);
my @inlineremote;
sub prep_menuitem {
my ($menuitem) = @_;
return '' unless(ref($menuitem) eq 'ARRAY');
my $link;
if ($$menuitem[1]) { # graphical Link
$link = "";
} else { # textual Link
$link = &mt($$menuitem[3]);
}
if($$menuitem[4] eq 'newmsg'){ #special style for New Messages
return '
'.$link.'';
}
return ''.$link.'';
}
# primary_menu() evaluates @primary_menu and returns XHTML for the menu
# that contains following links:
# About, Message, Roles, Help, Logout
# @primary_menu is filled within the BEGIN block of this module with
# entries from mydesk.tab
sub primary_menu {
my $menu;
# each element of @primary contains following array:
# (link url, icon path, alt text, link text, condition)
foreach my $menuitem (@primary_menu) {
# evaluate conditions
next if ref($menuitem) ne 'ARRAY'; #
next if $$menuitem[4] eq 'nonewmsg' # show links depending on
&& &Apache::lonmsg::mynewmail(); # whether a new msg
next if $$menuitem[4] eq 'newmsg' # arrived or not
&& !&Apache::lonmsg::mynewmail(); #
next if $$menuitem[4] !~ /public/ ##we've a public user,
&& $env{'user.name'} eq 'public' ##who should not see all
&& $env{'user.domain'} eq 'public'; ##links
next if $$menuitem[4] eq 'onlypublic'# hide links which are
&& $env{'user.name'} ne 'public' # only visible to public
&& $env{'user.domain'} ne 'public'; # users
next if $$menuitem[4] eq 'roles' ##show links depending on
&& &Apache::loncommon::show_course(); ##term 'Courses' or
next if $$menuitem[4] eq 'courses' ##'Roles' wanted
&& !&Apache::loncommon::show_course(); ##
if ($$menuitem[3] eq 'Help') { # special treatment for helplink
$menu .= ''.&Apache::loncommon::top_nav_help('Help').'';
} else {
my @items = @{$menuitem};
$items[0] = 'javascript:'.$menuitem->[0].';';
$menu .= &prep_menuitem(\@items);
}
}
return "";
}
sub secondary_menu {
my $menu;
my $crstype = &Apache::loncommon::course_type();
my $canedit = &Apache::lonnet::allowed('mdc', $env{'request.course.id'});
my $canviewgrps = &Apache::lonnet::allowed('vcg', $env{'request.course.id'}
. ($env{'request.course.sec'} ? "/$env{'request.course.sec'}"
: ''));
my $showlink = &show_return_link();
my %groups = &Apache::lonnet::get_active_groups(
$env{'user.domain'}, $env{'user.name'},
$env{'course.' . $env{'request.course.id'} . '.domain'},
$env{'course.' . $env{'request.course.id'} . '.num'});
foreach my $menuitem (@secondary_menu) {
# evaluate conditions
next if ref($menuitem) ne 'ARRAY';
next if $$menuitem[4] ne 'always'
&& !$env{'request.course.id'};
next if $$menuitem[4] eq 'showreturn'
&& !$showlink
&& !($env{'request.state'} eq 'construct');
next if $$menuitem[4] =~ /^mdc/
&& !$canedit;
next if $$menuitem[4] eq 'mdcCourse'
&& $crstype eq 'Community';
next if $$menuitem[4] eq 'mdcCommunity'
&& $crstype ne 'Community';
next if $$menuitem[4] =~ /^remotenav/
&& $env{'environment.remotenavmap'} ne 'on';
next if $$menuitem[4] =~ /noremotenav/
&& $env{'environment.remotenavmap'} eq 'on';
next if $$menuitem[4] =~ /^(no|)remotenav$/
&& $crstype eq 'Community';
next if $$menuitem[4] =~ /^(no|)remotenavCommunity$/
&& $crstype ne 'Community';
next if $$menuitem[4] =~ /showgroups$/
&& !$canviewgrps
&& !%groups;
if ($$menuitem[3] eq 'Roles' && $env{'request.course.id'}) {
# special treatment for role selector
my $roles_selector = &roles_selector(
$env{'course.' . $env{'request.course.id'} . '.domain'},
$env{'course.' . $env{'request.course.id'} . '.num'} );
$menu .= $roles_selector ? "$roles_selector"
: '';
} elsif ($env{'environment.remotenavmap'} eq 'on') {
# open link using javascript when remote navmap is activated
my @items = @{$menuitem};
if ($menuitem->[4] eq 'remotenav') {
$items[0] = "javascript:gonav('$menuitem->[0]');";
} else {
$items[0] = "javascript:go('$menuitem->[0]');";
}
$menu .= &prep_menuitem(\@items);
} else {
$menu .= &prep_menuitem(\@$menuitem);
}
}
if ($menu =~ /\[url\].*\[symb\]/) {
my $escurl = &escape( &Apache::lonenc::check_encrypt(
$env{'request.noversionuri'}));
my $escsymb = &escape( &Apache::lonenc::check_encrypt(
$env{'request.symb'}));
if ( $env{'request.state'} eq 'construct'
and ( $env{'request.noversionuri'} eq ''
|| !defined($env{'request.noversionuri'})))
{
($escurl = $env{'request.filename'}) =~
s{^/home/([^/]+)/public_html/(.*)$}{/priv/$1/$2};
$escurl = &escape($escurl);
}
$menu =~ s/\[url\]/$escurl/g;
$menu =~ s/\[symb\]/$escsymb/g;
}
return "";
}
#
# This routine returns a translated hash for the menu items in the top inline menu row
# Probably should be in mydesk.tab
#SD this sub is deprecated - don't use it
sub initlittle {
return &Apache::lonlocal::texthash('ret' => 'Return to Last Location',
'nav' => 'Course Contents',
'main' => 'Main Menu',
'roles' => (&Apache::loncommon::show_course()?
'Courses':'Roles'),
'other' => 'Other Roles',
'docs' => 'Course Editor',
'exit' => 'Logout',
'login' => 'Log In',
'launch' => 'Launch Remote Control',
'groups' => 'Groups',
'gdoc' => 'Community Documents',
);
}
#SD this sub is deprecated - don't use it
#SD functionality is covered by new loncommon::bodytag and primary_menu(), secondary_menu()
sub menubuttons {
my $forcereg=shift;
my $titletable=shift;
#
# Early-out for pages that should not have a menu, triggered by query string "inhibitmenu=yes"
#
&Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
['inhibitmenu']);
if (($env{'form.inhibitmenu'} eq 'yes') ||
($ENV{'REQUEST_URI'} eq '/adm/logout')) { return ''; }
if ($env{'request.noversionuri'} =~ m{^/res/adm/pages/}) { return ''; }
my %lt=&initlittle();
my $navmaps='';
my $reloadlink='';
my $docs='';
my $groups='';
my $roles=''.$lt{'roles'}.'';
my $role_selector;
my $showgroups=0;
my ($cnum,$cdom);
#
# if the URL is hidden, symbs and the non-versioned version of the URL would be encrypted
#
my $escurl=&escape(&Apache::lonenc::check_encrypt($env{'request.noversionuri'}));
my $escsymb=&escape(&Apache::lonenc::check_encrypt($env{'request.symb'}));
my $logo=&Apache::loncommon::lonhttpdurl("/adm/lonIcons/minilogo.gif");
$logo = '';
if ($env{'request.state'} eq 'construct') {
#
# We are in construction space
#
if (($env{'request.noversionuri'} eq '') || (!defined($env{'request.noversionuri'}))) {
my $returnurl = $env{'request.filename'};
$returnurl =~ s:^/home/([^/]+)/public_html/(.*)$:/priv/$1/$2:;
$escurl = &escape($returnurl);
}
}
if ($env{'request.course.id'}) {
#
# We are in a course
#
$cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
$cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
my %coursegroups;
my $viewgrps_permission =
&Apache::lonnet::allowed('vcg',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''));
if (!$viewgrps_permission) {
%coursegroups = &Apache::lonnet::get_active_groups($env{'user.domain'},$env{'user.name'},$cdom,$cnum);
}
if ((keys(%coursegroups) > 0) || ($viewgrps_permission)) {
$showgroups = 1;
}
$role_selector = &roles_selector($cdom,$cnum);
if ($role_selector) {
$roles = ''.$role_selector.' '.$lt{'other'}.'';
}
}
if ($env{'environment.remote'} eq 'off') {
# Remote Control is switched off
# figure out colors
my %lt=&initlittle();
my $domain=&Apache::loncommon::determinedomain();
my $function=&Apache::loncommon::get_users_function();
my $link=&Apache::loncommon::designparm($function.'.link',$domain);
my $alink=&Apache::loncommon::designparm($function.'.alink',$domain);
my $vlink=&Apache::loncommon::designparm($function.'.vlink',$domain);
my $sidebg=&Apache::loncommon::designparm($function.'.sidebg',$domain);
if ($env{'user.name'} eq 'public' && $env{'user.domain'} eq 'public') {
return (<