--- loncom/interface/lonnavmaps.pm 2003/02/06 22:58:12 1.139 +++ loncom/interface/lonnavmaps.pm 2003/02/13 23:44:30 1.143 @@ -2,7 +2,7 @@ # The LearningOnline Network with CAPA # Navigate Maps Handler # -# $Id: lonnavmaps.pm,v 1.139 2003/02/06 22:58:12 bowersj2 Exp $ +# $Id: lonnavmaps.pm,v 1.143 2003/02/13 23:44:30 bowersj2 Exp $ # # Copyright Michigan State University Board of Trustees # @@ -56,21 +56,23 @@ sub NOTHING { return 3; } # Some data +my $resObj = "Apache::lonnavmaps::resource"; + # Keep these mappings in sync with lonquickgrades, which uses the colors # instead of the icons. my %statusIconMap = - ( Apache::lonnavmaps::resource->NETWORK_FAILURE => '', - Apache::lonnavmaps::resource->NOTHING_SET => '', - Apache::lonnavmaps::resource->CORRECT => 'navmap.correct.gif', - Apache::lonnavmaps::resource->EXCUSED => 'navmap.correct.gif', - Apache::lonnavmaps::resource->PAST_DUE_NO_ANSWER => 'navmap.wrong.gif', - Apache::lonnavmaps::resource->PAST_DUE_ANSWER_LATER => 'navmap.wrong.gif', - Apache::lonnavmaps::resource->ANSWER_OPEN => 'navmap.wrong.gif', - Apache::lonnavmaps::resource->OPEN_LATER => '', - Apache::lonnavmaps::resource->TRIES_LEFT => 'navmap.open.gif', - Apache::lonnavmaps::resource->INCORRECT => 'navmap.wrong.gif', - Apache::lonnavmaps::resource->OPEN => 'navmap.open.gif', - Apache::lonnavmaps::resource->ATTEMPTED => 'navmap.open.gif' ); + ( $resObj->NETWORK_FAILURE => '', + $resObj->NOTHING_SET => '', + $resObj->CORRECT => 'navmap.correct.gif', + $resObj->EXCUSED => 'navmap.correct.gif', + $resObj->PAST_DUE_NO_ANSWER => 'navmap.wrong.gif', + $resObj->PAST_DUE_ANSWER_LATER => 'navmap.wrong.gif', + $resObj->ANSWER_OPEN => 'navmap.wrong.gif', + $resObj->OPEN_LATER => '', + $resObj->TRIES_LEFT => 'navmap.open.gif', + $resObj->INCORRECT => 'navmap.wrong.gif', + $resObj->OPEN => 'navmap.open.gif', + $resObj->ATTEMPTED => 'navmap.open.gif' ); my %iconAltTags = ( 'navmap.correct.gif' => 'Correct', @@ -79,17 +81,17 @@ my %iconAltTags = # Defines a status->color mapping, null string means don't color my %colormap = - ( Apache::lonnavmaps::resource->NETWORK_FAILURE => '', - Apache::lonnavmaps::resource->CORRECT => '', - Apache::lonnavmaps::resource->EXCUSED => '#3333FF', - Apache::lonnavmaps::resource->PAST_DUE_ANSWER_LATER => '', - Apache::lonnavmaps::resource->PAST_DUE_NO_ANSWER => '', - Apache::lonnavmaps::resource->ANSWER_OPEN => '#006600', - Apache::lonnavmaps::resource->OPEN_LATER => '', - Apache::lonnavmaps::resource->TRIES_LEFT => '', - Apache::lonnavmaps::resource->INCORRECT => '', - Apache::lonnavmaps::resource->OPEN => '', - Apache::lonnavmaps::resource->NOTHING_SET => '' ); + ( $resObj->NETWORK_FAILURE => '', + $resObj->CORRECT => '', + $resObj->EXCUSED => '#3333FF', + $resObj->PAST_DUE_ANSWER_LATER => '', + $resObj->PAST_DUE_NO_ANSWER => '', + $resObj->ANSWER_OPEN => '#006600', + $resObj->OPEN_LATER => '', + $resObj->TRIES_LEFT => '', + $resObj->INCORRECT => '', + $resObj->OPEN => '', + $resObj->NOTHING_SET => '' ); # And a special case in the nav map; what to do when the assignment # is not yet done and due in less then 24 hours my $hurryUpColor = "#FF0000"; @@ -117,8 +119,6 @@ sub handler { sub real_handler { my $r = shift; - &Apache::loncommon::get_unprocessed_cgi($ENV{QUERY_STRING}); - # Handle header-only request if ($r->header_only) { if ($ENV{'browser.mathml'}) { @@ -164,83 +164,6 @@ sub real_handler { # Now that we've displayed some stuff to the user, init the navmap $navmap->init(); - $r->print('
Key: | '); - - # Print discussions and feedback header - if ($navmap->{LAST_CHECK}) { - $r->print(' '.
- '![]() | '.
- '![]() '. - ' | ');
- } else {
- $r->print(' '.
- '![]() | '.
- ' ![]() | ');
- }
- $r->print('
";
-
+
+ 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'};
}
@@ -913,39 +758,226 @@ 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'};
- # 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 $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
- my $r = $args->{'r'};
+
+ # 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; }
+ my $filterFunc = setDefault($args->{'filterFunc'},
+ sub {return 1;});
+
+ # Print key?
+ if ($printKey) {
+ $result .= '
\n"; + } + + if ($r) { + $r->print($result); + $r->rflush(); + $result = ""; + } # End parameter setting # Data - my $result .= ' |