--- loncom/interface/lonmenu.pm 2012/05/23 00:29:22 1.369.2.5
+++ loncom/interface/lonmenu.pm 2012/08/03 22:38:35 1.369.2.18
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Routines to control the menu
#
-# $Id: lonmenu.pm,v 1.369.2.5 2012/05/23 00:29:22 raeburn Exp $
+# $Id: lonmenu.pm,v 1.369.2.18 2012/08/03 22:38:35 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -115,10 +115,42 @@ entries from mydesk.tab
Same as primary_menu() but operates on @secondary_menu.
+=item create_submenu()
+
+Creates XHTML for unordered list of sub-menu items which belong to a
+particular top-level menu item. Uses hover pseudo class in css to display
+dropdown list when mouse hovers over top-level item. Support for IE6
+(no hover psuedo class) via LC_hoverable class for
tag for top-
+level item, which employs jQuery to handle behavior on mouseover.
+
+Inputs: 4 - (a) link and (b) target for anchor href in top level item,
+ (c) title for text wrapped by anchor tag in top level item.
+ (d) reference to array of arrays of sub-menu items.
+
=item innerregister()
This gets called in order to register a URL 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()
@@ -137,6 +169,9 @@ The javascript is usually similar to "go
=item utilityfunctions()
+Output from this routine is a number of javascript functions called by
+items in the inline menu, and in some cases items in the Main Menu page.
+
=item serverform()
=item constspaceform()
@@ -164,6 +199,7 @@ use Apache::lonlocal;
use Apache::lonmsg();
use LONCAPA qw(:DEFAULT :match);
use HTML::Entities();
+use Apache::lonwishlist();
use vars qw(@desklines %category_names %category_members %category_positions
$readdesk @primary_menu %primary_submenu @secondary_menu %secondary_submenu);
@@ -221,51 +257,30 @@ sub primary_menu {
my $title = $menuitem->[3];
if (defined($primary_submenu{$title})) {
- my ($link,$target,$numsub);
+ my ($link,$target);
if ($menuitem->[0] ne '') {
$link = $menuitem->[0];
$target = '_top';
} else {
$link = '#';
}
+ my @primsub;
if (ref($primary_submenu{$title}) eq 'ARRAY') {
- $numsub = @{$primary_submenu{$title}};
- if ($numsub) {
- $title =
- ''.$title.
- ''.
- ' ▼';
- }
- }
- $menu .= ''.
- ''.$title.'';
- if ($numsub) {
- $menu .= '';
- foreach my $item (@{$primary_submenu{$menuitem->[3]}}) {
- if (ref($item) eq 'ARRAY') {
- if ($item->[2] eq 'wishlist') {
- next unless ((&Apache::lonnet::allowed('bre',"/res/$env{'user.domain'}/")) ||
- (&Apache::lonnet::allowed('bro',"/res/$env{'user.domain'}/")));
- } elsif ($item->[2] eq 'reqcrs') {
- next unless(&check_for_rcrs());
- } elsif (($item->[2] eq 'portfolio') ||
- ($item->[2] eq 'blog')) {
- if (!&Apache::lonnet::usertools_access(
- $env{'user.name'},
- $env{'user.domain'},
- $item->[2],undef,'tools')) {
- next;
- }
- }
- $menu .= '- '.
- ''.
- $item->[1].'
';
- }
+ foreach my $item (@{$primary_submenu{$title}}) {
+ next if (($item->[2] eq 'wishlist') && (!$env{'user.adv'}));
+ next if (($item->[2] eq 'reqcrs') && (!&check_for_rcrs()));
+ next if ((($item->[2] eq 'portfolio') ||
+ ($item->[2] eq 'blog')) &&
+ (!&Apache::lonnet::usertools_access('','',$item->[2],
+ undef,'tools')));
+ push(@primsub,$item);
+ }
+ if (@primsub > 0) {
+ $menu .= &create_submenu($link,$target,$title,\@primsub);
+ } elsif ($link) {
+ $menu .= '- '.&mt($title).'
';
}
- $menu .= '
';
}
- $menu .= '';
} elsif ($$menuitem[3] eq 'Help') { # special treatment for helplink
if ($public) {
my $origmail = $Apache::lonnet::perlvar{'lonSupportEMail'};
@@ -371,17 +386,15 @@ sub secondary_menu {
my $title = $menuitem->[3];
if (defined($secondary_submenu{$title})) {
- my ($link,$target,$numsub);
+ my ($link,$target);
if ($menuitem->[0] ne '') {
$link = $menuitem->[0];
$target = '_top';
} else {
$link = '#';
}
-
my @scndsub;
if (ref($secondary_submenu{$title}) eq 'ARRAY') {
- $numsub = 0;
foreach my $item (@{$secondary_submenu{$title}}) {
if (ref($item) eq 'ARRAY') {
next if ($item->[2] eq 'vgr' && !$canvgr);
@@ -390,43 +403,14 @@ sub secondary_menu {
next if ($item->[2] eq 'mgr' && !$canmgr);
next if ($item->[2] eq 'vcg' && !$canviewgrps);
push(@scndsub,$item);
- $numsub ++;
}
}
- if ($numsub) {
- $title =
- ''.$title.
- ''.
- ' ▼';
+ if (@scndsub > 0) {
+ $menu .= &create_submenu($link,$target,$title,\@scndsub);
+ } elsif ($link) {
+ $menu .= ''.&mt($title).'';
}
}
- $menu .= ''.
- ''.$title.'';
- if ($numsub) {
- $menu .= '';
- my $count = 0;
- foreach my $item (@scndsub) {
- $count ++;
- if (ref($item) eq 'ARRAY') {
- my $borderbot;
- my ($padtop,$padbot) = (0,0);
- if ($count == 1) {
- $padtop = '5px';
- }
- if ($count == $numsub) {
- $padbot = '5px';
- $borderbot = 'border-bottom:1px solid black;';
- }
- $menu .= '- '.
- $item->[1].'
';
- }
- }
- $menu .= '
';
- }
- $menu .= '';
} elsif ($$menuitem[3] eq 'Roles' && $env{'request.course.id'}) {
# special treatment for role selector
my $roles_selector = &roles_selector(
@@ -463,6 +447,65 @@ sub secondary_menu {
return "";
}
+sub create_submenu {
+ my ($link,$target,$title,$submenu) = @_;
+ return unless (ref($submenu) eq 'ARRAY');
+ my $disptarget;
+ if ($target ne '') {
+ $disptarget = ' target="'.$target.'"';
+ }
+ my $menu = ''.
+ ''.
+ ''.&mt($title).
+ ''.
+ ' ▼'.
+ '';
+ my $count = 0;
+ my $numsub = scalar(@{$submenu});
+ foreach my $item (@{$submenu}) {
+ $count ++;
+ if (ref($item) eq 'ARRAY') {
+ my $borderbot;
+ if ($count == $numsub) {
+ $borderbot = 'border-bottom:1px solid black;';
+ }
+ $menu .= '- '.
+ &mt($item->[1]).'
';
+ }
+ }
+ $menu .= '
';
+ return $menu;
+}
+
+sub registerurl {
+ my ($forcereg) = @_;
+ my $result = '';
+ if ($env{'request.noversionuri'} =~ m{^/res/adm/pages/}) { return ''; }
+ my $force_title='';
+ if ($env{'request.state'} eq 'construct') {
+ $force_title=&Apache::lonxml::display_title();
+ }
+ if (($env{'environment.remote'} eq 'off') ||
+ ((($env{'request.publicaccess'}) ||
+ (!&Apache::lonnet::is_on_map(
+ &unescape($env{'request.noversionuri'})))) &&
+ (!$forcereg))) {
+ return
+ $result
+ .''
+ .$force_title;
+ }
+# Graphical display after login only
+ if ($env{'request.registered'} && !$forcereg) { return ''; }
+ $result.=&innerregister($forcereg);
+ return $result.$force_title;
+}
+
sub innerregister {
my ($forcereg,$bread_crumbs) = @_;
my $const_space = ($env{'request.state'} eq 'construct');
@@ -472,8 +515,19 @@ sub innerregister {
$env{'request.registered'} = 1;
+ my $noremote = ($env{'environment.remote'} eq 'off');
+
undef(@inlineremote);
+ my $reopen=&Apache::lonmenu::reopenmenu();
+
+ my $newmail='';
+
+ if (&Apache::lonmsg::newmail() && !$noremote) {
+ # We have new mail and remote is up
+ $newmail= 'swmenu.setstatus("you have","messages");';
+ }
+
my $resurl;
if ( $env{'request.symb'} && $env{'request.course.id'} ) {
@@ -512,11 +566,11 @@ sub innerregister {
&Apache::lonhtmlcommon::clear_breadcrumbs();
&Apache::lonhtmlcommon::add_breadcrumb({text => 'View Resource'});
}
+ my $timesync = ( $noremote ? '' : 'swmenu.syncclock(1000*'.time.');' );
# =============================================================================
# ============================ This is for URLs that actually can be registered
- return '' unless ( ($env{'request.noversionuri'}!~m{^/(res/)*adm/})
- || $forcereg );
-
+ if ( ($env{'request.noversionuri'}!~m{^/(res/)*adm/})
+ || ($forcereg)) {
# -- This applies to homework problems for users with grading privileges
my $crs='/'.$env{'request.course.id'};
if ($env{'request.course.sec'}) {
@@ -543,11 +597,13 @@ sub innerregister {
"gocmd('/adm/parmset','set')",
'Content Settings');
}
- if ($env{'request.symb'}=~/^uploaded/ &&
- &Apache::lonnet::allowed('mdc',$crs)) {
- $hwkadd.=&switch('','',7,4,'docs.png','Folder/Page Content','parms[_2]',
- "gocmd('/adm/coursedocs','direct')",
- 'Folder/Page Content');
+ if ($noremote) {
+ if ($env{'request.symb'}=~/^uploaded/ &&
+ &Apache::lonnet::allowed('mdc',$crs)) {
+ $hwkadd.=&switch('','',7,4,'docs.png','Folder/Page Content','parms[_2]',
+ "gocmd('/adm/coursedocs','direct')",
+ 'Folder/Page Content');
+ }
}
# -- End Homework
###
@@ -696,7 +752,7 @@ sub innerregister {
###
###
# Prepare the rest of the buttons
- my $menuitems;
+ my ($menuitems,$got_prt,$got_wishlist);
if ($const_space) {
#
# We are in construction space
@@ -732,7 +788,7 @@ ENDMENUITEMS
} elsif ( defined($env{'request.course.id'}) &&
$env{'request.symb'} ne '' ) {
#
-# We are in a course and looking at a registred URL
+# We are in a course and looking at a registered URL
# Should probably be in mydesk.tab
#
$menuitems=(<
+//
+
+ENDREGTHIS
}
+ } else {
+ unless ($noremote) {
+# Not registered, graphical
+ return (<
+//
+
+ENDDONOTREGTHIS
+
+ }
+ return '';
+ }
}
sub is_course_upload {
@@ -865,10 +1042,22 @@ sub edit_course_upload {
return $cfile;
}
+sub loadevents() {
+ if ($env{'request.state'} eq 'construct' ||
+ $env{'request.noversionuri'} =~ m{^/res/adm/pages/}) { return ''; }
+ return 'LONCAPAreg();';
+}
+
+sub unloadevents() {
+ if ($env{'request.state'} eq 'construct' ||
+ $env{'request.noversionuri'} =~ m{^/res/adm/pages/}) { return ''; }
+ return 'LONCAPAstale();';
+}
+
sub startupremote {
my ($lowerurl)=@_;
- if ($env{'environment.remote'} eq 'off') {
- return ('');
+ unless ($env{'environment.remote'} eq 'on') {
+ return ('');
}
#
# The Remote actually gets launched!
@@ -946,7 +1135,7 @@ ENDSETFLAGS
}
sub maincall() {
- if ($env{'environment.remote'} eq 'off') { return ''; }
+ unless ($env{'environment.remote'} eq 'on') { return ''; }
return(<
// '."\n"
.'// 13)) { return ''; }
+ return "\n".qq(window.status+='.';swmenu.clearbut($row,$col););
+ } else {
+ $inlineremote[10*$row+$col]='';
+ return '';
+ }
}
# ============================================ Switch a button or create a link
@@ -1045,6 +1239,14 @@ sub switch {
my $idx=10*$row+$col;
$category_members{$cat}.=':'.$idx;
+ if ($env{'environment.remote'} eq 'on') {
+ if (($row<1) || ($row>13)) { return ''; }
+# Remote
+ $img=~s/\.png$/\.gif/;
+ return "\n".
+ qq(window.status+='.';swmenu.switchbutton($row,$col,"$img","$top","$bot","$act","$desc"););
+ }
+
# Inline Menu
if ($nobreak==2) { return ''; }
my $text=$top.' '.$bot;
@@ -1075,9 +1277,19 @@ sub switch {
}
} else {
# Inline Menu
- $inlineremote[$idx]=
+ my @tools = (93,91,81,82,83);
+ unless ($env{'request.state'} eq 'construct') {
+ push(@tools,63);
+ }
+ if (($env{'environment.icons'} eq 'iconsonly') &&
+ (grep(/^$idx$/,@tools))) {
+ $inlineremote[$idx] =
+ '';
+ } else {
+ $inlineremote[$idx] =
'';
+ }
}
return '';
}
@@ -1096,6 +1308,13 @@ sub secondlevel {
return $output;
}
+sub openmenu {
+ my $menuname = &get_menu_name();
+ unless ($env{'environment.remote'} eq 'on') { return ''; }
+ my $nothing = &Apache::lonhtmlcommon::javascript_nothing();
+ return "window.open(".$nothing.",'".$menuname."');";
+}
+
sub inlinemenu {
undef(@inlineremote);
undef(%category_members);
@@ -1138,7 +1357,13 @@ sub rawconfig {
#
my $textualoverride=shift;
my $output='';
- return '' unless $textualoverride;
+ if ($env{'environment.remote'} eq 'on') {
+ $output.=
+ "window.status='Opening Remote Control';var swmenu=".&openmenu().
+"\nwindow.status='Configuring Remote Control ';";
+ } else {
+ unless ($textualoverride) { return ''; }
+ }
my $uname=$env{'user.name'};
my $udom=$env{'user.domain'};
my $adv=$env{'user.adv'};
@@ -1313,6 +1538,12 @@ sub rawconfig {
$uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc,$cat);
}
}
+ if ($env{'environment.remote'} eq 'on') {
+ $output.="\nwindow.status='Synchronizing Time';swmenu.syncclock(1000*".time.");\nwindow.status='Remote Control Configured.';";
+ if (&Apache::lonmsg::newmail()) {
+ $output.='swmenu.setstatus("you have","messages");';
+ }
+ }
return $output;
}
@@ -1341,7 +1572,7 @@ sub check_for_rcrs {
# ======================================================================= Close
sub close {
- if ($env{'environment.remote'} eq 'off') { return ''; }
+ unless ($env{'environment.remote'} eq 'on') { return ''; }
my $menuname = &get_menu_name();
return(<
@@ -1385,6 +1616,27 @@ END
}
+sub countdown_toggle_js {
+ return <<"END";
+
+function toggleCountdown() {
+ var countdownid = document.getElementById('duedatecountdown');
+ var currstyle = countdownid.style.display;
+ if (currstyle == 'inline') {
+ countdownid.style.display = 'none';
+ document.getElementById('ddcountcollapse').innerHTML='';
+ document.getElementById('ddcountexpand').innerHTML='◄ ';
+ } else {
+ countdownid.style.display = 'inline';
+ document.getElementById('ddcountcollapse').innerHTML='► ';
+ document.getElementById('ddcountexpand').innerHTML='';
+ }
+ return;
+}
+
+END
+}
+
sub utilityfunctions {
my $currenturl=&Apache::lonnet::clutter(&Apache::lonnet::fixversion((split(/\?/,$env{'request.noversionuri'}))[0]));
if ($currenturl =~ m{^/adm/wrapper/ext/}
@@ -1413,21 +1665,14 @@ sub utilityfunctions {
my $end_page_annotate =
&Apache::loncommon::end_page({'js_ready' => 1});
- my $start_page_bookmark =
- &Apache::loncommon::start_page('Bookmarks',undef,
- {'only_body' => 1,
- 'js_ready' => 1,
- 'bgcolor' => '#BBBBBB',});
-
- my $end_page_bookmark =
- &Apache::loncommon::end_page({'js_ready' => 1});
-
my $confirm_switch = &mt("Editing requires switching to the resource's home server.").'\n'.
&mt('Switch server?');
my $esc_url=&escape($currenturl);
my $esc_symb=&escape($currentsymb);
+ my $countdown = &countdown_toggle_js();
+
return (<'
- +'$end_page_bookmark' );
- bmquery.document.close();
-}
+$countdown
ENDUTILITY
}
@@ -1626,6 +1857,16 @@ sub constspaceform {
ENDCONSTSPACEFORM
}
+sub get_nav_status {
+ my $navstatus="swmenu.w_loncapanav_flag=";
+ if ($env{'environment.remotenavmap'} eq 'on') {
+ $navstatus.="1";
+ } else {
+ $navstatus.="-1";
+ }
+ return $navstatus;
+}
+
sub hidden_button_check {
if ( $env{'request.course.id'} eq ''
|| $env{'request.role.adv'} ) {
@@ -1992,6 +2233,52 @@ sub required_privs {
return $privs;
}
+sub countdown_timer {
+ if (($env{'request.course.id'}) && ($env{'request.symb'} ne '') &&
+ ($env{'request.filename'}=~/$LONCAPA::assess_re/) &&
+ ($Apache::inputtags::status[-1] eq 'CAN_ANSWER')) {
+ my $duedate = &Apache::lonnet::EXT("resource.0.duedate");
+ my @interval=&Apache::lonnet::EXT("resource.0.interval");
+ my $hastimeleft;
+ if (@interval > 1) {
+ my $first_access=&Apache::lonnet::get_first_access($interval[1]);
+ if ($first_access > 0) {
+ if ($first_access+$interval[0] > time) {
+ $hastimeleft = 1;
+ }
+ }
+ }
+ if (($duedate && $duedate > time) ||
+ (!$duedate && $hastimeleft)) {
+ my ($collapse,$expand,$alttxt,$title,$currdisp);
+ if (@interval > 1 && $hastimeleft) {
+ $currdisp = 'inline';
+ $collapse = '► ';
+ } else {
+ $currdisp = 'none';
+ $expand = '◄ ';
+ }
+ unless ($env{'environment.icons'} eq 'iconsonly') {
+ $alttxt = &mt('Timer');
+ $title = $alttxt.' ';
+ }
+ my $desc = &mt('Countdown to due date/time');
+ return <