version 1.110, 2002/11/15 20:12:11
|
version 1.115, 2002/11/26 14:45:24
|
Line 83 sub handler {
|
Line 83 sub handler {
|
return HTTP_NOT_ACCEPTABLE; |
return HTTP_NOT_ACCEPTABLE; |
} |
} |
|
|
|
$r->print("<html><head>\n"); |
|
$r->print("<title>Navigate Course Contents</title>"); |
|
|
# Header |
# Header |
$r->print(&Apache::loncommon::bodytag('Navigate Course Map','', |
$r->print(&Apache::loncommon::bodytag('Navigate Course Contents','', |
'')); |
'')); |
$r->print('<script>window.focus();</script>'); |
$r->print('<script>window.focus();</script>'); |
|
|
Line 155 sub handler {
|
Line 158 sub handler {
|
my %colormap = |
my %colormap = |
( $res->NETWORK_FAILURE => '', |
( $res->NETWORK_FAILURE => '', |
$res->CORRECT => '', |
$res->CORRECT => '', |
$res->EXCUSED => '#BBBBFF', |
$res->EXCUSED => '#3333FF', |
$res->PAST_DUE_ANSWER_LATER => '', |
$res->PAST_DUE_ANSWER_LATER => '', |
$res->PAST_DUE_NO_ANSWER => '', |
$res->PAST_DUE_NO_ANSWER => '', |
$res->ANSWER_OPEN => '#CCFFCC', |
$res->ANSWER_OPEN => '#006600', |
$res->OPEN_LATER => '', |
$res->OPEN_LATER => '', |
$res->TRIES_LEFT => '', |
$res->TRIES_LEFT => '', |
$res->INCORRECT => '', |
$res->INCORRECT => '', |
Line 168 sub handler {
|
Line 171 sub handler {
|
# is not yet done and due in less then 24 hours |
# is not yet done and due in less then 24 hours |
my $hurryUpColor = "#FF0000"; |
my $hurryUpColor = "#FF0000"; |
|
|
|
# Keep these mappings in sync with lonquickgrades, which uses the colors |
|
# instead of the icons. |
my %statusIconMap = |
my %statusIconMap = |
( $res->NETWORK_FAILURE => '', |
( $res->NETWORK_FAILURE => '', |
$res->NOTHING_SET => '', |
$res->NOTHING_SET => '', |
Line 204 sub handler {
|
Line 209 sub handler {
|
# maps in their own folders, in favor of "inlining" them. |
# maps in their own folders, in favor of "inlining" them. |
my $topResource = $navmap->getById("0.0"); |
my $topResource = $navmap->getById("0.0"); |
my $inlineTopLevelMaps = $topResource->src() =~ m|^/uploaded/.*default\.sequence$|; |
my $inlineTopLevelMaps = $topResource->src() =~ m|^/uploaded/.*default\.sequence$|; |
|
my $inlinedelta = $inlineTopLevelMaps? -1 : 0; |
|
|
# Begin the HTML table |
# Begin the HTML table |
# four cols: resource + indent, chat+feedback, icon, text string |
# four cols: resource + indent, chat+feedback, icon, text string |
Line 285 sub handler {
|
Line 291 sub handler {
|
$condition); |
$condition); |
$mapIterator->next(); |
$mapIterator->next(); |
$curRes = $mapIterator->next(); |
$curRes = $mapIterator->next(); |
my $deltadepth = 0; |
|
$depth = 1; |
$depth = 1; |
|
|
my @backgroundColors = ("#FFFFFF", "#F6F6F6"); |
my @backgroundColors = ("#FFFFFF", "#F6F6F6"); |
Line 299 sub handler {
|
Line 304 sub handler {
|
} |
} |
|
|
while ($depth > 0) { |
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() || |
if ($curRes == $mapIterator->BEGIN_MAP() || |
$curRes == $mapIterator->BEGIN_BRANCH()) { |
$curRes == $mapIterator->BEGIN_BRANCH()) { |
$indentLevel++; |
$indentLevel++; |
Line 324 sub handler {
|
Line 320 sub handler {
|
|
|
if (ref($curRes)) { $counter++; } |
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 |
# Is this resource being ignored because it is in a random-out |
# map and it was not selected? |
# map and it was not selected? |
if (ref($curRes) && !advancedUser() && $curRes->randomout()) { |
if (ref($curRes) && !advancedUser() && $curRes->randomout()) { |
Line 336 sub handler {
|
Line 329 sub handler {
|
|
|
if (ref($curRes) && $curRes->src()) { |
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 |
# Step one: Decide which parts to show |
my @parts = @{$curRes->parts()}; |
my @parts = @{$curRes->parts()}; |
my $multipart = scalar(@parts) > 1; |
my $multipart = scalar(@parts) > 1; |
Line 421 sub handler {
|
Line 424 sub handler {
|
# For each part we intend to display... |
# For each part we intend to display... |
foreach my $part (@parts) { |
foreach my $part (@parts) { |
|
|
my $deltalevel = 0; # for inserting the branch icon |
|
my $nonLinkedText = ""; # unlinked stuff after title |
my $nonLinkedText = ""; # unlinked stuff after title |
|
|
my $stack = $mapIterator->getStack(); |
my $stack = $mapIterator->getStack(); |
Line 443 sub handler {
|
Line 445 sub handler {
|
if ($isNewBranch) { |
if ($isNewBranch) { |
$newBranchText = "<img src=\"/adm/lonIcons/branch.gif\" border=\"0\">"; |
$newBranchText = "<img src=\"/adm/lonIcons/branch.gif\" border=\"0\">"; |
$isNewBranch = 0; |
$isNewBranch = 0; |
$deltalevel = 1; # reserves space for the branch icon |
|
} |
} |
|
|
# links to open and close the folders |
# links to open and close the folders |
Line 479 sub handler {
|
Line 480 sub handler {
|
my $colorizer = ""; |
my $colorizer = ""; |
my $color; |
my $color; |
if ($curRes->is_problem()) { |
if ($curRes->is_problem()) { |
my $status = $curRes->status($part); |
$color = $colormap{$curRes->status}; |
$color = $colormap{$status}; |
|
|
|
# Special case in the navmaps: If in less then |
if (dueInLessThen24Hours($curRes, $part) || |
# 24 hours, give it a bit of urgency |
lastTry($curRes, $part)) { |
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()) { |
|
$color = $hurryUpColor; |
$color = $hurryUpColor; |
} |
} |
|
|
if ($color ne "") { |
if ($color ne "") { |
$colorizer = "bgcolor=\"$color\""; |
$colorizer = "bgcolor=\"$color\""; |
} |
} |
Line 521 sub handler {
|
Line 508 sub handler {
|
} |
} |
|
|
# print indentation |
# print indentation |
for (my $i = 0; $i < $indentLevel - $deltalevel + $deltadepth; $i++) { |
for (my $i = 0; $i < $indentLevel - $deltalevel + $inlinedelta; $i++) { |
$r->print($indentString); |
$r->print($indentString); |
} |
} |
|
|
Line 552 sub handler {
|
Line 539 sub handler {
|
'<font size="-1">Host down</font>')); |
'<font size="-1">Host down</font>')); |
} |
} |
|
|
|
$r->print("</td>\n"); |
|
|
# SECOND COL: Is there text, feedback, errors?? |
# SECOND COL: Is there text, feedback, errors?? |
my $discussionHTML = ""; my $feedbackHTML = ""; |
my $discussionHTML = ""; my $feedbackHTML = ""; |
|
|
Line 610 sub handler {
|
Line 599 sub handler {
|
} |
} |
|
|
$r->print(" </td></tr>\n"); |
$r->print(" </td></tr>\n"); |
|
|
|
if (!($counter % 20)) { $r->rflush(); } |
|
if ($counter == 2) { $r->rflush(); } |
} |
} |
} |
} |
$curRes = $mapIterator->next(); |
$curRes = $mapIterator->next(); |
Line 727 sub getDescription {
|
Line 719 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. |
# This puts a human-readable name on the ENV variable. |
sub advancedUser { |
sub advancedUser { |
return $ENV{'user.adv'}; |
return $ENV{'user.adv'}; |
Line 892 sub new {
|
Line 911 sub new {
|
&GDBM_READER(), 0640))) { |
&GDBM_READER(), 0640))) { |
return undef; |
return undef; |
} |
} |
$self->{NAV_HASH} = \%navmaphash; |
|
|
|
my %parmhash; |
my %parmhash; |
if (!(tie(%parmhash, 'GDBM_File', $self->{PARM_HASH_FILE}, |
if (!(tie(%parmhash, 'GDBM_File', $self->{PARM_HASH_FILE}, |
Line 901 sub new {
|
Line 919 sub new {
|
untie $self->{PARM_HASH}; |
untie $self->{PARM_HASH}; |
return undef; |
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); |
bless($self); |
|
$self->untieHashes(); |
|
|
return $self; |
return $self; |
} |
} |
Line 1018 sub init {
|
Line 1042 sub init {
|
$self->{PARM_CACHE} = {}; |
$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 |
# Checks to see if coursemap is defined, matching test in old lonnavmaps |
sub courseMapDefined { |
sub courseMapDefined { |
my $self = shift; |
my $self = shift; |
my $uri = &Apache::lonnet::clutter($ENV{'request.course.uri'}); |
my $uri = &Apache::lonnet::clutter($ENV{'request.course.uri'}); |
|
|
my $firstres = $self->{NAV_HASH}->{"map_start_$uri"}; |
my $firstres = $self->navhash("map_start_$uri"); |
my $lastres = $self->{NAV_HASH}->{"map_finish_$uri"}; |
my $lastres = $self->navhash("map_finish_$uri"); |
return $firstres && $lastres; |
return $firstres && $lastres; |
} |
} |
|
|
Line 1104 sub getById {
|
Line 1135 sub getById {
|
|
|
sub firstResource { |
sub firstResource { |
my $self = shift; |
my $self = shift; |
my $firstResource = $self->{NAV_HASH}->{'map_start_' . |
my $firstResource = $self->navhash('map_start_' . |
&Apache::lonnet::clutter($ENV{'request.course.uri'})}; |
&Apache::lonnet::clutter($ENV{'request.course.uri'})); |
return $self->getById($firstResource); |
return $self->getById($firstResource); |
} |
} |
|
|
Line 1117 sub firstResource {
|
Line 1148 sub firstResource {
|
|
|
sub finishResource { |
sub finishResource { |
my $self = shift; |
my $self = shift; |
my $firstResource = $self->{NAV_HASH}->{'map_finish_' . |
my $firstResource = $self->navhash('map_finish_' . |
&Apache::lonnet::clutter($ENV{'request.course.uri'})}; |
&Apache::lonnet::clutter($ENV{'request.course.uri'})); |
return $self->getById($firstResource); |
return $self->getById($firstResource); |
} |
} |
|
|
Line 1509 sub next {
|
Line 1540 sub next {
|
# BC branch and gets to C, it will see F as the only next resource, but it's |
# BC branch and gets to C, it will see F as the only next resource, but it's |
# one level lower. Thus, this is the end of the branch, since there are no |
# one level lower. Thus, this is the end of the branch, since there are no |
# more resources added to this level or above. |
# more resources added to this level or above. |
|
# We don't do this if the examined resource is the finish resource, |
|
# because the condition given above is true, but the "END_MAP" will |
|
# take care of things and we should already be at depth 0. |
my $isEndOfBranch = $maxDepthAdded < $self->{CURRENT_DEPTH}; |
my $isEndOfBranch = $maxDepthAdded < $self->{CURRENT_DEPTH}; |
if ($isEndOfBranch) { # **9** |
if ($isEndOfBranch && $here != $self->{FINISH_RESOURCE}) { # **9** |
push @{$self->{STACK}->[$self->{CURRENT_DEPTH}]}, END_BRANCH(); |
push @{$self->{STACK}->[$self->{CURRENT_DEPTH}]}, END_BRANCH(); |
} |
} |
|
|
Line 1774 sub navHash {
|
Line 1808 sub navHash {
|
my $self = shift; |
my $self = shift; |
my $param = shift; |
my $param = shift; |
my $id = shift; |
my $id = shift; |
return $self->{NAV_MAP}->{NAV_HASH}->{$param . ($id?$self->{ID}:"")}; |
return $self->{NAV_MAP}->navhash($param . ($id?$self->{ID}:"")); |
} |
} |
|
|
=pod |
=pod |
Line 2453 sub getNext {
|
Line 2487 sub getNext {
|
|
|
# Don't remember it if the student doesn't have browse priviledges |
# Don't remember it if the student doesn't have browse priviledges |
# future note: this may properly belong in the client of the resource |
# 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')) { |
if (!($browsePriv ne '2' && $browsePriv ne 'F')) { |
push @branches, $next; |
push @branches, $next; |
} |
} |
Line 2472 sub getPrevious {
|
Line 2510 sub getPrevious {
|
|
|
# Don't remember it if the student doesn't have browse priviledges |
# Don't remember it if the student doesn't have browse priviledges |
# future note: this may properly belong in the client of the resource |
# 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')) { |
if (!($browsePriv ne '2' && $browsePriv ne 'F')) { |
push @branches, $prev; |
push @branches, $prev; |
} |
} |