--- loncom/interface/lonnavmaps.pm 2003/05/16 14:17:08 1.191 +++ loncom/interface/lonnavmaps.pm 2003/06/10 20:07:58 1.198 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Navigate Maps Handler # -# $Id: lonnavmaps.pm,v 1.191 2003/05/16 14:17:08 bowersj2 Exp $ +# $Id: lonnavmaps.pm,v 1.198 2003/06/10 20:07:58 bowersj2 Exp $ # # Copyright Michigan State University Board of Trustees # @@ -47,6 +47,7 @@ use Apache::Constants qw(:common :http); use Apache::loncommon(); use Apache::lonmenu(); use POSIX qw (floor strftime); +use Data::Dumper; # for debugging, not always used # symbolic constants sub SYMB { return 1; } @@ -838,7 +839,7 @@ sub render_resource { my $icon = ""; if ($resource->is_problem()) { - if ($part eq "" || $params->{'condensed'}) { + if ($part eq '0' || $params->{'condensed'}) { $icon = ''; } else { $icon = $params->{'indentString'}; @@ -908,7 +909,7 @@ sub render_resource { $params->{'displayedHereMarker'} = 1; } - if ($resource->is_problem() && $part ne "" && + if ($resource->is_problem() && $part ne '0' && !$params->{'condensed'}) { $partLabel = " (Part $part)"; $title = ""; @@ -965,6 +966,10 @@ sub render_communication_status { } } + if ($params->{'multipart'} && $part != '0') { + $discussionHTML = $feedbackHTML = $errorHTML = ''; + } + return "$discussionHTML$feedbackHTML$errorHTML "; } @@ -1000,7 +1005,7 @@ sub render_long_status { $params->{'multipart'} && $part eq "0"; my $color; - if ($resource->is_problem()) { + if ($resource->is_problem() && ($resource->countParts() <= 1 || $part ne '') ) { $color = $colormap{$resource->status}; if (dueInLessThen24Hours($resource, $part) || @@ -1020,8 +1025,6 @@ sub render_long_status { $result .= '(randomly select ' . $resource->randompick() .')'; } - $result .= " \n"; - return $result; } @@ -1373,7 +1376,7 @@ sub render { # Decide what parts to show. if ($curRes->is_problem() && $showParts) { @parts = @{$curRes->parts()}; - $args->{'multipart'} = scalar(@parts) > 1; + $args->{'multipart'} = $curRes->multipart(); if ($condenseParts) { # do the condensation if (!$curRes->opendate("0")) { @@ -1382,13 +1385,13 @@ sub render { } if (!$args->{'condensed'}) { # Decide whether to condense based on similarity - my $status = $curRes->status($parts[1]); - my $due = $curRes->duedate($parts[1]); - my $open = $curRes->opendate($parts[1]); + my $status = $curRes->status($parts[0]); + my $due = $curRes->duedate($parts[0]); + my $open = $curRes->opendate($parts[0]); my $statusAllSame = 1; my $dueAllSame = 1; my $openAllSame = 1; - for (my $i = 2; $i < scalar(@parts); $i++) { + for (my $i = 1; $i < scalar(@parts); $i++) { if ($curRes->status($parts[$i]) != $status){ $statusAllSame = 0; } @@ -1409,25 +1412,30 @@ sub render { if (($statusAllSame && defined($condenseStatuses{$status})) || ($dueAllSame && $status == $curRes->OPEN && $statusAllSame)|| ($openAllSame && $status == $curRes->OPEN_LATER && $statusAllSame) ){ - @parts = (); + @parts = ($parts[0]); $args->{'condensed'} = 1; } - } + # Multipart problem with one part: always "condense" (happens + # to match the desirable behavior) + if ($curRes->countParts() == 1) { + @parts = ($parts[0]); + $args->{'condensed'} = 1; + } } } # If the multipart problem was condensed, "forget" it was multipart if (scalar(@parts) == 1) { $args->{'multipart'} = 0; + } else { + # Add part 0 so we display it correctly. + unshift @parts, '0'; } # Now, we've decided what parts to show. Loop through them and # show them. - foreach my $part ('', @parts) { - if ($part eq '0') { - next; - } + foreach my $part (@parts) { $rownum ++; my $backgroundColor = $backgroundColors[$rownum % scalar(@backgroundColors)]; @@ -1587,7 +1595,14 @@ sub new { return undef; } - $self->{NAV_HASH} = \%navmaphash; + # try copying into memory + my %tmpnavhash; + while (my ($k, $v) = each(%navmaphash)) { + $tmpnavhash{$k} = $v; + } + untie %navmaphash; + + $self->{NAV_HASH} = \%tmpnavhash; $self->{PARM_HASH} = \%parmhash; $self->{INITED} = 0; @@ -1661,7 +1676,7 @@ sub init { my %emailstatus = &Apache::lonnet::dump('email_status'); my $logoutTime = $emailstatus{'logout'}; my $courseLeaveTime = $emailstatus{'logout_'.$ENV{'request.course.id'}}; - $self->{LAST_CHECK} = ($courseLeaveTime < $logoutTime ? + $self->{LAST_CHECK} = (($courseLeaveTime > $logoutTime) ? $courseLeaveTime : $logoutTime); my %discussiontime = &Apache::lonnet::dump('discussiontimes', $cdom, $cnum); @@ -1778,6 +1793,16 @@ object for that resource. This method, o (as in the resource object) is the only proper way to obtain a resource object. +=item * B(symb): + +Based on the symb of the resource, get a resource object for that +resource. This is one of the proper ways to get a resource object. + +=item * B(map_pc): + +Based on the map_pc of the resource, get a resource object for +the given map. This is one of the proper ways to get a resource object. + =cut # The strategy here is to cache the resource objects, and only construct them @@ -1808,6 +1833,14 @@ sub getBySymb { return $self->getById($map->map_pc() . '.' . $id); } +sub getByMapPc { + my $self = shift; + my $map_pc = shift; + my $map_id = $self->{NAV_HASH}->{'map_id_' . $map_pc}; + $map_id = $self->{NAV_HASH}->{'ids_' . $map_id}; + return $self->getById($map_id); +} + =pod =item * B(): @@ -3210,27 +3243,30 @@ sub getErrors { =item * B(): Returns a list reference containing sorted strings corresponding to -each part of the problem. To count the number of parts, use the list -in a scalar context, and subtract one if greater than two. (One part -problems have a part 0. Multi-parts have a part 0, plus a part for -each part. Filtering part 0 if you want it is up to you.) +each part of the problem. Single part problems have only a part '0'. +Multipart problems do not return their part '0', since they typically +do not really matter. =item * B(): Returns the number of parts of the problem a student can answer. Thus, for single part problems, returns 1. For multipart, it returns the -number of parts in the problem, not including psuedo-part 0. Thus, -B may return an array with more parts in it then countParts -might lead you to believe. +number of parts in the problem, not including psuedo-part 0. + +=item * B(): + +Returns true if the problem is multipart, false otherwise. Use this instead +of countParts if all you want is multipart/not multipart. =item * B($part): Returns the response type of the part, without the word "response" on the end. Example return values: 'string', 'essay', 'numeric', etc. -=item * B($part): +=item * B($part): -Retreives the response ID for the given part, which may be an empty string. +Retreives the response IDs for the given part as an array reference containing +strings naming the response IDs. This may be empty. =back @@ -3239,7 +3275,7 @@ Retreives the response ID for the given sub parts { my $self = shift; - if ($self->ext) { return ['0']; } + if ($self->ext) { return []; } $self->extractParts(); return $self->{PARTS}; @@ -3263,6 +3299,11 @@ sub countParts { return scalar(@{$parts}); # + $delta; } +sub multipart { + my $self = shift; + return $self->countParts() > 1; +} + sub responseType { my $self = shift; my $part = shift; @@ -3271,7 +3312,7 @@ sub responseType { return $self->{RESPONSE_TYPE}->{$part}; } -sub responseId { +sub responseIds { my $self = shift; my $part = shift;