File:  [LON-CAPA] / loncom / interface / lonnavdisplay.pm
Revision 1.6: download - view: text, annotated - select for diffs
Thu Feb 26 16:17:30 2009 UTC (15 years, 2 months ago) by schafran
Branches: MAIN
CVS tags: HEAD
Box title is now the main title of the next page and the link text or the former page title will be set to the subtitle in the near future.
Group: consistent wording

    1: # The LearningOnline Network with CAPA
    2: # Navigate Maps Handler
    3: #
    4: # $Id: lonnavdisplay.pm,v 1.6 2009/02/26 16:17:30 schafran Exp $
    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: #
   28: ###
   29: 
   30: package Apache::lonnavdisplay;
   31: 
   32: use strict;
   33: use Apache::Constants qw(:common :http);
   34: use Apache::lonmenu();
   35: use Apache::loncommon();
   36: use Apache::lonnavmaps();
   37: use Apache::lonhtmlcommon();
   38: use Apache::lonnet;
   39: use Apache::lonlocal;
   40: use Time::HiRes qw( gettimeofday tv_interval );
   41: 
   42: sub handler {
   43:     my $r = shift;
   44:     real_handler($r);
   45: }
   46: 
   47: sub real_handler {
   48:     my $r = shift;
   49:     #my $t0=[&gettimeofday()];
   50:     # Handle header-only request
   51:     if ($r->header_only) {
   52:         if ($env{'browser.mathml'}) {
   53:             &Apache::loncommon::content_type($r,'text/xml');
   54:         } else {
   55:             &Apache::loncommon::content_type($r,'text/html');
   56:         }
   57:         $r->send_http_header;
   58:         return OK;
   59:     }
   60: 
   61:     # Send header, don't cache this page
   62:     if ($env{'browser.mathml'}) {
   63:         &Apache::loncommon::content_type($r,'text/xml');
   64:     } else {
   65:         &Apache::loncommon::content_type($r,'text/html');
   66:     }
   67:     &Apache::loncommon::no_cache($r);
   68: 
   69:     my %toplinkitems=();
   70:     &Apache::lonnavmaps::add_linkitem(\%toplinkitems,'blank','',
   71: 				      "Select Action");
   72:     if ($ENV{QUERY_STRING} eq 'collapseExternal') {
   73: 	&Apache::lonnet::put('environment',{'remotenavmap' => 'off'});
   74: 	&Apache::lonnet::appenv({'environment.remotenavmap' => 'off'});
   75: 	my $menu=&Apache::lonmenu::reopenmenu();
   76: 	my $navstatus=&Apache::lonmenu::get_nav_status();
   77: 	if ($menu) {
   78: 	    $menu=(<<MENU)
   79:              swmenu=$menu
   80:              swmenu.clearTimeout(swmenu.menucltim);
   81: 	     $navstatus
   82: MENU
   83:         } else {
   84: 	    my $nothing = &Apache::lonhtmlcommon::javascript_nothing();
   85: 	    my $mainwindow='window.open('.$nothing.',"loncapaclient","",false);';
   86: 	    $menu=(<<MENU)
   87:              swmenu=$mainwindow
   88: 	     $navstatus
   89: MENU
   90: 	}
   91:         $r->send_http_header;
   92: 	my $js =<<"ENDSUBM";
   93: 	  <script type="text/javascript">
   94:  	    function submitthis() {
   95: 		    $menu
   96: 		    self.close();
   97: 	    }
   98: 	
   99:   	  </script>
  100: ENDSUBM
  101:         $r->print(&Apache::loncommon::start_page(undef,$js,
  102: 						 {'only_body' => 1,
  103: 						  'bgcolor'   => '#FFFFFF',
  104: 						  'add_entries' => 
  105: 						      {'onload' =>
  106: 							   "submitthis()"}}).
  107: 		  &Apache::loncommon::end_page());
  108: 
  109:         return OK;
  110:     }
  111:     if ($ENV{QUERY_STRING} =~ /^launchExternal/) {
  112: 	&Apache::lonnet::put('environment',{'remotenavmap' => 'on'});
  113: 	&Apache::lonnet::appenv({'environment.remotenavmap' => 'on'});
  114:  	my $menu=&Apache::lonmenu::reopenmenu();
  115: 	my $navstatus=&Apache::lonmenu::get_nav_status();
  116: 	if ($menu) {
  117: 	    $r->print(<<MENU);
  118:              <script type="text/javascript">
  119:              swmenu=$menu
  120:              swmenu.clearTimeout(swmenu.menucltim);
  121: 	     $navstatus
  122:              </script>
  123: MENU
  124:         }
  125:    }
  126:     if ($ENV{QUERY_STRING} eq 'turningOffExternal') {
  127: 	$env{'environment.remotenavmap'}='off';
  128:     }
  129: 
  130:     # Create the nav map
  131:     my $navmap = Apache::lonnavmaps::navmap->new();
  132: 
  133:     if (!defined($navmap)) {
  134:         my $requrl = $r->uri;
  135:         $env{'user.error.msg'} = "$requrl:bre:0:0:Course not initialized";
  136:         $env{'user.reinit'} = 1;
  137:         return HTTP_NOT_ACCEPTABLE;
  138:     }
  139:     $r->send_http_header;
  140: 
  141: # ------------------------------------------------------------ Get query string
  142:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['register','sort','showOnlyHomework','postsymb']);
  143:     
  144: # ----------------------------------------------------- Force menu registration
  145:     my $body_only='';
  146:     my $js;
  147:     if ($env{'environment.remotenavmap'} eq 'on') {
  148: 	$js='<script type="text/javascript">
  149:                 function collapse() {
  150:                    this.document.location="/adm/navmaps?collapseExternal";
  151:                 }
  152:              </script>';
  153: 	$body_only=1;
  154:     }
  155: 
  156:     # Header
  157:     my $course_type = &Apache::loncommon::course_type();
  158:     $r->print(&Apache::loncommon::start_page(#'Navigate '.$course_type.
  159: 					     'Course Contents',
  160: 					     $js,
  161: 					     {'only_body'       => $body_only,
  162: 					      'force_register'  =>
  163: 						  $env{'form.register'},}));
  164:     $r->print('<script type="text/javascript">window.focus();</script>');
  165:      
  166:     $r->rflush();
  167: 
  168:     # Check that it's defined
  169:     if (!($navmap->courseMapDefined())) {
  170: 	$r->print(&Apache::loncommon::help_open_menu('Navigation Screen','Navigation_Screen',undef,'RAT'));
  171:         $r->print('<span class="LC_error">'.&mt('Coursemap undefined.').
  172: 		  '</span>' .
  173:                   &Apache::loncommon::end_page());
  174:         return OK;
  175:     }
  176: 
  177:     # See if there's only one map in the top-level, if we don't
  178:     # already have a filter... if so, automatically display it
  179:     # (older code; should use retrieveResources)
  180:     if ($ENV{QUERY_STRING} !~ /filter/) {
  181:         my $iterator = $navmap->getIterator(undef, undef, undef, 0);
  182:         my $curRes;
  183:         my $sequenceCount = 0;
  184:         my $sequenceId;
  185:         while ($curRes = $iterator->next()) {
  186:             if (ref($curRes) && $curRes->is_sequence()) {
  187:                 $sequenceCount++;
  188:                 $sequenceId = $curRes->map_pc();
  189:             }
  190:         }
  191:         
  192:         if ($sequenceCount == 1) {
  193:             # The automatic iterator creation in the render call 
  194:             # will pick this up. We know the condition because
  195:             # the defined($env{'form.filter'}) also ensures this
  196:             # is a fresh call.
  197:             $env{'form.filter'} = "$sequenceId";
  198:         }
  199:     }
  200: 
  201:     if ($ENV{QUERY_STRING} eq 'launchExternal') {
  202: 	$r->print('
  203:           <form name="returnwin" action="/adm/flip?postdata=navlaunch%3a" 
  204:                 method="post" target="loncapaclient">
  205:           </form>');
  206: 	$r->print('
  207:           <script type="text/javascript">
  208:               this.document.returnwin.submit();
  209:           </script>');
  210:     }
  211: 
  212:     if ($env{'environment.remotenavmap'} ne 'on') {
  213: 	$r->print(&launch_win('link','yes',\%toplinkitems));
  214:     } 
  215:     if ($env{'environment.remotenavmap'} eq 'on') {
  216: 	&Apache::lonnavmaps::add_linkitem(\%toplinkitems,'closenav',
  217: 					  'collapse()',
  218: 					  "Close navigation window");
  219:     } 
  220: 
  221: 
  222:     # Check to see if the student is jumping to next open, do-able problem
  223:     if ($ENV{QUERY_STRING} =~ /^jumpToFirstHomework/) {
  224:         # Find the next homework problem that they can do.
  225:         my $iterator = $navmap->getIterator(undef, undef, undef, 1);
  226:         my $curRes;
  227:         my $foundDoableProblem = 0;
  228:         my $minimumduedate;
  229:         my $now = time();
  230: 	
  231:         while ($curRes = $iterator->next()) {
  232:             if (ref($curRes) && $curRes->is_problem()) {
  233:                 my $status = $curRes->status();
  234: 		my $thisduedate=$curRes->duedate();
  235:                 if ($thisduedate > $now 
  236: 		    && $curRes->completable()) {
  237:                         
  238:                     $foundDoableProblem = 1;
  239: 
  240:                     if (!defined($minimumduedate)
  241:                         || $thisduedate<$minimumduedate) {
  242: 			# Pop open all previous maps
  243: 			my $stack = $iterator->getStack();
  244: 			pop @$stack; # last resource in the stack is the problem
  245: 			# itself, which we don't need in the map stack
  246: 			my @mapPcs = map {$_->map_pc()} @$stack;
  247: 			$env{'form.filter'} = join(',', @mapPcs);
  248: 			
  249: 			# Mark as both "here" and "jump"
  250: 			$env{'form.postsymb'} = $curRes->symb();
  251:                         $minimumduedate=$thisduedate;
  252: 		    }
  253:                 }
  254:             }
  255:         }
  256: 
  257:         # If we found no problems, print a note to that effect.
  258:         if (!$foundDoableProblem) {
  259:             $r->print("<font size='+2'>"
  260:                      .&mt("All homework assignments have been completed.")
  261:                      ."</font><br /><br />");
  262:         }
  263:     } else {
  264: 	&Apache::lonnavmaps::add_linkitem(\%toplinkitems,'firsthomework',
  265: 					  'location.href="navmaps?jumpToFirstHomework"',
  266: 					  "Show my first due problem");
  267:     }
  268: 
  269:     my $suppressEmptySequences = 0;
  270:     my $filterFunc = undef;
  271:     my $resource_no_folder_link = 0;
  272: 
  273:     # Display only due homework.
  274:     my $showOnlyHomework = 0;
  275:     if ($env{'form.showOnlyHomework'} eq "1") {
  276:         $showOnlyHomework = 1;
  277:         $suppressEmptySequences = 1;
  278:         $filterFunc = sub { my $res = shift; 
  279:                             return $res->completable() || $res->is_map();
  280:                         };
  281: 	&Apache::lonnavmaps::add_linkitem(\%toplinkitems,'everything',
  282: 					  'location.href="navmaps?sort='.$env{'form.sort'}.'"',
  283: 					  "Show everything");
  284:         $r->print("<p><font size='+2'>".&mt("Uncompleted Problems")."</font></p>");
  285:         $env{'form.filter'} = '';
  286:         $env{'form.condition'} = 1;
  287: 	$resource_no_folder_link = 1;
  288:     } else {
  289: 	&Apache::lonnavmaps::add_linkitem(\%toplinkitems,'uncompleted',
  290: 					  'location.href="navmaps?sort='.$env{'form.sort'}.
  291: 					  '&showOnlyHomework=1"',
  292: 					  "Show only uncompleted problems");
  293:     }
  294: 
  295:     my %selected=($env{'form.sort'} => 'selected=on');
  296:     my $sort_html=("<form>
  297:                  <nobr>
  298:                     <input type=\"hidden\" name=\"showOnlyHomework\" value=\"".$env{'form.showOnlyHomework'}."\" />
  299:                     <input type=\"submit\" value=\"".&mt('Sort by:')."\" />
  300:                     <select name=\"sort\">
  301:                        <option value=\"default\" $selected{'default'}>".&mt('Default')."</option>
  302:                        <option value=\"title\"   $selected{'title'}  >".&mt('Title')."</option>
  303:                        <option value=\"duedate\" $selected{'duedate'}>".&mt('Duedate')."</option>
  304:                        <option value=\"discussion\" $selected{'discussion'}>".&mt('Has New Discussion')."</option>
  305:                     </select>
  306:                  </nobr>
  307:                </form>");
  308:     # renderer call
  309:     my $renderArgs = { 'cols' => [0,1,2,3],
  310: 		       'sort' => $env{'form.sort'},
  311:                        'url' => '/adm/navmaps',
  312:                        'navmap' => $navmap,
  313:                        'suppressNavmap' => 1,
  314:                        'suppressEmptySequences' => $suppressEmptySequences,
  315:                        'filterFunc' => $filterFunc,
  316: 		       'resource_no_folder_link' => $resource_no_folder_link,
  317: 		       'sort_html'=> $sort_html,
  318:                        'r' => $r,
  319:                        'caller' => 'navmapsdisplay',
  320:                        'linkitems' => \%toplinkitems};
  321:     my $render = &Apache::lonnavmaps::render($renderArgs);
  322: 
  323:     # If no resources were printed, print a reassuring message so the
  324:     # user knows there was no error.
  325:     if ($renderArgs->{'counter'} == 0) {
  326:         if ($showOnlyHomework) {
  327:             $r->print("<p><font size='+1'>".&mt("All homework is currently completed.")."</font></p>");
  328:         } else { # both jumpToFirstHomework and normal use the same: course must be empty
  329:             $r->print("<p><font size='+1'>".&mt("This course is empty.")."</font></p>");
  330:         }
  331:     }
  332:     #my $td=&tv_interval($t0);
  333:     #$r->print("<br />$td");
  334: 
  335:     $r->print(&Apache::loncommon::end_page());
  336:     $r->rflush();
  337: 
  338:     return OK;
  339: }
  340: 
  341: sub launch_win {
  342:     my ($mode,$script,$toplinkitems,$firsttime)=@_;
  343:     my $result;
  344:     if ($script ne 'no') {
  345: 	$result.='<script type="text/javascript">';
  346:     }
  347:     if ($firsttime) {
  348: 	$result.='function launch_navmapwin() {
  349:                  newWindow=open(\'/adm/navmaps?launchExternalRoles\',\'loncapanav\',\'width=400,height=600,scrollbars=1\');
  350:                }';
  351:     } else {
  352: 	$result.='function launch_navmapwin() {
  353:                  newWindow=open(\'/adm/navmaps?launchExternal\',\'loncapanav\',\'width=400,height=600,scrollbars=1\');
  354:                }';
  355:     }
  356:     if ($mode eq 'now') {
  357: 	$result.="\nlaunch_navmapwin();\n";
  358:     }
  359:     if ($script ne 'no') {
  360: 	$result.='</script>';
  361:     }
  362:     if ($mode eq 'link') {
  363: 	&Apache::lonnavmaps::add_linkitem($toplinkitems,'launchnav',
  364: 					  'launch_navmapwin()',
  365: 					  "Launch navigation window");
  366:     }
  367:     return $result;
  368: }
  369: 
  370: 1;
  371: __END__
  372: 

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