--- loncom/interface/lonmenu.pm 2008/03/10 23:47:35 1.235 +++ loncom/interface/lonmenu.pm 2009/08/20 06:04:14 1.244.2.6 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Routines to control the menu # -# $Id: lonmenu.pm,v 1.235 2008/03/10 23:47:35 raeburn Exp $ +# $Id: lonmenu.pm,v 1.244.2.6 2009/08/20 06:04:14 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -36,6 +36,105 @@ # browser.interface is 'textual' # +=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 SUBROUTINES + +=over + +=item show_course() + +Little texts + +=item initlittle() + +=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 convert_menu_function() + +FIXME this needs to move into mydesktab and the other locations +the text is generated + +=item hidden_button_check() + +=item roles_selector() + +=item jump_to_role() + +=back + +=cut + package Apache::lonmenu; use strict; @@ -53,7 +152,6 @@ my @inlineremote; -# ================================================================ Little texts sub show_course { my $course = !$env{'user.adv'}; if (!$env{'user.adv'}) { @@ -72,11 +170,11 @@ sub initlittle { return &Apache::lonlocal::texthash('ret' => 'Return to Last Location', 'nav' => 'Navigate Contents', 'main' => 'Main Menu', - 'roles' => (&show_course()? + 'roles' => (&Apache::loncommon::show_course()? 'Courses':'Roles'), 'other' => 'Other Roles', 'docs' => 'Edit Course', - 'exit' => 'Exit', + 'exit' => 'Logout', 'login' => 'Log In', 'launch' => 'Launch Remote Control', 'groups' => 'Groups', @@ -84,8 +182,6 @@ sub initlittle { ); } -# ============================= This gets called at the top of the body section - sub menubuttons { my $forcereg=shift; my $registration=shift; @@ -251,16 +347,12 @@ ENDCRELOAD } my $form=&serverform(); my $utility=&utilityfunctions(); - my $remote; - if ($env{'user.adv'}) { - $remote = ''.$lt{'launch'}.'' - } my $helplink=&Apache::loncommon::top_nav_help('Help'); return (< -// BEGIN LON-CAPA Internal // @@ -272,7 +364,6 @@ $reloadlink $navmaps $docs $groups -$remote $roles $helplink $lt{'exit'} @@ -302,7 +393,6 @@ sub show_return_link { )); } -# ====================================== This gets called in the header section sub registerurl { my ($forcereg) = @_; @@ -319,7 +409,9 @@ sub registerurl { &unescape($env{'request.noversionuri'})))) && (!$forcereg))) { return $result. - ''.$force_title; + ''.$force_title; } # Graphical display after login only if ($env{'request.registered'} && !$forcereg) { return ''; } @@ -327,9 +419,6 @@ sub registerurl { return $result.$force_title; } -# =========== This gets called in order to register a URL, both with the Remote -# =========== and in the body of the document - sub innerregister { my ($forcereg, $titletable) = @_; my $result = ''; @@ -406,7 +495,7 @@ sub innerregister { if ($env{'request.symb'} ne '' && $env{'request.filename'}=~/\.(problem|exam|quiz|assess|survey|form|task)$/) { if (&Apache::lonnet::allowed('mgr',$crs)) { - $hwkadd.=&switch('','',7,2,'pgrd.gif','problem[_1]','grades[_3]', + $hwkadd.=&switch('','',7,2,'pgrd.gif','problem[_1]','grades[_4]', "gocmd('/adm/grades','gradingmenu')", 'Modify user grades for this assessment resource'); } elsif (&Apache::lonnet::allowed('vgr',$crs)) { @@ -427,6 +516,12 @@ sub innerregister { ### resource ### my $editbutton = ''; + my $noeditbutton = 1; + my ($cnum,$cdom); + if ($env{'request.course.id'}) { + $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; + $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + } if ($env{'user.author'}) { if ($env{'request.role'}=~/^(aa|ca|au)/) { # Set defaults for authors @@ -434,7 +529,7 @@ sub innerregister { my $action = "go('/priv/".$env{'user.name'}."');"; my $cadom = $env{'request.role.domain'}; my $caname = $env{'user.name'}; - my $desc = "Enter my resource construction space"; + my $desc = "Enter my construction space"; # Set defaults for co-authors if ($env{'request.role'} =~ /^ca/) { ($cadom,$caname)=($env{'request.role'}=~/($match_domain)\/($match_username)$/); @@ -454,6 +549,7 @@ sub innerregister { foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } } if (!$allowed) { $editbutton=&switch('','',6,1,$top,,$bottom,$action,$desc); + $noeditbutton = 0; } } ## @@ -462,6 +558,7 @@ sub innerregister { my $cfile=''; my $cfuname=''; my $cfudom=''; + my $uploaded; if ($env{'request.filename'}) { my $file=&Apache::lonnet::declutter($env{'request.filename'}); $file=~s/^($match_domain)\/($match_username)/\/priv\/$2/; @@ -482,10 +579,27 @@ sub innerregister { $editbutton=&switch ('','',6,1,'pcstr.gif','edit[_1]','resource[_2]', "go('".$cfile."');","Edit this resource"); + $noeditbutton = 0; } elsif ($editbutton eq '') { $editbutton=&clear(6,1); } } + if (($noeditbutton) && ($env{'request.filename'})) { + if (&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) { + my $file=&Apache::lonnet::declutter($env{'request.filename'}); + if (defined($cnum) && defined($cdom)) { + if (&is_course_upload($file,$cnum,$cdom)) { + my $cfile = &edit_course_upload($file,$cnum,$cdom); + if ($cfile) { + $editbutton=&switch + ('','',6,1,'pcstr.gif','edit[_1]', + 'resource[_2]',"go('".$cfile."');", + 'Edit this resource'); + } + } + } + } + } ### ### # Prepare the rest of the buttons @@ -503,7 +617,7 @@ sub innerregister { $menuitems=(< 0){ + $menuitems.="anot2.gif"; +}else{ + $menuitems.="anot.gif"; +} +$menuitems.="&anno-[_1]&tations[_1]&annotate()&"; +$menuitems.="Make notes and annotations about this resource&&1\n"; + + unless ($noremote) { + my $showreqcrs = &check_for_rcrs(); + if ($showreqcrs) { + $menuitems.="s&8&1&rcrs.gif&request[_1]&course[_16]". + "&go('/adm/requestcourse')&Course requests\n"; + } + } unless ($env{'request.noversionuri'}=~/\/(bulletinboard|smppg|navmaps|syllabus|aboutme)(\?|$)/) { if (!$env{'request.enc'}) { $menuitems.=(< +// ENDREGTHIS } @@ -677,6 +811,7 @@ ENDDONOTREGTEXT $result = (< +// ENDDONOTREGTHIS } @@ -709,6 +845,42 @@ ENDDONOTREGTHIS return $result; } +sub is_course_upload { + my ($file,$cnum,$cdom) = @_; + my $uploadpath = &LONCAPA::propath($cdom,$cnum); + $uploadpath =~ s{^\/}{}; + if (($file =~ m{^\Q$uploadpath\E/userfiles/docs/}) || + ($file =~ m{^userfiles/\Q$cdom\E/\Q$cnum\E/docs/})) { + return 1; + } + return; +} + +sub edit_course_upload { + my ($file,$cnum,$cdom) = @_; + my $cfile; + if ($file =~/\.(htm|html|css|js|txt)$/) { + my $ext = $1; + my $url = &Apache::lonnet::hreflocation('',$file); + my $home = &Apache::lonnet::homeserver($cnum,$cdom); + my @ids=&Apache::lonnet::current_machine_ids(); + my $dest; + if ($home && grep(/^\Q$home\E$/,@ids)) { + $dest = $url.'?forceedit=1'; + } else { + unless (&Apache::lonnet::get_locks()) { + $dest = '/adm/switchserver?otherserver='. + $home.'&role='.$env{'request.role'}. + '&url='.$url.'&forceedit=1'; + } + } + if ($dest) { + $cfile = &HTML::Entities::encode($dest,'"<>&'); + } + } + return $cfile; +} + sub loadevents() { if ($env{'request.state'} eq 'construct' || $env{'request.noversionuri'} =~ m{^/res/adm/pages/}) { return ''; } @@ -721,7 +893,6 @@ sub unloadevents() { return 'LONCAPAstale();'; } -# ============================================================= Start up remote sub startupremote { my ($lowerurl)=@_; @@ -737,6 +908,7 @@ sub startupremote { my $message=&mt('"Waiting for Remote Control window to load: "+[_1]','waited'); return(< +// ENDREMOTESTARTUP } @@ -794,8 +966,10 @@ ENDREMOTESTARTUP sub setflags() { return(< +// ENDSETFLAGS } @@ -805,7 +979,9 @@ sub maincall() { ($env{'environment.remote'} eq 'off')) { return ''; } return(< +// ENDMAINCALL } @@ -817,8 +993,9 @@ sub load_remote_msg { ($env{'environment.remote'} eq 'off')) { return ''; } my $esclowerurl=&escape($lowerurl); - my $link=&mt('Continue on in Inline Menu mode', - "/adm/remote?action=collapse&url=$esclowerurl"); + my $link=&mt('[_1]Continue[_2] on in Inline Menu mode', + '', + ''); return(<
@@ -835,7 +1012,6 @@ sub get_menu_name { return 'LCmenu'.$hostid; } -# ================================================================= Reopen menu sub reopenmenu { if (($env{'browser.interface'} eq 'textual') || @@ -845,13 +1021,17 @@ sub reopenmenu { return('window.open('.$nothing.',"'.$menuname.'","",false);'); } -# =============================================================== Open the menu sub open { my $returnval=''; if (($env{'browser.interface'} eq 'textual') || ($env{'environment.remote'} eq 'off')) { - return ''; + return + ''; } my $menuname = &get_menu_name(); @@ -864,11 +1044,13 @@ sub open { #} #ENDRESIZE # } - $returnval.=(< ENDOPEN return ''; } @@ -898,8 +1080,9 @@ sub switch { $top=&mt($top); $bot=&mt($bot); $desc=&mt($desc); - $img=&mt($img); - + if (($env{'environment.remote'} ne 'off') || ($env{'environment.icons'} eq 'classic')) { + $img=&mt($img); + } my $idx=10*$row+$col; $category_members{$cat}.=':'.$idx; @@ -994,11 +1177,14 @@ sub inlinemenu { &rawconfig(1); my $output=''; for (my $col=1; $col<=2; $col++) { - $output.='"; @@ -1031,7 +1218,7 @@ sub rawconfig { my $uname=$env{'user.name'}; my $udom=$env{'user.domain'}; my $adv=$env{'user.adv'}; - my $show_course=&show_course(); + my $show_course=&Apache::loncommon::show_course(); my $author=$env{'user.author'}; my $crs=''; if ($env{'request.course.id'}) { @@ -1125,6 +1312,32 @@ sub rawconfig { } } } + } elsif ($pro eq 'tools') { + my @tools = ('aboutme','blog','portfolio'); + if (grep(/^\Q$prt\E$/,@tools)) { + if (!&Apache::lonnet::usertools_access($env{'user.name'}, + $env{'user.domain'}, + $prt,undef,'tools')) { + $output.=&clear($row,$col); + next; + } + } elsif (($prt eq 'reqcrsnsc') || ($prt eq 'reqcrsshc')) { + if (($prt eq 'reqcrsnsc') && ($show_course)) { + next; + } + if (($prt eq 'reqcrsshc') && (!$show_course)) { + next; + } + my $showreqcrs = &check_for_rcrs(); + if (!$showreqcrs) { + $output.=&clear($row,$col); + next; + } + } + $prt='any'; + $output.=&secondlevel( + $uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc,$cat); + } } unless (($env{'browser.interface'} eq 'textual') || @@ -1138,6 +1351,19 @@ sub rawconfig { return $output; } +sub check_for_rcrs { + my $showreqcrs = 0; + foreach my $type ('official','unofficial','community') { + if (&Apache::lonnet::usertools_access($env{'user.name'}, + $env{'user.domain'}, + $type,undef,'requestcourses')) { + $showreqcrs = 1; + last; + } + } + return $showreqcrs; +} + # ======================================================================= Close sub close { @@ -1146,6 +1372,7 @@ sub close { my $menuname = &get_menu_name(); return(< +// ENDCLOSE } @@ -1341,16 +1569,16 @@ function set_bookmark() { bmquery=window.open('','bmquery','width=365,height=165,scrollbars=0'); bmquery.document.write( '$start_page_bookmark' - +"
\\n
'; + $output.=''; for (my $row=1; $row<=8; $row++) { foreach my $cat (keys(%category_members)) { if ($category_positions{$cat} ne "$col,$row") { next; } - $output.=''; + #$output.='
'.&mt($category_names{$cat}).'
'; + $output.='
'; + $output.=''.&mt($category_names{$cat}).''; + $output.='
'.&mt($category_names{$cat}).'
'; my %active=(); foreach my $menu_item (split(/\:/,$category_members{$cat})) { if ($inlineremote[$menu_item]) { @@ -1009,6 +1195,7 @@ sub inlinemenu { $output.=$inlineremote[$item]; } $output.='
'; + $output.=''; } } $output.="
Link Name:
" - +"
Address:

<\\/center><\\/td>" - +"<\\/tr><\\/table><\\/form><\\/center>" + +'
' + +'
Link Name:
' + +'
Address:

' +'$end_page_bookmark' ); bmquery.document.close(); } @@ -1426,7 +1654,7 @@ sub hidden_button_check { sub roles_selector { my ($cdom,$cnum) = @_; my $now = time; - my %courseroles; + my (%courseroles,%seccount); my $is_cc; my $role_selector; if ($env{'user.role.cc./'.$cdom.'/'.$cnum}) { @@ -1441,39 +1669,45 @@ sub roles_selector { } } if ($is_cc) { - my %adv_roles = - &Apache::lonnet::get_course_adv_roles($env{'request.course.id'},1); - foreach my $role (keys(%adv_roles),'st') { - my ($urole,$usec) = split(/:/,$role); - @{$courseroles{$urole}} = 'none'; - } + &get_all_courseroles($cdom,$cnum,\%courseroles,\%seccount); } else { + my %gotnosection; foreach my $item (keys(%env)) { - if ($item =~ m-^user\.role\.([^.]+)\./\Q$cdom\E/\Q$cnum\E(/?\w*)$-) { + if ($item =~ m-^user\.role\.([^.]+)\./\Q$cdom\E/\Q$cnum\E/?(\w*)$-) { my $role = $1; my $sec = $2; next if ($role eq 'gr'); my ($start,$end) = split(/\./,$env{$item}); next if (($start && $start > $now) || ($end && $end < $now)); if ($sec eq '') { - $sec = 'none'; + if (!$gotnosection{$role}) { + $seccount{$role} ++; + $gotnosection{$role} = 1; + } } if (ref($courseroles{$role}) eq 'ARRAY') { - if (!grep(/^Q$sec\E$/,@{$courseroles{$role}})) { - push(@{$courseroles{$role}},$sec); + if ($sec ne '') { + if (!grep(/^Q$sec\E$/,@{$courseroles{$role}})) { + push(@{$courseroles{$role}},$sec); + $seccount{$role} ++; + } } } else { - @{$courseroles{$role}} = ($sec); + @{$courseroles{$role}} = (); + if ($sec ne '') { + $seccount{$role} ++; + push(@{$courseroles{$role}},$sec); + } } } } } my @roles_order = ('cc','in','ta','ep','ad','st'); if (keys(%courseroles) > 1) { - $role_selector = &jump_to_role($cdom,$cnum); + $role_selector = &jump_to_role($cdom,$cnum,\%seccount,\%courseroles); $role_selector .= '