--- loncom/interface/lonnavmaps.pm 2002/11/26 14:45:24 1.115
+++ loncom/interface/lonnavmaps.pm 2002/12/02 14:20:24 1.120
@@ -2,7 +2,7 @@
# The LearningOnline Network with CAPA
# Navigate Maps Handler
#
-# $Id: lonnavmaps.pm,v 1.115 2002/11/26 14:45:24 bowersj2 Exp $
+# $Id: lonnavmaps.pm,v 1.120 2002/12/02 14:20:24 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('
');
@@ -208,8 +249,6 @@ sub handler {
# Is this a new-style course? If so, we want to suppress showing the top-level
# maps in their own folders, in favor of "inlining" them.
my $topResource = $navmap->getById("0.0");
- my $inlineTopLevelMaps = $topResource->src() =~ m|^/uploaded/.*default\.sequence$|;
- my $inlinedelta = $inlineTopLevelMaps? -1 : 0;
# Begin the HTML table
# four cols: resource + indent, chat+feedback, icon, text string
@@ -221,35 +260,33 @@ 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;
-
- while ($depth > 0) {
- if ($curRes == $mapIterator->BEGIN_MAP()) { $depth++; }
- if ($curRes == $mapIterator->END_MAP()) { $depth--; }
+ my $foundJump = ($jumpType == $NOTHING); # look for jump point if we have one
+ my $looped = 0;
- if (ref($curRes)) { $counter++; }
+ $r->print($hereType);
- 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.
+ # We only need to do this if we need to open the maps to show the
+ # 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--; }
- # 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) ||
+ (ref($curRes) && $hereType == $URL && $curRes->src() eq $here)) {
+ my $mapStack = $mapIterator->getStack();
# Ensure the parent maps are open
for my $map (@{$mapStack}) {
@@ -261,16 +298,33 @@ sub handler {
}
$ENV{'form.alreadyHere'} = 1;
}
-
- # Preprocessing: If we're inlining nav maps into the top-level display,
- # make sure we show this map!
- if ($inlineTopLevelMaps && ref($curRes) && $curRes->is_map &&
- scalar(@{$mapStack}) == 1) {
- if ($condition) {
- undef $filterHash{$curRes->map_pc()};
- } else {
- $filterHash{$curRes->map_pc()} = 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();
@@ -284,6 +338,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
@@ -298,11 +353,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()) {
@@ -327,11 +377,11 @@ sub handler {
next; # if yes, then just ignore this resource
}
- if (ref($curRes) && $curRes->src()) {
+ if (ref($curRes)) {
my $deltalevel = $isNewBranch? 1 : 0; # reserves space for branch icon
- if ($indentLevel - $deltalevel + $inlinedelta < 0) {
+ if ($indentLevel - $deltalevel < 0) {
# If this would be at a negative depth (top-level maps in
# new-style courses, we want to suppress their title display)
# then ignore it.
@@ -472,7 +522,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 = "";
}
@@ -500,15 +553,16 @@ sub handler {
my $backgroundColor = $backgroundColors[$rowNum % scalar(@backgroundColors)];
# FIRST COL: The resource indentation, branch icon, name, and anchor
- $r->print(" \n");
+ $r->print(" |
\n");
# Print the anchor if necessary
- if ($counter == $currentUrlIndex - $currentUrlDelta) {
- $r->print('');
+ if ($counter == $currentJumpIndex - $currentJumpDelta ) {
+ $r->print('');
+ $displayedJumpMarker = 1;
}
# print indentation
- for (my $i = 0; $i < $indentLevel - $deltalevel + $inlinedelta; $i++) {
+ for (my $i = 0; $i < $indentLevel - $deltalevel; $i++) {
$r->print($indentString);
}
@@ -518,8 +572,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;
}
@@ -534,10 +590,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");
@@ -607,7 +663,14 @@ sub handler {
$curRes = $mapIterator->next();
}
- $r->print("