--- loncom/interface/lonnavmaps.pm 2002/11/15 21:23:03 1.111
+++ loncom/interface/lonnavmaps.pm 2002/11/26 14:45:24 1.115
@@ -2,7 +2,7 @@
# The LearningOnline Network with CAPA
# Navigate Maps Handler
#
-# $Id: lonnavmaps.pm,v 1.111 2002/11/15 21:23:03 bowersj2 Exp $
+# $Id: lonnavmaps.pm,v 1.115 2002/11/26 14:45:24 bowersj2 Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -158,10 +158,10 @@ sub handler {
my %colormap =
( $res->NETWORK_FAILURE => '',
$res->CORRECT => '',
- $res->EXCUSED => '#BBBBFF',
+ $res->EXCUSED => '#3333FF',
$res->PAST_DUE_ANSWER_LATER => '',
$res->PAST_DUE_NO_ANSWER => '',
- $res->ANSWER_OPEN => '#CCFFCC',
+ $res->ANSWER_OPEN => '#006600',
$res->OPEN_LATER => '',
$res->TRIES_LEFT => '',
$res->INCORRECT => '',
@@ -171,6 +171,8 @@ sub handler {
# is not yet done and due in less then 24 hours
my $hurryUpColor = "#FF0000";
+ # Keep these mappings in sync with lonquickgrades, which uses the colors
+ # instead of the icons.
my %statusIconMap =
( $res->NETWORK_FAILURE => '',
$res->NOTHING_SET => '',
@@ -207,6 +209,7 @@ sub handler {
# 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
@@ -288,7 +291,6 @@ sub handler {
$condition);
$mapIterator->next();
$curRes = $mapIterator->next();
- my $deltadepth = 0;
$depth = 1;
my @backgroundColors = ("#FFFFFF", "#F6F6F6");
@@ -302,15 +304,6 @@ sub handler {
}
while ($depth > 0) {
- # If this is an inlined map, cancel the shift to the right,
- # which has the effect of making the map look inlined
- if ($inlineTopLevelMaps && scalar(@{$mapIterator->getStack()}) == 1 &&
- ref($curRes) && $curRes->is_map()) {
- $deltadepth = -1;
- $curRes = $mapIterator->next();
- next;
- }
-
if ($curRes == $mapIterator->BEGIN_MAP() ||
$curRes == $mapIterator->BEGIN_BRANCH()) {
$indentLevel++;
@@ -327,9 +320,6 @@ sub handler {
if (ref($curRes)) { $counter++; }
- if ($depth == 1) { $deltadepth = 0; } # we're done shifting, because we're
- # out of the inlined map
-
# Is this resource being ignored because it is in a random-out
# map and it was not selected?
if (ref($curRes) && !advancedUser() && $curRes->randomout()) {
@@ -339,6 +329,16 @@ sub handler {
if (ref($curRes) && $curRes->src()) {
+ my $deltalevel = $isNewBranch? 1 : 0; # reserves space for branch icon
+
+ if ($indentLevel - $deltalevel + $inlinedelta < 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 = $mapIterator->next();
+ next;
+ }
+
# Step one: Decide which parts to show
my @parts = @{$curRes->parts()};
my $multipart = scalar(@parts) > 1;
@@ -424,7 +424,6 @@ sub handler {
# For each part we intend to display...
foreach my $part (@parts) {
- my $deltalevel = 0; # for inserting the branch icon
my $nonLinkedText = ""; # unlinked stuff after title
my $stack = $mapIterator->getStack();
@@ -446,7 +445,6 @@ sub handler {
if ($isNewBranch) {
$newBranchText = "
";
$isNewBranch = 0;
- $deltalevel = 1; # reserves space for the branch icon
}
# links to open and close the folders
@@ -482,27 +480,13 @@ sub handler {
my $colorizer = "";
my $color;
if ($curRes->is_problem()) {
- my $status = $curRes->status($part);
- $color = $colormap{$status};
+ $color = $colormap{$curRes->status};
- # Special case in the navmaps: If in less then
- # 24 hours, give it a bit of urgency
- if (($status == $curRes->OPEN() || $status == $curRes->ATTEMPTED() ||
- $status == $curRes->TRIES_LEFT())
- && $curRes->duedate() &&
- $curRes->duedate() < time()+(24*60*60) &&
- $curRes->duedate() > time()) {
- $color = $hurryUpColor;
- }
- # Special case: If this is the last try, and there is
- # more then one available, and it's not due yet, give a bit of urgency
- my $tries = $curRes->tries($part);
- my $maxtries = $curRes->maxtries($part);
- if ($tries && $maxtries && $maxtries > 1 &&
- $maxtries - $tries == 1 && $curRes->duedate() &&
- $curRes->duedate() > time()) {
+ if (dueInLessThen24Hours($curRes, $part) ||
+ lastTry($curRes, $part)) {
$color = $hurryUpColor;
}
+
if ($color ne "") {
$colorizer = "bgcolor=\"$color\"";
}
@@ -524,7 +508,7 @@ sub handler {
}
# print indentation
- for (my $i = 0; $i < $indentLevel - $deltalevel + $deltadepth; $i++) {
+ for (my $i = 0; $i < $indentLevel - $deltalevel + $inlinedelta; $i++) {
$r->print($indentString);
}
@@ -555,6 +539,8 @@ sub handler {
'Host down'));
}
+ $r->print("\n");
+
# SECOND COL: Is there text, feedback, errors??
my $discussionHTML = ""; my $feedbackHTML = "";
@@ -613,6 +599,9 @@ sub handler {
}
$r->print(" \n");
+
+ if (!($counter % 20)) { $r->rflush(); }
+ if ($counter == 2) { $r->rflush(); }
}
}
$curRes = $mapIterator->next();
@@ -730,6 +719,33 @@ sub getDescription {
}
}
+# Convenience function, so others can use it: Is the problem due in less then
+# 24 hours, and still can be done?
+
+sub dueInLessThen24Hours {
+ my $res = shift;
+ my $part = shift;
+ my $status = $res->status($part);
+
+ return ($status == $res->OPEN() || $status == $res->ATTEMPTED() ||
+ $status == $res->TRIES_LEFT()) &&
+ $res->duedate() && $res->duedate() < time()+(24*60*60) &&
+ $res->duedate() > time();
+}
+
+# Convenience function, so others can use it: Is there only one try remaining for the
+# part, with more then one try to begin with, not due yet and still can be done?
+sub lastTry {
+ my $res = shift;
+ my $part = shift;
+
+ my $tries = $res->tries($part);
+ my $maxtries = $res->maxtries($part);
+ return $tries && $maxtries && $maxtries > 1 &&
+ $maxtries - $tries == 1 && $res->duedate() &&
+ $res->duedate() > time();
+}
+
# This puts a human-readable name on the ENV variable.
sub advancedUser {
return $ENV{'user.adv'};
@@ -895,7 +911,6 @@ sub new {
&GDBM_READER(), 0640))) {
return undef;
}
- $self->{NAV_HASH} = \%navmaphash;
my %parmhash;
if (!(tie(%parmhash, 'GDBM_File', $self->{PARM_HASH_FILE},
@@ -904,10 +919,16 @@ sub new {
untie $self->{PARM_HASH};
return undef;
}
- $self->{PARM_HASH} = \%parmhash;
- $self->{HASH_TIED} = 1;
+
+ # Now copy the hashes for speed (?)
+ my %realnav; my %realparm;
+ foreach (%navmaphash) { $realnav{$_} = $navmaphash{$_}; }
+ foreach (%parmhash) { $realparm{$_} = $navmaphash{$_}; }
+ $self->{NAV_HASH} = \%realnav;
+ $self->{PARM_HASH} = \%realparm;
bless($self);
+ $self->untieHashes();
return $self;
}
@@ -1021,13 +1042,20 @@ sub init {
$self->{PARM_CACHE} = {};
}
+# Internal function: Takes a key to look up in the nav hash and implements internal
+# memory caching of that key.
+sub navhash {
+ my $self = shift; my $key = shift;
+ return $self->{NAV_HASH}->{$key};
+}
+
# Checks to see if coursemap is defined, matching test in old lonnavmaps
sub courseMapDefined {
my $self = shift;
my $uri = &Apache::lonnet::clutter($ENV{'request.course.uri'});
- my $firstres = $self->{NAV_HASH}->{"map_start_$uri"};
- my $lastres = $self->{NAV_HASH}->{"map_finish_$uri"};
+ my $firstres = $self->navhash("map_start_$uri");
+ my $lastres = $self->navhash("map_finish_$uri");
return $firstres && $lastres;
}
@@ -1107,8 +1135,8 @@ sub getById {
sub firstResource {
my $self = shift;
- my $firstResource = $self->{NAV_HASH}->{'map_start_' .
- &Apache::lonnet::clutter($ENV{'request.course.uri'})};
+ my $firstResource = $self->navhash('map_start_' .
+ &Apache::lonnet::clutter($ENV{'request.course.uri'}));
return $self->getById($firstResource);
}
@@ -1120,8 +1148,8 @@ sub firstResource {
sub finishResource {
my $self = shift;
- my $firstResource = $self->{NAV_HASH}->{'map_finish_' .
- &Apache::lonnet::clutter($ENV{'request.course.uri'})};
+ my $firstResource = $self->navhash('map_finish_' .
+ &Apache::lonnet::clutter($ENV{'request.course.uri'}));
return $self->getById($firstResource);
}
@@ -1780,7 +1808,7 @@ sub navHash {
my $self = shift;
my $param = shift;
my $id = shift;
- return $self->{NAV_MAP}->{NAV_HASH}->{$param . ($id?$self->{ID}:"")};
+ return $self->{NAV_MAP}->navhash($param . ($id?$self->{ID}:""));
}
=pod
@@ -2459,7 +2487,11 @@ sub getNext {
# Don't remember it if the student doesn't have browse priviledges
# future note: this may properly belong in the client of the resource
- my $browsePriv = &Apache::lonnet::allowed('bre', $self->src);
+ my $browsePriv = $self->{BROWSE_PRIV};
+ if (!defined($browsePriv)) {
+ $browsePriv = &Apache::lonnet::allowed('bre', $self->src);
+ $self->{BROWSE_PRIV} = $browsePriv;
+ }
if (!($browsePriv ne '2' && $browsePriv ne 'F')) {
push @branches, $next;
}
@@ -2478,7 +2510,11 @@ sub getPrevious {
# Don't remember it if the student doesn't have browse priviledges
# future note: this may properly belong in the client of the resource
- my $browsePriv = &Apache::lonnet::allowed('bre', $self->src);
+ my $browsePriv = $self->{BROWSE_PRIV};
+ if (!defined($browsePriv)) {
+ $browsePriv = &Apache::lonnet::allowed('bre', $self->src);
+ $self->{BROWSE_PRIV} = $browsePriv;
+ }
if (!($browsePriv ne '2' && $browsePriv ne 'F')) {
push @branches, $prev;
}