: If true, print the "Close all folders" or "open all folders" links. Default is true.
+
=back
=head2 Additional Info
@@ -1076,7 +561,6 @@ sub render_resource {
# If this is a new branch, label it so
if ($params->{'isNewBranch'}) {
$newBranchText = "
";
- $params->{'isNewBranch'} = 0;
}
# links to open and close the folder
@@ -1113,7 +597,8 @@ sub render_resource {
. $params->{'hereType'} . '&here=' .
&Apache::lonnet::escape($params->{'here'}) .
'&jumpType=' . SYMB() . '&jump=' .
- &Apache::lonnet::escape($params->{$resource->symb()}) . "'>";
+ &Apache::lonnet::escape($resource->symb()) .
+ "&folderManip=1'>";
}
if ($resource->randomout()) {
@@ -1122,10 +607,12 @@ sub render_resource {
# We're done preparing and finally ready to start the rendering
my $result = "";
-
+
+ my $indentLevel = $params->{'indentLevel'};
+ if ($newBranchText) { $indentLevel--; }
+
# print indentation
- for (my $i = 0; $i < $params->{'indentLevel'} -
- $params->{'deltaLevel'}; $i++) {
+ for (my $i = 0; $i < $indentLevel; $i++) {
$result .= $params->{'indentString'};
}
@@ -1269,44 +756,229 @@ sub setDefault {
sub render {
my $args = shift;
-
+ &Apache::loncommon::get_unprocessed_cgi($ENV{QUERY_STRING});
+ my $result = '';
+
# Configure the renderer.
my $cols = $args->{'cols'};
if (!defined($cols)) {
# no columns, no nav maps.
return '';
}
- my $it = $args->{'iterator'};
- if (!defined($it)) {
- # no iterator, no nav map.
- return '';
+ my $mustCloseNavMap = 0;
+ my $navmap;
+ if (defined($args->{'navmap'})) {
+ $navmap = $args->{'navmap'};
}
-
- my $showParts = setDefault($args->{'showParts'}, 1);
- my $condenseParts = setDefault($args->{'condenseParts'}, 1);
+
+ my $queryString = $args->{'queryString'};
my $jumpToURL = $args->{'jumpToURL'};
my $jumpToSymb = $args->{'jumpToSymb'};
+ my $jumpType;
my $hereURL = $args->{'hereURL'};
my $hereSymb = $args->{'hereSymb'};
-
- #if (defined($jumpToURL)) {
- # $args->{'jumpType'} =
+ my $hereType;
+ my $here;
+ my $jump;
+ my $currentJumpIndex = setDefault($args->{'currentJumpIndex'}, 0);
+ my $currentJumpDelta = 2; # change this to change how many resources are displayed
+ # before the current resource when using #current
+
+ # If we were passed 'here' information, we are not rendering
+ # after a folder manipulation, and we were not passed an
+ # iterator, make sure we open the folders to show the "here"
+ # marker
+ my $filterHash = {};
+ # Figure out what we're not displaying
+ foreach (split(/\,/, $ENV{"form.filter"})) {
+ if ($_) {
+ $filterHash->{$_} = "1";
+ }
+ }
+
+ my $condition = 0;
+ if ($ENV{'form.condition'}) {
+ $condition = 1;
+ }
+
+ if (!$ENV{'form.folderManip'} && !defined($args->{'iterator'})) {
+ # Step 1: Check to see if we have a navmap
+ if (!defined($navmap)) {
+ $navmap = Apache::lonnavmaps::navmap->new(
+ $ENV{"request.course.fn"}.".db",
+ $ENV{"request.course.fn"}."_parms.db", 1, 1);
+ $mustCloseNavMap = 1;
+ }
+ $navmap->init();
+
+ # Step two: Locate what kind of here marker is necessary
+ # Determine where the "here" marker is and where the screen jumps to.
+
+ # 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();
+ }
+ # Step three: Ensure the folders are open
+ my $mapIterator = $navmap->getIterator(undef, undef, undef, 1);
+ my $depth = 1;
+ $mapIterator->next(); # discard the first BEGIN_MAP
+ my $curRes = $mapIterator->next();
+ my $counter = 0;
+ my $found = 0;
+
+ # 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 && !$found) {
+ if ($curRes == $mapIterator->BEGIN_MAP()) { $depth++; }
+ if ($curRes == $mapIterator->END_MAP()) { $depth--; }
+
+ if (ref($curRes) &&
+ ($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}) {
+ if ($condition) {
+ undef $filterHash->{$map->map_pc()};
+ } else {
+ $filterHash->{$map->map_pc()} = 1;
+ }
+ }
+ $found = 1;
+ }
+
+ $curRes = $mapIterator->next();
+ }
+
+ # Since we changed the folders, (re-)locate the jump point, if any
+ $mapIterator = $navmap->getIterator(undef, undef, $filterHash, 0);
+ $depth = 1;
+ $mapIterator->next();
+ $curRes = $mapIterator->next();
+ my $foundJump = 0;
+
+ 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))) {
+
+ # 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();
+ }
+
+ }
+ if ( !defined($args->{'iterator'}) && $ENV{'form.folderManip'} ) { # 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'};
+ }
+
+ my $it = $args->{'iterator'};
+ if (!defined($it)) {
+ # Construct a default iterator based on $ENV{'form.'} information
+
+ # Step 1: Check to see if we have a navmap
+ if (!defined($navmap)) {
+ $navmap = Apache::lonnavmaps::navmap->new(
+ $ENV{"request.course.fn"}.".db",
+ $ENV{"request.course.fn"}."_parms.db", 1, 1);
+ $mustCloseNavMap = 1;
+ }
+ # Paranoia: Make sure it's ready
+ $navmap->init();
+
+ $args->{'iterator'} = $it = $navmap->getIterator(undef, undef, $filterHash, $condition);
+ }
+
+ my $showParts = setDefault($args->{'showParts'}, 1);
+ my $condenseParts = setDefault($args->{'condenseParts'}, 1);
+ # 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 $r = $args->{'r'};
+ my $printKey = $args->{'printKey'};
+ my $printCloseAll = $args->{'printCloseAll'};
+ if (!defined($printCloseAll)) { $printCloseAll = 1; }
+
+ # Print key?
+ if ($printKey) {
+ $result .= '';
+ }
+
+ if ($printCloseAll) {
+ if ($condition) {
+ $result.="Close All Folders";
+ } else {
+ $result.="Open All Folders";
+ }
+ }
+
+ if ($r) {
+ $r->print($result);
+ $r->rflush();
+ $result = "";
+ }
# End parameter setting
# Data
- my $result .= '' ."\n";
+ $result .= '' ."\n";
my $res = "Apache::lonnavmaps::resource";
my %condenseStatuses =
( $res->NETWORK_FAILURE => 1,
$res->NOTHING_SET => 1,
$res->CORRECT => 1 );
my @backgroundColors = ("#FFFFFF", "#F6F6F6");
- 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 $currentJumpDelta = 2; # change this to change how many resources are displayed
- # before the current resource when using #current
# Shared variables
$args->{'counter'} = 0; # counts the rows
@@ -1325,6 +997,10 @@ sub render {
my $in24Hours = $now + 24 * 60 * 60;
my $rownum = 0;
+ # export "here" marker information
+ $args->{'here'} = $here;
+ $args->{'hereType'} = $hereType;
+
while ($depth > 0) {
if ($curRes == $it->BEGIN_MAP()) { $depth++; }
if ($curRes == $it->END_MAP()) { $depth--; }
@@ -1350,15 +1026,6 @@ sub render {
}
$args->{'counter'}++;
- # reserve space for branch symbol
- $args->{'deltalevel'} = $args->{'isNewBranch'}? 1 : 0;
- if ($args->{'indentLevel'} - $args->{'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.
- $curRes = $it->next();
- next;
- }
# Does it have multiple parts?
$args->{'multipart'} = 0;
@@ -1449,38 +1116,52 @@ sub render {
# Now, display each column.
foreach my $col (@$cols) {
+ my $colHTML = '';
+ if (ref($col)) {
+ $colHTML .= &$col($curRes, $part, $args);
+ } else {
+ $colHTML .= &{$preparedColumns[$col]}($curRes, $part, $args);
+ }
# If this is the first column and it's time to print
# the anchor, do so
if ($col == $cols->[0] &&
$args->{'counter'} == $args->{'currentJumpIndex'} -
- $args->{'currentJumpDelta'}) {
- $result .= '';
+ $currentJumpDelta) {
+ # Jam the anchor after the tag;
+ # necessary for valid HTML (which Mozilla requires)
+ $colHTML =~ s/\>/\>\/;
$displayedJumpMarker = 1;
}
-
-
- if (ref($col)) {
- $result .= &$col($curRes, $part, $args);
- } else {
- $result .= &{$preparedColumns[$col]}($curRes, $part, $args);
- }
-
+ $result .= $colHTML . "\n";
}
-
- $result .= " \n";
+ $result .= " \n";
+ $args->{'isNewBranch'} = 0;
+ }
+
+ if ($r && $rownum % 20 == 0) {
+ $r->print($result);
+ $result = "";
+ $r->rflush();
}
-
$curRes = $it->next();
}
# Print out the part that jumps to #curloc if it exists
- if ($args->{"displayedJumpMarker"}) {
- $result .= "\n";
+ if ($displayedJumpMarker) {
+ $result .= "\n";
}
$result .= " | ";
+
+ if ($r) {
+ $r->print($result);
+ $result = "";
+ $r->rflush();
+ }
+
+ if ($mustCloseNavMap) { $navmap->untieHashes(); }
return $result;
}
@@ -1550,6 +1231,7 @@ sub new {
$self->{HASH_TIED} = 1;
$self->{NAV_HASH} = \%navmaphash;
$self->{PARM_HASH} = \%parmhash;
+ $self->{INITED} = 0;
bless($self);
@@ -1558,6 +1240,7 @@ sub new {
sub init {
my $self = shift;
+ if ($self->{INITED}) { return; }
# If the course opt hash and the user opt hash should be generated,
# generate them
@@ -1663,6 +1346,7 @@ sub init {
}
$self->{PARM_CACHE} = {};
+ $self->{INITED} = 1;
}
# Internal function: Takes a key to look up in the nav hash and implements internal
@@ -2228,7 +1912,9 @@ sub next {
# If this is a blank resource, don't actually return it.
# Should you ever find you need it, make sure to add an option to the code
# that you can use; other things depend on this behavior.
- if (!$self->{HERE}->src() || !$self->{HERE}->browsePriv()) {
+ my $browsePriv = $self->{HERE}->browsePriv();
+ if (!$self->{HERE}->src() ||
+ (!($browsePriv eq 'F') && !($browsePriv eq '2')) ) {
return $self->next();
}
@@ -2312,7 +1998,7 @@ sub new {
# A hash, used as a set, of resource already seen
$self->{ALREADY_SEEN} = shift;
- if (!defined($self->{ALREADY_SEEN})) { $self->{ALREADY_SEEN} = {} };
+ if (!defined($self->{ALREADY_SEEN})) { $self->{ALREADY_SEEN} = {} };
$self->{CONDITION} = shift;
$self->{DIRECTION} = shift || FORWARD();
@@ -2435,7 +2121,7 @@ A resource object encapsulates a resourc
A resource only makes sense in the context of a navmap, as some of the data is stored in the navmap object.
-You will probably never need to instantiate this object directly. Use Apache::lonnavmap::navmap, and use the "start" method to obtain the starting resource.
+You will probably never need to instantiate this object directly. Use Apache::lonnavmaps::navmap, and use the "start" method to obtain the starting resource.
=head2 Public Members
@@ -2566,8 +2252,6 @@ These methods are shortcuts to deciding
=item * B: Returns true if the resource is a page.
-=item * B: Returns true if the resource is a problem.
-
=item * B: Returns true if the resource is a sequence.
=back
|