--- loncom/interface/lonnavmaps.pm 2002/11/26 17:01:29 1.117 +++ loncom/interface/lonnavmaps.pm 2002/12/02 14:04:52 1.118 @@ -2,7 +2,7 @@ # The LearningOnline Network with CAPA # Navigate Maps Handler # -# $Id: lonnavmaps.pm,v 1.117 2002/11/26 17:01:29 bowersj2 Exp $ +# $Id: lonnavmaps.pm,v 1.118 2002/12/02 14:04:52 bowersj2 Exp $ # # Copyright Michigan State University Board of Trustees # @@ -48,6 +48,11 @@ use POSIX qw (floor strftime); sub handler { my $r = shift; + real_handler($r); +} + +sub real_handler { + my $r = shift; &Apache::loncommon::get_unprocessed_cgi($ENV{QUERY_STRING}); @@ -84,7 +89,7 @@ sub handler { } $r->print("\n"); - $r->print("Navigate Course Contents"); + $r->print("Navigate Course Contents"); # Header $r->print(&Apache::loncommon::bodytag('Navigate Course Contents','', @@ -116,22 +121,58 @@ sub handler { $condition = 1; } - my $currenturl = $ENV{'form.postdata'}; - $currenturl=~s/^http\:\/\///; - $currenturl=~s/^[^\/]+//; + # Determine where the "here" marker is and where the screen jumps to. + my $SYMB = 1; my $URL = 2; my $NOTHING = 3; # symbolic constants + my $hereType; # the type of marker, $SYMB, $URL, or $NOTHING + my $here; # the actual URL or SYMB for the here marker + my $jumpType; # The type of the thing we have a jump for, $SYMB or $URL + my $jump; # the SYMB/URL of the resource we need to jump to + + if ( $ENV{'form.alreadyHere'} ) { # we came from a user's manipulation of the nav page + # If this is a click on a folder or something, we want to preserve the "here" + # from the querystring, and get the new "jump" marker + $hereType = $ENV{'form.hereType'}; + $here = $ENV{'form.here'}; + $jumpType = $ENV{'form.jumpType'} || $NOTHING; + $jump = $ENV{'form.jump'}; + } else { # the user is visiting the nav map from the remote + # We're coming from the remote. We have either a url, a symb, or nothing, + # and we need to figure out what. + # Preference: Symb + + if ($ENV{'form.symb'}) { + $hereType = $jumpType = $SYMB; + $here = $jump = $ENV{'form.symb'}; + } elsif ($ENV{'form.postdata'}) { + # couldn't find a symb, is there a URL? + my $currenturl = $ENV{'form.postdata'}; + $currenturl=~s/^http\:\/\///; + $currenturl=~s/^[^\/]+//; + + $hereType = $jumpType = $URL; + $here = $jump = $currenturl; + } else { + # Nothing + $hereType = $jumpType = $NOTHING; + } + } + # alreadyHere allows us to only open the maps necessary to view # the current location once, while at the same time remembering # the current location. Without that check, the user would never # be able to close those maps; the user would close it, and the # currenturl scan would re-open it. - my $queryAdd = "postdata=" . &Apache::lonnet::escape($currenturl) . - "&alreadyHere=1"; + my $queryAdd = "&alreadyHere=1"; if ($condition) { - $r->print("Close All Folders"); + $r->print("Close All Folders"); } else { - $r->print("Open All Folders"); + $r->print("Open All Folders"); } $r->print('
 '); @@ -219,37 +260,30 @@ sub handler { # Here's a simple example of the iterator. # Preprocess the map: Look for current URL, force inlined maps to display - my $mapIterator = $navmap->getIterator(undef, undef, \%filterHash, 1); + my $mapIterator = $navmap->getIterator(undef, undef, undef, 1); my $found = 0; my $depth = 1; - my $currentUrlIndex = 0; # keeps track of when the current resource is found, + my $currentJumpIndex = 0; # keeps track of when the current resource is found, # so we can back up a few and put the anchor above the # current resource - my $currentUrlDelta = 5; # change this to change how many resources are displayed + my $currentJumpDelta = 2; # change this to change how many resources are displayed # before the current resource when using #current $mapIterator->next(); # discard the first BEGIN_MAP my $curRes = $mapIterator->next(); my $counter = 0; + my $foundJump = ($jumpType == $NOTHING); # look for jump point if we have one + my $looped = 0; # We only need to do this if we need to open the maps to show the - # current position + # current position. This will change the counter so we can't count + # for the jump marker with this loop. while ($depth > 0 && !$ENV{'form.alreadyHere'}) { if ($curRes == $mapIterator->BEGIN_MAP()) { $depth++; } if ($curRes == $mapIterator->END_MAP()) { $depth--; } - - if (ref($curRes)) { $counter++; } - - my $mapStack = $mapIterator->getStack(); - if ($currenturl && !$ENV{'form.alreadyHere'} && ref($curRes) && - $curRes->src() eq $currenturl) { - # If this is the correct resource, be sure to - # show it by making sure the containing maps - # are open. - - # This is why we have to use the main iterator instead of the - # potentially faster DFS: The count has to be the same, so - # the order has to be the same, which DFS won't give us. - $currentUrlIndex = $counter; + if (ref($curRes) && !$ENV{'form.alreadyHere'} && + ($hereType == $SYMB && $curRes->symb() eq $here) || + ($hereType == $URL && $curRes->src() eq $here)) { + my $mapStack = $mapIterator->getStack(); # Ensure the parent maps are open for my $map (@{$mapStack}) { @@ -261,7 +295,35 @@ sub handler { } $ENV{'form.alreadyHere'} = 1; } - + $looped = 1; + + $curRes = $mapIterator->next(); + } + + $mapIterator = $navmap->getIterator(undef, undef, \%filterHash, 0); + $depth = 1; + $mapIterator->next(); + $curRes = $mapIterator->next(); + + while ($depth > 0 && !$foundJump) { + if ($curRes == $mapIterator->BEGIN_MAP()) { $depth++; } + if ($curRes == $mapIterator->END_MAP()) { $depth--; } + if (ref($curRes)) { $counter++; } + + if (ref($curRes) && + (($jumpType == $SYMB && $curRes->symb() eq $jump) || + ($jumpType == $URL && $curRes->src() eq $jump))) { + # If this is the correct resource, be sure to + # show it by making sure the containing maps + # are open. + + # This is why we have to use the main iterator instead of the + # potentially faster DFS: The count has to be the same, so + # the order has to be the same, which DFS won't give us. + $currentJumpIndex = $counter; + $foundJump = 1; + } + $curRes = $mapIterator->next(); } @@ -273,6 +335,7 @@ sub handler { my $now = time(); my $in24Hours = $now + 24 * 60 * 60; my $displayedHereMarker = 0; + my $displayedJumpMarker = 0; # We know the first thing is a BEGIN_MAP (see "$self->{STARTED}" # code in iterator->next), so ignore the first one @@ -287,11 +350,6 @@ sub handler { $counter = 0; - # Print the 'current' anchor here if it would fall off the top - if ($currentUrlIndex - $currentUrlDelta < 0) { - $r->print(''); - } - while ($depth > 0) { if ($curRes == $mapIterator->BEGIN_MAP() || $curRes == $mapIterator->BEGIN_BRANCH()) { @@ -461,7 +519,10 @@ sub handler { $linkopen .= ($nowOpen xor $condition) ? addToFilter(\%filterHash, $mapId) : removeFromFilter(\%filterHash, $mapId); - $linkopen .= "&condition=$condition&$queryAdd\">"; + $linkopen .= "&condition=$condition&$queryAdd" . + "&hereType=$hereType&here=" . + Apache::lonnet::escape($here) . "&jumpType=$SYMB&" . + "jump=" . Apache::lonnet::escape($curRes->symb()) ."\">"; $linkclose = ""; } @@ -492,8 +553,9 @@ sub handler { $r->print(" \n"); # Print the anchor if necessary - if ($counter == $currentUrlIndex - $currentUrlDelta) { - $r->print(''); + if ($counter == $currentJumpIndex - $currentJumpDelta ) { + $r->print(''); + $displayedJumpMarker = 1; } # print indentation @@ -507,8 +569,10 @@ sub handler { my $curMarkerEnd = ""; # Is this the current resource? - if ($curRes->src() eq $currenturl && !$displayedHereMarker) { - $curMarkerBegin = '> '; + if (!$displayedHereMarker && + (($hereType == $SYMB && $curRes->symb eq $here) || + ($hereType == $URL && $curRes->src eq $here))) { + $curMarkerBegin = '> '; $curMarkerEnd = ' <'; $displayedHereMarker = 1; } @@ -523,10 +587,10 @@ sub handler { $r->print(" $curMarkerBegin$title$partLabel $curMarkerEnd $nonLinkedText"); - if ($curRes->{RESOURCE_ERROR}) { - $r->print(&Apache::loncommon::help_open_topic ("Navmap_Host_Down", - 'Host down')); - } + #if ($curRes->{RESOURCE_ERROR}) { + # $r->print(&Apache::loncommon::help_open_topic ("Navmap_Host_Down", + # 'Host down')); + # } $r->print("\n"); @@ -596,7 +660,14 @@ sub handler { $curRes = $mapIterator->next(); } - $r->print(""); + $r->print(""); + + # Print out the part that jumps to #curloc if it exists + if ($displayedJumpMarker) { + $r->print(''); + } + + $r->print(""); $navmap->untieHashes();