\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('');
+ }
# print indentation
- for (my $i = 0; $i < $indentLevel - $deltalevel; $i++) {
+ for (my $i = 0; $i < $indentLevel - $deltalevel + $deltadepth; $i++) {
$r->print($indentString);
}
@@ -1218,7 +1295,7 @@ sub new_handle {
my $discussionHTML = ""; my $feedbackHTML = "";
- # SECOND COL: Is there text or feedback?
+ # SECOND COL: Is there text, feedback, errors??
if ($curRes->hasDiscussion()) {
$discussionHTML = $linkopen .
'' .
@@ -1259,12 +1336,15 @@ sub new_handle {
}
# FOURTH COL: Text description
- $r->print(" | \n");
+ #$r->print(" | \n");
+ $r->print(" | \n");
if ($curRes->kind() eq "res" &&
$curRes->is_problem() &&
!$firstDisplayed) {
+ $r->print ("") if ($color);
$r->print (getDescription($curRes, $part));
+ $r->print ("") if ($color);
}
if ($curRes->is_map() && advancedUser() && $curRes->randompick()) {
$r->print('(randomly select ' . $curRes->randompick() .')');
@@ -1473,7 +1553,7 @@ sub timeToHumanString {
# Less then 5 days away, display day of the week and
# HH:MM
if ( $delta < $day * 5 ) {
- my $timeStr = strftime("%A at %I:%M %P", localtime($time));
+ my $timeStr = strftime("%A, %b %e at %I:%M %P", localtime($time));
$timeStr =~ s/12:00 am/midnight/;
$timeStr =~ s/12:00 pm/noon/;
return ($inPast ? "last " : "next ") .
@@ -1563,6 +1643,14 @@ sub new {
$self->{PARM_HASH} = \%parmhash;
$self->{HASH_TIED} = 1;
+ bless($self);
+
+ return $self;
+}
+
+sub init {
+ my $self = shift;
+
# If the course opt hash and the user opt hash should be generated,
# generate them
if ($self->{GENERATE_COURSE_USER_OPT}) {
@@ -1667,10 +1755,6 @@ sub new {
}
$self->{PARM_CACHE} = {};
-
- bless($self);
-
- return $self;
}
# Checks to see if coursemap is defined, matching test in old lonnavmaps
@@ -1686,7 +1770,8 @@ sub courseMapDefined {
sub getIterator {
my $self = shift;
my $iterator = Apache::lonnavmaps::iterator->new($self, shift, shift,
- shift, undef, shift);
+ shift, undef, shift,
+ $ENV{'form.direction'});
return $iterator;
}
@@ -1910,7 +1995,7 @@ getIterator behaves as follows:
=over 4
-=item B(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(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.
@@ -1940,6 +2025,8 @@ sub BEGIN_MAP { return 1; } # beginin
sub END_MAP { return 2; } # end of the map
sub BEGIN_BRANCH { return 3; } # beginning 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,
# already seen hash ref
@@ -1970,6 +2057,7 @@ sub new {
$self->{ALREADY_SEEN} = shift;
if (!defined($self->{ALREADY_SEEN})) { $self->{ALREADY_SEEN} = {} };
$self->{CONDITION} = shift;
+ $self->{DIRECTION} = shift || FORWARD();
# Flag: Have we started yet? If not, the first action is to return BEGIN_MAP.
$self->{STARTED} = 0;
@@ -1994,7 +2082,11 @@ sub new {
$self->{FORCE_NEXT} = undef;
# 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;
bless($self);
@@ -2091,7 +2183,12 @@ sub next {
$self->{ALREADY_SEEN}->{$self->{HERE}->{ID}} = 1;
# 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 = [];
# filter the next possibilities to remove things we've
@@ -2141,7 +2238,7 @@ sub next {
$self->{RECURSIVE_ITERATOR} =
Apache::lonnavmaps::iterator->new ($self->{NAV_MAP}, $firstResource,
$finishResource, $self->{FILTER}, $self->{ALREADY_SEEN},
- $self->{CONDITION});
+ $self->{CONDITION}, $self->{DIRECTION});
}
return $self->{HERE};
@@ -2168,7 +2265,7 @@ sub populateStack {
my $self=shift;
my $stack = shift;
- push @$stack, $self->{HERE};
+ push @$stack, $self->{HERE} if ($self->{HERE});
if ($self->{RECURSIVE_ITERATOR_FLAG}) {
$self->{RECURSIVE_ITERATOR}->populateStack($stack);
@@ -2270,7 +2367,9 @@ These are methods that help you retrieve
# These info functions can be used directly, as they don't return
# resource information.
+sub comesfrom { my $self=shift; return $self->navHash("comesfrom_", 1); }
sub ext { my $self=shift; return $self->navHash("ext_", 1) eq 'true:'; }
+sub from { my $self=shift; return $self->navHash("from_", 1); }
sub goesto { my $self=shift; return $self->navHash("goesto_", 1); }
sub kind { my $self=shift; return $self->navHash("kind_", 1); }
sub randomout { my $self=shift; return $self->navHash("randomout_", 1); }
@@ -2554,7 +2653,7 @@ sub hasDiscussion {
sub getFeedback {
my $self = shift;
- return $self->{NAV_MAP}->getFeedback($self->symb());
+ return $self->{NAV_MAP}->getFeedback($self->src());
}
=pod
@@ -2884,20 +2983,18 @@ sub status {
=over 4
-=item * B(): Gets the next resource in the navmap after this one.
+=item * B($alreadySeenHashRef): Retreive an array of the possible next resources after this one. Always returns an array, even in the one- or zero-element case. The "alreadySeenHashRef" is an optional parameter that can be passed in to the method. If $$alreadySeenHashRef{$res->id()} is true in that hash, getNext will not return it in the list. In other words, you can use it to suppress resources you've already seen in the getNext method directly.
-=cut
+=item * B($alreadySeenHashRef): Retreive an array of the possible previous resources from this one. Always returns an array, even in the one- or zero-element case. $alreadySeenHashRef is the same as in getNext.
-# For the simple single-link case, to get from a resource to the next
-# resource, you need to look up the "to_" link in the nav hash, then
-# follow that with the "goesto_" link.
+=cut
sub getNext {
my $self = shift;
my $alreadySeenHash = shift;
my @branches;
my $to = $self->to();
- foreach my $branch ( split(/\,/, $to) ) {
+ foreach my $branch ( split(/,/, $to) ) {
my $choice = $self->{NAV_MAP}->getById($branch);
my $next = $choice->goesto();
$next = $self->{NAV_MAP}->getById($next);
@@ -2913,6 +3010,28 @@ sub getNext {
}
return \@branches;
}
+
+sub getPrevious {
+ my $self = shift;
+ my $alreadySeenHash = shift;
+ my @branches;
+ my $from = $self->from();
+ foreach my $branch ( split /,/, $from) {
+ my $choice = $self->{NAV_MAP}->getById($branch);
+ my $prev = $choice->comesfrom();
+ $prev = $self->{NAV_MAP}->getById($prev);
+
+ # Skip it if we've already seen it or the user doesn't have
+ # browse privs
+ my $browsePriv = &Apache::lonnet::allowed('bre', $self->src);
+ if (!defined($alreadySeenHash) ||
+ !defined($alreadySeenHash->{$prev->{ID}}) ||
+ ($browsePriv ne '2' && $browsePriv ne 'F')) {
+ push @branches, $prev;
+ }
+ }
+ return \@branches;
+}
=pod
|