version 1.86, 2002/10/24 19:10:07
|
version 1.91, 2002/10/29 20:17:39
|
Line 910 sub new_handle {
|
Line 910 sub new_handle {
|
} |
} |
} |
} |
|
|
|
# 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 $currenturl = $ENV{'form.postdata'}; |
my $currenturl = $ENV{'form.postdata'}; |
$currenturl=~s/^http\:\/\///; |
$currenturl=~s/^http\:\/\///; |
$currenturl=~s/^[^\/]+//; |
$currenturl=~s/^[^\/]+//; |
Line 921 sub new_handle {
|
Line 926 sub new_handle {
|
my $queryAdd = "postdata=" . &Apache::lonnet::escape($currenturl) . |
my $queryAdd = "postdata=" . &Apache::lonnet::escape($currenturl) . |
"&alreadyHere=1"; |
"&alreadyHere=1"; |
|
|
$r->print('<a href="navmaps?condition=1&filter=">Show All Resources</a><br /><br />'); |
|
|
|
# Begin the HTML table |
|
# four cols: resource + indent, chat+feedback, icon, text string |
|
$r->print('<table cellspacing="0" cellpadding="3" border="0" bgcolor="#FFFFFF">' ."\n"); |
|
|
|
my $condition = 0; |
my $condition = 0; |
if ($ENV{'form.condition'}) { |
if ($ENV{'form.condition'}) { |
$condition = 1; |
$condition = 1; |
} |
} |
|
|
|
if ($condition) { |
|
$r->print('<a href="navmaps?condition=0&filter=">Close All Folders</a><br /><br />'); |
|
} else { |
|
$r->print('<a href="navmaps?condition=1&filter=">Open All Folders</a><br /><br />'); |
|
} |
|
|
|
# Begin the HTML table |
|
# four cols: resource + indent, chat+feedback, icon, text string |
|
$r->print('<table cellspacing="0" cellpadding="3" border="0" bgcolor="#FFFFFF">' ."\n"); |
|
|
# This needs to be updated to use symbs from the remote, |
# This needs to be updated to use symbs from the remote, |
# instead of uris. The changes to this and the main rendering |
# instead of uris. The changes to this and the main rendering |
# loop should be obvious. |
# loop should be obvious. |
# Here's a simple example of the iterator. |
# Here's a simple example of the iterator. |
# If there is a current resource |
# Preprocess the map: Look for current URL, force inlined maps to display |
if ($currenturl && !$ENV{'form.alreadyHere'}) { |
|
# Give me every resource... |
my $mapIterator = $navmap->getIterator(undef, undef, {}, 1); |
my $mapIterator = $navmap->getIterator(undef, undef, {}, 1); |
my $found = 0; |
my $found = 0; |
my $depth = 1; |
my $depth = 1; |
my $currentUrlIndex = 0; # keeps track of when the current resource is found, |
$mapIterator->next(); # discard the first BEGIN_MAP |
# so we can back up a few and put the anchor above the |
my $curRes = $mapIterator->next(); |
# current resource |
|
$mapIterator->next(); # discard the first BEGIN_MAP |
while ($depth > 0 && !$found) { |
my $curRes = $mapIterator->next(); |
if (ref($curRes) && $curRes->src() eq $currenturl) { |
my $counter = 0; |
# If this is the correct resource, be sure to |
|
# show it by making sure the containing maps |
while ($depth > 0) { |
# are open. |
if ($curRes == $mapIterator->BEGIN_MAP()) { |
|
$depth++; |
my $mapStack = $mapIterator->getStack(); |
} |
for my $map (@{$mapStack}) { |
if ($curRes == $mapIterator->END_MAP()) { |
if ($condition) { |
$depth--; |
undef $filterHash{$map->map_pc()}; |
} |
} else { |
|
$filterHash{$map->map_pc()} = 1; |
if (ref($curRes)) { $counter++; } |
} |
|
|
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. |
|
|
|
$currentUrlIndex = $counter; |
|
|
|
for my $map (@{$mapStack}) { |
|
if ($condition) { |
|
undef $filterHash{$map->map_pc()}; |
|
} else { |
|
$filterHash{$map->map_pc()} = 1; |
} |
} |
$found = 1; |
|
} |
} |
$curRes = $mapIterator->next(); |
$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; |
|
} |
} |
} |
} |
|
|
|
|
$curRes = $mapIterator->next(); |
|
} |
|
|
undef $res; # so we don't accidentally use it later |
undef $res; # so we don't accidentally use it later |
my $indentLevel = 0; |
my $indentLevel = 0; |
my $indentString = "<img src=\"/adm/lonIcons/whitespace1.gif\" width=\"25\" height=\"1\" alt=\"\" border=\"0\" />"; |
my $indentString = "<img src=\"/adm/lonIcons/whitespace1.gif\" width=\"25\" height=\"1\" alt=\"\" border=\"0\" />"; |
Line 972 sub new_handle {
|
Line 1007 sub new_handle {
|
my $isNewBranch = 0; |
my $isNewBranch = 0; |
my $now = time(); |
my $now = time(); |
my $in24Hours = $now + 24 * 60 * 60; |
my $in24Hours = $now + 24 * 60 * 60; |
my $depth = 1; |
|
my $displayedHereMarker = 0; |
my $displayedHereMarker = 0; |
|
|
# We know the first thing is a BEGIN_MAP (see "$self->{STARTED}" |
# We know the first thing is a BEGIN_MAP (see "$self->{STARTED}" |
# code in iterator->next), so ignore the first one |
# code in iterator->next), so ignore the first one |
my $mapIterator = $navmap->getIterator(undef, undef, \%filterHash, |
$mapIterator = $navmap->getIterator(undef, undef, \%filterHash, |
$condition); |
$condition); |
$mapIterator->next(); |
$mapIterator->next(); |
my $curRes = $mapIterator->next(); |
$curRes = $mapIterator->next(); |
|
my $deltadepth = 0; |
|
$depth = 1; |
|
|
|
my @backgroundColors = ("#FFFFFF", "#F6F6F6"); |
|
my $rowNum = 0; |
|
|
|
$counter = 0; |
|
|
while ($depth > 0) { |
while ($depth > 0) { |
|
# If we're in a new style course, and this is a BEGIN_MAP, END_MAP, or |
|
# map resource and the stack depth is only one, just plain ignore this resource |
|
# entirely. (This has the effect of inlining the resources in that map |
|
# in the nav map.) |
|
if ($inlineTopLevelMaps && scalar(@{$mapIterator->getStack()}) == 1 && |
|
ref($curRes) && $curRes->is_map()) { |
|
# We let the normal depth stuff occur, but we need to shift everything |
|
# over by one to the left to make it look right. |
|
$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 1001 sub new_handle {
|
Line 1055 sub new_handle {
|
$depth--; |
$depth--; |
} |
} |
|
|
|
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 blotted out? |
# Is this resource being blotted out? |
if (ref($curRes) && !advancedUser() && $curRes->randomout()) { |
if (ref($curRes) && !advancedUser() && $curRes->randomout()) { |
$curRes = $mapIterator->next(); |
$curRes = $mapIterator->next(); |
Line 1168 sub new_handle {
|
Line 1227 sub new_handle {
|
$color = $hurryUpColor; |
$color = $hurryUpColor; |
} |
} |
# Special case: If this is the last try, and there is |
# Special case: If this is the last try, and there is |
# more then one available, give a bit of urgency |
# more then one available, and it's not due yet, give a bit of urgency |
my $tries = $curRes->tries($part); |
my $tries = $curRes->tries($part); |
my $maxtries = $curRes->maxtries($part); |
my $maxtries = $curRes->maxtries($part); |
if ($tries && $maxtries && $maxtries > 1 && |
if ($tries && $maxtries && $maxtries > 1 && |
$maxtries - $tries == 1) { |
$maxtries - $tries == 1 && $curRes->duedate() && |
|
$curRes->duedate() > time()) { |
$color = $hurryUpColor; |
$color = $hurryUpColor; |
} |
} |
if ($color ne "") { |
if ($color ne "") { |
Line 1184 sub new_handle {
|
Line 1244 sub new_handle {
|
$nonLinkedText .= ' <i>(hidden)</i> '; |
$nonLinkedText .= ' <i>(hidden)</i> '; |
} |
} |
|
|
# FIRST COL: The resource indentation, branch icon, and name |
$rowNum++; |
$r->print(" <tr><td align=\"left\" valign=\"center\" width=\"60%\">\n"); |
my $backgroundColor = $backgroundColors[$rowNum % scalar(@backgroundColors)]; |
|
|
|
# FIRST COL: The resource indentation, branch icon, name, and anchor |
|
$r->print(" <tr bgcolor=\"$backgroundColor\"><td align=\"left\" valign=\"center\" width=\"60%\">\n"); |
|
|
|
# anchor for current resource... - 5 is deliberate: If it's that |
|
# high on the screen, don't bother focusing on it. Also this will |
|
# print multiple anchors if this is an expanded multi-part problem... |
|
# who cares? |
|
if ($counter == $currentUrlIndex - 5) { |
|
$r->print('<a name="current" />'); |
|
} |
|
|
# print indentation |
# print indentation |
for (my $i = 0; $i < $indentLevel - $deltalevel; $i++) { |
for (my $i = 0; $i < $indentLevel - $deltalevel + $deltadepth; $i++) { |
$r->print($indentString); |
$r->print($indentString); |
} |
} |
|
|
Line 1692 sub courseMapDefined {
|
Line 1763 sub courseMapDefined {
|
sub getIterator { |
sub getIterator { |
my $self = shift; |
my $self = shift; |
my $iterator = Apache::lonnavmaps::iterator->new($self, shift, shift, |
my $iterator = Apache::lonnavmaps::iterator->new($self, shift, shift, |
shift, undef, shift); |
shift, undef, shift, |
|
$ENV{'form.direction'}); |
return $iterator; |
return $iterator; |
} |
} |
|
|
Line 1916 getIterator behaves as follows:
|
Line 1988 getIterator behaves as follows:
|
|
|
=over 4 |
=over 4 |
|
|
=item B<getIterator>(firstResource, finishResource, filterHash, condition): All parameters are optional. firstResource is a resource reference corresponding to where the iterator should start. It defaults to navmap->firstResource() for the corresponding nav map. finishResource corresponds to where you want the iterator to end, defaulting to navmap->finishResource(). filterHash is a hash used as a set containing strings representing the resource IDs, defaulting to empty. Condition is a 1 or 0 that sets what to do with the filter hash: If a 0, then only resource that exist IN the filterHash will be recursed on. If it is a 1, only resources NOT in the filterHash will be recursed on. Defaults to 0, which is to say, do not recurse unless explicitly asked to. |
=item B<getIterator>(firstResource, finishResource, filterHash, condition, direction): All parameters are optional. firstResource is a resource reference corresponding to where the iterator should start. It defaults to navmap->firstResource() for the corresponding nav map. finishResource corresponds to where you want the iterator to end, defaulting to navmap->finishResource(). filterHash is a hash used as a set containing strings representing the resource IDs, defaulting to empty. Condition is a 1 or 0 that sets what to do with the filter hash: If a 0, then only resource that exist IN the filterHash will be recursed on. If it is a 1, only resources NOT in the filterHash will be recursed on. Defaults to 0, which is to say, do not recurse unless explicitly asked to. Direction specifies which direction to recurse, either FORWARD or BACKWARD, with FORWARD being default. |
|
|
Thus, by default, all resources will be shown. Change the condition to a 1 without changing the hash, and only the top level of the map will be shown. Changing the condition to 1 and including some values in the hash will allow you to selectively examine parts of the navmap, while leaving it on 0 and adding things to the hash will allow you to selectively ignore parts of the nav map. See the handler code for examples: By default, the condition is 0 and all folders are closed unless explicitly opened. Clicking "Show All Resources" will use a condition of 1 and an empty filterHash, resulting in all resources being shown. |
Thus, by default, all resources will be shown. Change the condition to a 1 without changing the hash, and only the top level of the map will be shown. Changing the condition to 1 and including some values in the hash will allow you to selectively examine parts of the navmap, while leaving it on 0 and adding things to the hash will allow you to selectively ignore parts of the nav map. See the handler code for examples: By default, the condition is 0 and all folders are closed unless explicitly opened. Clicking "Show All Resources" will use a condition of 1 and an empty filterHash, resulting in all resources being shown. |
|
|
Line 1946 sub BEGIN_MAP { return 1; } # beginin
|
Line 2018 sub BEGIN_MAP { return 1; } # beginin
|
sub END_MAP { return 2; } # end of the map |
sub END_MAP { return 2; } # end of the map |
sub BEGIN_BRANCH { return 3; } # beginning of a branch |
sub BEGIN_BRANCH { return 3; } # beginning of a branch |
sub END_BRANCH { return 4; } # end of a branch |
sub END_BRANCH { return 4; } # end of a branch |
|
sub FORWARD { return 1; } # go forward |
|
sub BACKWARD { return 2; } |
|
|
# Params: nav map, start resource, end resource, filter, condition, |
# Params: nav map, start resource, end resource, filter, condition, |
# already seen hash ref |
# already seen hash ref |
Line 1976 sub new {
|
Line 2050 sub new {
|
$self->{ALREADY_SEEN} = shift; |
$self->{ALREADY_SEEN} = shift; |
if (!defined($self->{ALREADY_SEEN})) { $self->{ALREADY_SEEN} = {} }; |
if (!defined($self->{ALREADY_SEEN})) { $self->{ALREADY_SEEN} = {} }; |
$self->{CONDITION} = shift; |
$self->{CONDITION} = shift; |
|
$self->{DIRECTION} = shift || FORWARD(); |
|
|
# Flag: Have we started yet? If not, the first action is to return BEGIN_MAP. |
# Flag: Have we started yet? If not, the first action is to return BEGIN_MAP. |
$self->{STARTED} = 0; |
$self->{STARTED} = 0; |
Line 2000 sub new {
|
Line 2075 sub new {
|
$self->{FORCE_NEXT} = undef; |
$self->{FORCE_NEXT} = undef; |
|
|
# Start with the first resource |
# Start with the first resource |
push @{$self->{BRANCH_STACK}}, $self->{FIRST_RESOURCE}; |
if ($self->{DIRECTION} == FORWARD) { |
|
push @{$self->{BRANCH_STACK}}, $self->{FIRST_RESOURCE}; |
|
} else { |
|
push @{$self->{BRANCH_STACK}}, $self->{FINISH_RESOURCE}; |
|
} |
$self->{BRANCH_STACK_SIZE} = 1; |
$self->{BRANCH_STACK_SIZE} = 1; |
|
|
bless($self); |
bless($self); |
Line 2097 sub next {
|
Line 2176 sub next {
|
$self->{ALREADY_SEEN}->{$self->{HERE}->{ID}} = 1; |
$self->{ALREADY_SEEN}->{$self->{HERE}->{ID}} = 1; |
|
|
# Get the next possible resources |
# Get the next possible resources |
my $nextUnfiltered = $self->{HERE}->getNext(); |
my $nextUnfiltered; |
|
if ($self->{DIRECTION} == FORWARD()) { |
|
$nextUnfiltered = $self->{HERE}->getNext(); |
|
} else { |
|
$nextUnfiltered = $self->{HERE}->getPrevious(); |
|
} |
my $next = []; |
my $next = []; |
|
|
# filter the next possibilities to remove things we've |
# filter the next possibilities to remove things we've |
Line 2147 sub next {
|
Line 2231 sub next {
|
$self->{RECURSIVE_ITERATOR} = |
$self->{RECURSIVE_ITERATOR} = |
Apache::lonnavmaps::iterator->new ($self->{NAV_MAP}, $firstResource, |
Apache::lonnavmaps::iterator->new ($self->{NAV_MAP}, $firstResource, |
$finishResource, $self->{FILTER}, $self->{ALREADY_SEEN}, |
$finishResource, $self->{FILTER}, $self->{ALREADY_SEEN}, |
$self->{CONDITION}); |
$self->{CONDITION}, $self->{DIRECTION}); |
} |
} |
|
|
return $self->{HERE}; |
return $self->{HERE}; |
Line 2174 sub populateStack {
|
Line 2258 sub populateStack {
|
my $self=shift; |
my $self=shift; |
my $stack = shift; |
my $stack = shift; |
|
|
push @$stack, $self->{HERE}; |
push @$stack, $self->{HERE} if ($self->{HERE}); |
|
|
if ($self->{RECURSIVE_ITERATOR_FLAG}) { |
if ($self->{RECURSIVE_ITERATOR_FLAG}) { |
$self->{RECURSIVE_ITERATOR}->populateStack($stack); |
$self->{RECURSIVE_ITERATOR}->populateStack($stack); |
Line 2922 sub getNext {
|
Line 3006 sub getNext {
|
|
|
sub getPrevious { |
sub getPrevious { |
my $self = shift; |
my $self = shift; |
my @alreadySeen = shift; |
my $alreadySeenHash = shift; |
my @branches; |
my @branches; |
my $from = $self->from(); |
my $from = $self->from(); |
foreach my $branch ( split /,/, $from) { |
foreach my $branch ( split /,/, $from) { |
Line 2934 sub getPrevious {
|
Line 3018 sub getPrevious {
|
# browse privs |
# browse privs |
my $browsePriv = &Apache::lonnet::allowed('bre', $self->src); |
my $browsePriv = &Apache::lonnet::allowed('bre', $self->src); |
if (!defined($alreadySeenHash) || |
if (!defined($alreadySeenHash) || |
!defined($alreadySeenHash->{$next->{ID}}) || |
!defined($alreadySeenHash->{$prev->{ID}}) || |
($browsePriv ne '2' && $browsePriv ne 'F')) { |
($browsePriv ne '2' && $browsePriv ne 'F')) { |
push @branches, $next; |
push @branches, $prev; |
} |
} |
} |
} |
return \@branches; |
return \@branches; |