# The LearningOnline Network with CAPA # Navigate Maps Handler # # $Id: lonnavdisplay.pm,v 1.10 2009/05/06 16:19:34 bisitz 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/ # ### package Apache::lonnavdisplay; use strict; use Apache::Constants qw(:common :http); use Apache::lonmenu(); use Apache::loncommon(); use Apache::lonnavmaps(); use Apache::lonhtmlcommon(); use Apache::lonnet; use Apache::lonlocal; use Time::HiRes qw( gettimeofday tv_interval ); sub handler { my $r = shift; real_handler($r); } sub real_handler { my $r = shift; #my $t0=[&gettimeofday()]; # Handle header-only request if ($r->header_only) { if ($env{'browser.mathml'}) { &Apache::loncommon::content_type($r,'text/xml'); } else { &Apache::loncommon::content_type($r,'text/html'); } $r->send_http_header; return OK; } # Send header, don't cache this page if ($env{'browser.mathml'}) { &Apache::loncommon::content_type($r,'text/xml'); } else { &Apache::loncommon::content_type($r,'text/html'); } &Apache::loncommon::no_cache($r); my %toplinkitems=(); &Apache::lonnavmaps::add_linkitem(\%toplinkitems,'blank','', "Select Action"); if ($ENV{QUERY_STRING} eq 'collapseExternal') { &Apache::lonnet::put('environment',{'remotenavmap' => 'off'}); &Apache::lonnet::appenv({'environment.remotenavmap' => 'off'}); my $menu=&Apache::lonmenu::reopenmenu(); my $navstatus=&Apache::lonmenu::get_nav_status(); if ($menu) { $menu=(<send_http_header; my $js =<<"ENDSUBM"; ENDSUBM $r->print(&Apache::loncommon::start_page(undef,$js, {'only_body' => 1, 'bgcolor' => '#FFFFFF', 'add_entries' => {'onload' => "submitthis()"}}). &Apache::loncommon::end_page()); return OK; } if ($ENV{QUERY_STRING} =~ /^launchExternal/) { &Apache::lonnet::put('environment',{'remotenavmap' => 'on'}); &Apache::lonnet::appenv({'environment.remotenavmap' => 'on'}); my $menu=&Apache::lonmenu::reopenmenu(); my $navstatus=&Apache::lonmenu::get_nav_status(); if ($menu) { $r->print(< swmenu=$menu swmenu.clearTimeout(swmenu.menucltim); $navstatus MENU } } if ($ENV{QUERY_STRING} eq 'turningOffExternal') { $env{'environment.remotenavmap'}='off'; } # Create the nav map my $navmap = Apache::lonnavmaps::navmap->new(); if (!defined($navmap)) { my $requrl = $r->uri; $env{'user.error.msg'} = "$requrl:bre:0:0:Course not initialized"; $env{'user.reinit'} = 1; return HTTP_NOT_ACCEPTABLE; } $r->send_http_header; # ------------------------------------------------------------ Get query string &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['register','sort','showOnlyHomework','postsymb']); # ----------------------------------------------------- Force menu registration my $body_only=''; my $js; if ($env{'environment.remotenavmap'} eq 'on') { $js=''; $body_only=1; } # Header my $course_type = &Apache::loncommon::course_type(); $r->print(&Apache::loncommon::start_page(#'Navigate '.$course_type. 'Course Contents', $js, {'only_body' => $body_only, 'force_register' => $env{'form.register'},})); $r->print(''); $r->rflush(); # Check that it's defined if (!($navmap->courseMapDefined())) { $r->print(&Apache::loncommon::help_open_menu('Navigation Screen','Navigation_Screen',undef,'RAT')); $r->print(''.&mt('Coursemap undefined.'). '' . &Apache::loncommon::end_page()); return OK; } # See if there's only one map in the top-level, if we don't # already have a filter... if so, automatically display it # (older code; should use retrieveResources) if ($ENV{QUERY_STRING} !~ /filter/) { my $iterator = $navmap->getIterator(undef, undef, undef, 0); my $curRes; my $sequenceCount = 0; my $sequenceId; while ($curRes = $iterator->next()) { if (ref($curRes) && $curRes->is_sequence()) { $sequenceCount++; $sequenceId = $curRes->map_pc(); } } if ($sequenceCount == 1) { # The automatic iterator creation in the render call # will pick this up. We know the condition because # the defined($env{'form.filter'}) also ensures this # is a fresh call. $env{'form.filter'} = "$sequenceId"; } } if ($ENV{QUERY_STRING} eq 'launchExternal') { $r->print('
'); $r->print(' '); } if ($env{'environment.remotenavmap'} ne 'on') { $r->print(&launch_win('link','yes',\%toplinkitems)); } if ($env{'environment.remotenavmap'} eq 'on') { &Apache::lonnavmaps::add_linkitem(\%toplinkitems,'closenav', 'collapse()', "Close navigation window"); } # Check to see if the student is jumping to next open, do-able problem if ($ENV{QUERY_STRING} =~ /^jumpToFirstHomework/) { # Find the next homework problem that they can do. my $iterator = $navmap->getIterator(undef, undef, undef, 1); my $curRes; my $foundDoableProblem = 0; my $minimumduedate; my $now = time(); while ($curRes = $iterator->next()) { if (ref($curRes) && $curRes->is_problem()) { my $status = $curRes->status(); my $thisduedate=$curRes->duedate(); if ($thisduedate > $now && $curRes->completable()) { $foundDoableProblem = 1; if (!defined($minimumduedate) || $thisduedate<$minimumduedate) { # Pop open all previous maps my $stack = $iterator->getStack(); pop @$stack; # last resource in the stack is the problem # itself, which we don't need in the map stack my @mapPcs = map {$_->map_pc()} @$stack; $env{'form.filter'} = join(',', @mapPcs); # Mark as both "here" and "jump" $env{'form.postsymb'} = $curRes->symb(); $minimumduedate=$thisduedate; } } } } # If we found no problems, print a note to that effect. if (!$foundDoableProblem) { $r->print("" .&mt("All homework assignments have been completed.") .""); } } else { &Apache::lonnavmaps::add_linkitem(\%toplinkitems,'firsthomework', 'location.href="navmaps?jumpToFirstHomework"', "Show my first due problem"); } my $suppressEmptySequences = 0; my $filterFunc = undef; my $resource_no_folder_link = 0; # Display only due homework. my $showOnlyHomework = 0; if ($env{'form.showOnlyHomework'} eq "1") { $showOnlyHomework = 1; $suppressEmptySequences = 1; $filterFunc = sub { my $res = shift; return $res->completable() || $res->is_map(); }; &Apache::lonnavmaps::add_linkitem(\%toplinkitems,'everything', 'location.href="navmaps?sort='.$env{'form.sort'}.'"', "Show everything"); $r->print("".&mt("Uncompleted Problems").""); $env{'form.filter'} = ''; $env{'form.condition'} = 1; $resource_no_folder_link = 1; } else { &Apache::lonnavmaps::add_linkitem(\%toplinkitems,'uncompleted', 'location.href="navmaps?sort='.$env{'form.sort'}. '&showOnlyHomework=1"', "Show only uncompleted problems"); } my %selected=($env{'form.sort'} => ' selected="selected"'); my $sort_html=("
".&mt('Sort by:')."
"); # renderer call my $renderArgs = { 'cols' => [0,1,2,3], 'sort' => $env{'form.sort'}, 'url' => '/adm/navmaps', 'navmap' => $navmap, 'suppressNavmap' => 1, 'suppressEmptySequences' => $suppressEmptySequences, 'filterFunc' => $filterFunc, 'resource_no_folder_link' => $resource_no_folder_link, 'sort_html'=> $sort_html, 'r' => $r, 'caller' => 'navmapsdisplay', 'linkitems' => \%toplinkitems}; my $render = &Apache::lonnavmaps::render($renderArgs); # If no resources were printed, print a reassuring message so the # user knows there was no error. if ($renderArgs->{'counter'} == 0) { if ($showOnlyHomework) { $r->print("

".&mt("All homework is currently completed.")."

"); } else { # both jumpToFirstHomework and normal use the same: course must be empty $r->print("

".&mt("This course is empty.")."

"); } } #my $td=&tv_interval($t0); #$r->print("
$td"); $r->print(&Apache::loncommon::end_page()); $r->rflush(); return OK; } sub launch_win { my ($mode,$script,$toplinkitems,$firsttime)=@_; my $result; if ($script ne 'no') { $result.=''; } if ($mode eq 'link') { &Apache::lonnavmaps::add_linkitem($toplinkitems,'launchnav', 'launch_navmapwin()', "Launch navigation window"); } return $result; } 1; __END__