--- loncom/interface/lonnavmaps.pm 2002/10/04 20:34:04 1.66 +++ loncom/interface/lonnavmaps.pm 2002/10/08 18:54:39 1.69 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Navigate Maps Handler # -# $Id: lonnavmaps.pm,v 1.66 2002/10/04 20:34:04 bowersj2 Exp $ +# $Id: lonnavmaps.pm,v 1.69 2002/10/08 18:54:39 bowersj2 Exp $ # # Copyright Michigan State University Board of Trustees # @@ -892,7 +892,13 @@ sub new_handle { $res->OPEN_LATER => '', $res->TRIES_LEFT => 'navmap.open.gif', $res->INCORRECT => 'navmap.wrong.gif', - $res->OPEN => 'navmap.open.gif' ); + $res->OPEN => 'navmap.open.gif', + $res->ATTEMPTED => '' ); + + my %iconAltTags = + ( 'navmap.correct.gif' => 'Correct', + 'navmap.wrong.gif' => 'Incorrect', + 'navmap.open.gif' => 'Open' ); my %condenseStatuses = ( $res->NETWORK_FAILURE => 1, @@ -920,7 +926,7 @@ sub new_handle { my $condition = 0; if ($ENV{'form.condition'}) { - $condition = 1; + $condition = 1; } my $mapIterator = $navmap->getIterator(undef, undef, \%filterHash, $condition); @@ -946,6 +952,12 @@ sub new_handle { $isNewBranch = 1; } + # Is this resource being blotted out? + if (ref($curRes) && !advancedUser() && $curRes->randomout()) { + $curRes = $mapIterator->next(); + next; # and totally ignore this resource + } + if (ref($curRes) && $curRes->src()) { # Step one: Decide which parts to show @@ -962,7 +974,7 @@ sub new_handle { # just display first if (!$curRes->opendate("0")) { @parts = ("0"); # just display the zero-th part - $condensed = 1; + $condensed = 1; } else { # Otherwise, only display part 0 if we want to # attach feedback or email information to it @@ -1026,6 +1038,7 @@ sub new_handle { foreach my $part (@parts) { my $deltalevel = 0; # for inserting the branch icon + my $nonLinkedText = ""; # unlinked stuff after title # For each thing we're displaying... @@ -1075,7 +1088,7 @@ sub new_handle { removeFromFilter(\%filterHash, $mapId); $linkopen .= "&condition=$condition&$queryAdd\">"; $linkclose = ""; - + } my $colorizer = ""; @@ -1087,6 +1100,10 @@ sub new_handle { } } + if ($curRes->randomout()) { + $nonLinkedText .= ' (hidden) '; + } + # FIRST COL: The resource indentation, branch icon, and name $r->print(" \n"); @@ -1097,14 +1114,12 @@ sub new_handle { $r->print(" ${newBranchText}${linkopen}$icon${linkclose}\n"); - my $nonLinkedText = ""; - - if ($curRes->is_problem() && $part != "0" && !$condensed) { + if ($curRes->is_problem() && $part ne "0" && !$condensed) { $partLabel = " (Part $part)"; $title = ""; } if ($multipart && $condensed) { - $nonLinkedText = ' (' . $curRes->countParts() . ' parts)'; + $nonLinkedText .= ' (' . $curRes->countParts() . ' parts)'; } $r->print(" $title$partLabel $nonLinkedText"); @@ -1142,12 +1157,13 @@ sub new_handle { # columns? my $firstDisplayed = !$condensed && $multipart && $part eq "0"; - # THIRD ROW: Problem status icon + # THIRD COL: Problem status icon if ($curRes->is_problem() && !$firstDisplayed) { my $icon = $statusIconMap{$curRes->status($part)}; + my $alt = $iconAltTags{$icon}; if ($icon) { - $r->print("$linkopen$linkclose\n"); + $r->print("$linkopen\"$alt\"$linkclose\n"); } else { $r->print("\n"); } @@ -1155,7 +1171,7 @@ sub new_handle { $r->print("\n"); } - # FOURTH ROW: Text description + # FOURTH COL: Text description $r->print("\n"); if ($curRes->kind() eq "res" && @@ -1163,6 +1179,9 @@ sub new_handle { !$firstDisplayed) { $r->print (getDescription($curRes, $part)); } + if ($curRes->is_map() && advancedUser() && $curRes->randompick()) { + $r->print('(randomly select ' . $curRes->randompick() .')'); + } $r->print("\n"); } @@ -1232,7 +1251,7 @@ sub getLinkForResource { sub getDescription { my $res = shift; my $part = shift; - my $status = $res->getDateStatus(); + my $status = $res->status($part); if ($status == $res->NETWORK_FAILURE) { return ""; } if ($status == $res->NOTHING_SET) { @@ -1260,6 +1279,9 @@ sub getDescription { if ($status == $res->EXCUSED) { return "Excused by instructor"; } + if ($status == $res->ATTEMPTED) { + return "Not yet graded."; + } if ($status == $res->TRIES_LEFT) { my $tries = $res->tries(); my $maxtries = $res->maxtries(); @@ -1273,6 +1295,10 @@ sub getDescription { } } +sub advancedUser { + return $ENV{'user.adv'}; +} + # I want to change this into something more human-friendly. For # now, this is a simple call to localtime. The final function # probably belongs in loncommon. @@ -1770,21 +1796,33 @@ sub new { return $self; } +# FIXME: Document this. +sub cancelTopRecursion { + my $self = shift; + + if (!$self->{RECURSIVE_ITERATOR_FLAG}) {return;} + + # is this the iterator we want to kill? + if ($self->{RECURSIVE_ITERATOR_FLAG} && + !$self->{RECURSIVE_ITERATOR}->{RECURSIVE_ITERATOR_FLAG}) { + $self->{RECURSIVE_ITERATOR_FLAG} = 0; + undef $self->{RECURSIVE_ITERATOR}; + return; + } + + $self->{RECURSIVE_ITERATOR}->cancelTopRecursion(); +} + # Note... this function is *touchy*. I strongly recommend tracing # through it with the debugger a few times on a non-trivial map before # modifying it. Order is *everything*. +# FIXME: Doc that skipMap will prevent the recursion, if any. sub next { my $self = shift; + my $skipMap = shift; # Iterator logic goes here - # Is this return value pre-determined? - if (defined($self->{FORCE_NEXT})) { - my $tmp = $self->{FORCE_NEXT}; - $self->{FORCE_NEXT} = undef; - return $tmp; - } - # Are we using a recursive iterator? If so, pull from that and # watch the depth; we want to resume our level at the correct time. if ($self->{RECURSIVE_ITERATOR_FLAG}) @@ -1804,6 +1842,13 @@ sub next { return $next; } + # Is this return value pre-determined? + if (defined($self->{FORCE_NEXT})) { + my $tmp = $self->{FORCE_NEXT}; + $self->{FORCE_NEXT} = undef; + return $tmp; + } + # Is there a current resource to grab? If not, then return # END_BRANCH and END_MAP in succession. if (scalar(@{$self->{BRANCH_STACK}}) == 0) { @@ -1892,7 +1937,6 @@ sub next { $self->{FORCE_NEXT} = $self->END_BRANCH(); $self->{BRANCH_DEPTH}--; } - return $self->{HERE}; } while (@$next) { @@ -1908,15 +1952,12 @@ sub next { } # If this is a map and we want to recurse down it... (not filtered out) - if ($self->{HERE}->is_map() && + if ($self->{HERE}->is_map() && !$skipMap && (defined($self->{FILTER}->{$self->{HERE}->map_pc()}) xor $self->{CONDITION})) { $self->{RECURSIVE_ITERATOR_FLAG} = 1; my $firstResource = $self->{HERE}->map_start(); my $finishResource = $self->{HERE}->map_finish(); - # Odd perl syntax here; $self->new allows one to create a new iterator - # can't figure out how to ref this package directly correctly - # isn't MAIN::new, __PACKAGE__::new or Apache::lonnavmaps::iterator->new $self->{RECURSIVE_ITERATOR} = Apache::lonnavmaps::iterator->new ($self->{NAV_MAP}, $firstResource, $finishResource, $self->{FILTER}, $self->{ALREADY_SEEN}, @@ -2037,6 +2078,13 @@ sub goesto { my $self=shift; return $sel # "to" can return a comma seperated list for branches sub to { my $self=shift; return $self->navHash("to_", 1); } sub kind { my $self=shift; return $self->navHash("kind_", 1); } +sub ext { my $self=shift; return $self->navHash("ext_", 1) eq 'true:'; } +sub randomout { my $self=shift; return $self->navHash("randomout_", 1); } +sub randompick { + my $self = shift; + return $self->{NAV_MAP}->{PARM_HASH}->{$self->symb . + '.0.parameter_randompick'}; +} sub src { my $self=shift; return $self->navHash("src_", 1); @@ -2286,6 +2334,8 @@ sub getFeedback { sub parts { my $self = shift; + if ($self->ext) { return ['0']; } + $self->extractParts(); return $self->{PARTS}; } @@ -2309,6 +2359,7 @@ sub extractParts { my $self = shift; return if ($self->{PARTS}); + return if ($self->ext); $self->{PARTS} = []; @@ -2448,6 +2499,8 @@ B =item * B: Information not available due to network failure. +=item * B: Attempted, and not yet graded. + =back =cut @@ -2458,6 +2511,7 @@ sub INCORRECT_BY_OVERRIDE { return 12; } sub CORRECT { return 13; } sub CORRECT_BY_OVERRIDE { return 14; } sub EXCUSED { return 15; } +sub ATTEMPTED { return 16; } sub getCompletionStatus { my $self = shift; @@ -2476,6 +2530,7 @@ sub getCompletionStatus { if ($status eq 'incorrect_attempted') {return $self->INCORRECT; } if ($status eq 'incorrect_by_override') {return $self->INCORRECT_BY_OVERRIDE; } if ($status eq 'excused') {return $self->EXCUSED; } + if ($status eq 'ungraded_attempted') {return $self->ATTEMPTED; } return $self->NOT_ATTEMPTED; } @@ -2509,6 +2564,8 @@ Along with directly returning the date o =item * OPEN: The item is open and not yet tried. +=item * ATTEMPTED: The problem has been attempted. + =back =cut @@ -2531,7 +2588,11 @@ sub status { # There are a few whole rows we can dispose of: if ($completionStatus == CORRECT || $completionStatus == CORRECT_BY_OVERRIDE ) { - return CORRECT(); + return CORRECT; + } + + if ($completionStatus == ATTEMPTED) { + return ATTEMPTED; } # If it's EXCUSED, then return that no matter what @@ -2543,8 +2604,8 @@ sub status { return NOTHING_SET; } - # Now we're down to a 3 (incorrect, incorrect_override, not_attempted) - # by 4 matrix (date status). + # Now we're down to a 4 (incorrect, incorrect_override, not_attempted) + # by 4 matrix (date statuses). if ($dateStatus == PAST_DUE_ANSWER_LATER || $dateStatus == PAST_DUE_NO_ANSWER ) {