Diff for /loncom/interface/lonnavmaps.pm between versions 1.60 and 1.65

version 1.60, 2002/10/01 19:39:11 version 1.65, 2002/10/04 15:38:22
Line 819  sub new_handle { Line 819  sub new_handle {
     &Apache::loncommon::no_cache($r);      &Apache::loncommon::no_cache($r);
     $r->send_http_header;      $r->send_http_header;
   
     # Header  
     $r->print(&Apache::loncommon::bodytag('Navigate Course Map','',  
                                           ''));  
     # Initialize the nav map      # Initialize the nav map
     my $navmap = Apache::lonnavmaps::navmap->new(      my $navmap = Apache::lonnavmaps::navmap->new(
                         $ENV{"request.course.fn"}.".db",                          $ENV{"request.course.fn"}.".db",
Line 834  sub new_handle { Line 831  sub new_handle {
         return HTTP_NOT_ACCEPTABLE;          return HTTP_NOT_ACCEPTABLE;
     }      }
   
       # Header
       $r->print(&Apache::loncommon::bodytag('Navigate Course Map','',
                                             ''));
       $r->print('<script>window.focus();</script>');
       my $desc=$ENV{'course.'.$ENV{'request.course.id'}.'.description'};
       if (defined($desc)) { $r->print("<h2>$desc</h2>\n"); }
       my $date=localtime;
       $r->print("<h3>$date</h3>\n");
       $r->rflush();
       if ($navmap->{LAST_CHECK}) {
    $r->print('<img src="/adm/lonMisc/chat.gif"> New discussion since '.
     timeToHumanString($navmap->{LAST_CHECK}).
     '<br><img src="/adm/lonMisc/feedback.gif"> New message (click to open)<p>'); 
       } else {
    $r->print('<img src="/adm/lonMisc/chat.gif"> Discussions'.
     '<br><img src="/adm/lonMisc/feedback.gif"> New message (click to open)<p>'); 
       }
       #if (($currenturl=~/^\/res/) &&
       #    ($currenturl!~/^\/res\/adm/)) {
       #    $r->print('<a href="#curloc">Current Location</a><p>');
       #}
   
     # Check that it's defined      # Check that it's defined
     if (!($navmap->courseMapDefined())) {      if (!($navmap->courseMapDefined())) {
         $r->print('<font size="+2" color="red">Coursemap undefined.</font>' .          $r->print('<font size="+2" color="red">Coursemap undefined.</font>' .
Line 878  sub new_handle { Line 897  sub new_handle {
     my %condenseStatuses =      my %condenseStatuses =
  ( $res->NETWORK_FAILURE    => 1,   ( $res->NETWORK_FAILURE    => 1,
   $res->NOTHING_SET        => 1,    $res->NOTHING_SET        => 1,
   $res->CORRECT            => 1,    $res->CORRECT            => 1 );
   $res->OPEN               => 1 );  
   
     my %filterHash;      my %filterHash;
     # Figure out what we're not displaying      # Figure out what we're not displaying
Line 889  sub new_handle { Line 907  sub new_handle {
         }          }
     }      }
   
       my $currenturl = $ENV{'form.postdata'};
       $currenturl=~s/^http\:\/\///;
       $currenturl=~s/^[^\/]+//;
       my $queryAdd = "postdata=" . &Apache::lonnet::escape($currenturl);
   
       $r->print("$currenturl<br/>");
       
   
     # 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
     $r->print('<table cellspacing="3" cellpadding="0" bgcolor="#FFFFFF">' ."\n");      $r->print('<table cellspacing="3" cellpadding="0" bgcolor="#FFFFFF">' ."\n");
   
     my $mapIterator = $navmap->getIterator(undef, undef, \%filterHash);      my $mapIterator = $navmap->getIterator(undef, undef, \%filterHash, 0);
     my $curRes = $mapIterator->next();      my $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 = -1;      my $indentLevel = -1;
     my $indentString = "<img src=\"/adm/lonIcons/whitespace1.gif\" width=\"25\" height=\"1\"/>";      my $indentString = "<img src=\"/adm/lonIcons/whitespace1.gif\" width=\"25\" height=\"1\" alt=\"\" border=\"0\" />";
   
     my $isNewBranch = 0;      my $isNewBranch = 0;
     my $now = time();      my $now = time();
Line 919  sub new_handle { Line 945  sub new_handle {
         if (ref($curRes) && $curRes->src()) {          if (ref($curRes) && $curRes->src()) {
   
     # Step one: Decide which parts to show      # Step one: Decide which parts to show
             my @parts;      my @parts = @{$curRes->parts()};
       my $multipart = scalar(@parts) > 1;
       my $condensed = 0;
   
             if ($curRes->is_problem()) {              if ($curRes->is_problem()) {
  # Is it multipart?   # Is it multipart?
                 @parts = @{$curRes->parts()};  
   
  my $multipart = scalar(@parts) > 1;  
   
  if ($multipart) {   if ($multipart) {
     # If it's multipart, see if part 0 is "open"      # If it's multipart, see if part 0 is "open"
     # if it is, display all parts, if it isn't,      # if it is, display all parts, if it isn't,
Line 935  sub new_handle { Line 961  sub new_handle {
     } else {      } else {
  # Otherwise, only display part 0 if we want to    # Otherwise, only display part 0 if we want to 
  # attach feedback or email information to it   # attach feedback or email information to it
  if (!$curRes->hasDiscussion() && !$curRes->getFeedback()) {   if ($curRes->hasDiscussion() || $curRes->getFeedback()) {
     shift @parts;      shift @parts;
  } else {   } else {
     # If there's discussion or feedback, that counts      # If there's discussion or feedback, that counts
Line 943  sub new_handle { Line 969  sub new_handle {
           
     # Now, we decide whether to condense the      # Now, we decide whether to condense the
     # parts due to similarity      # parts due to similarity
     my $status = $curRes->status($parts[0]);      my $status = $curRes->status($parts[1]);
     my $allSame = 1;      my $due = $curRes->duedate($parts[1]);
     for (my $i = 1; $i < scalar(@parts); $i++) {      my $open = $curRes->opendate($parts[1]);
       my $statusAllSame = 1;
       my $dueAllSame = 1;
       my $openAllSame = 1;
       for (my $i = 2; $i < scalar(@parts); $i++) {
  if ($curRes->status($parts[$i]) != $status){   if ($curRes->status($parts[$i]) != $status){
     $allSame = 0;      $statusAllSame = 0;
    }
    if ($curRes->duedate($parts[$i]) != $due ) {
       $dueAllSame = 0;
    }
    if ($curRes->opendate($parts[$i]) != $open) {
       $openAllSame = 0;
  }   }
     }      }
           
     # $allSame is true if all the statuses were      # $allSame is true if all the statuses were
     # the same. Now, if they are all the same and      # the same. Now, if they are all the same and
     # match one of the statuses to condense, then      # match one of the statuses to condense, or they
     # only display part 0.      # are all open with the same due date, or they are
     if ($allSame && defined($condenseStatuses{$status})){      # all OPEN_LATER with the same open date, display the
  @parts = ("0");      # status of the first non-zero part (to get the 'correct'
       # status right, since 0 is never 'correct' or 'open').
       if (($statusAllSame && defined($condenseStatuses{$status})) ||
    ($dueAllSame && $status == $curRes->OPEN && $statusAllSame)||
    ($openAllSame && $status == $curRes->OPEN_LATER && $statusAllSame) ){
    @parts = ($parts[1]);
    $condensed = 1;
     }      }
  }   }
     }      }
Line 999  sub new_handle { Line 1041  sub new_handle {
                 my $linkopen = "<a href=\"$link\">";                  my $linkopen = "<a href=\"$link\">";
                 my $linkclose = "</a>";                  my $linkclose = "</a>";
   
                 my $icon = "html.gif";                  my $icon = "<img src=\"/adm/lonIcons/html.gif\" alt=\"\" border=\"0\" />";
                 if ($curRes->is_problem()) {                   if ($curRes->is_problem()) { 
                     $icon = "problem.gif";       if ($part eq "0" || $condensed) {
    $icon = '<img src="/adm/lonIcons/problem.gif" alt="" border=\"0\" />'; 
       } else {
    $icon = $indentString;
       }
                 }                  }
   
                 # Display the correct icon, link to open or shut map                  # Display the correct icon, link to open or shut map
Line 1009  sub new_handle { Line 1055  sub new_handle {
                     my $mapId = $curRes->map_pc();                      my $mapId = $curRes->map_pc();
                     my $nowOpen = !defined($filterHash{$mapId});                      my $nowOpen = !defined($filterHash{$mapId});
                     $icon = $nowOpen ?                      $icon = $nowOpen ?
                         "folder_opened.gif" : "folder_closed.gif";                          "folder_closed.gif" : "folder_opened.gif";
       $icon = "<img src=\"/adm/lonIcons/$icon\" alt=\"\" border=\"0\" />";
                     $linkopen = "<a href=\"/adm/navmaps?filter=";                      $linkopen = "<a href=\"/adm/navmaps?filter=";
                     $linkopen .= $nowOpen ?                       $linkopen .= $nowOpen ? 
                         addToFilter(\%filterHash, $mapId) :                          addToFilter(\%filterHash, $mapId) :
                         removeFromFilter(\%filterHash, $mapId);                          removeFromFilter(\%filterHash, $mapId);
                     $linkopen .= "\">";                      $linkopen .= "&$queryAdd\">";
                     $linkclose = "</a>";                      $linkclose = "</a>";
                                           
                 }                  }
Line 1036  sub new_handle { Line 1083  sub new_handle {
                     $r->print($indentString);                      $r->print($indentString);
                 }                  }
   
                 $r->print("  ${newBranchText}${linkopen}<img border=\"0\" src=\"" .                  $r->print("  ${newBranchText}${linkopen}$icon${linkclose}\n");
                           "/adm/lonIcons/$icon\" alt=\"\">${linkclose}\n");  
   
                 if ($curRes->is_problem() && $part != "0") { $partLabel = " (Part $part)"; }                  if ($curRes->is_problem() && $part != "0" && !$condensed) { 
       $partLabel = " (Part $part)"; 
       $title = "";
    }
   
                 $r->print("  <a href=\"$link\">$title$partLabel</a></td>");                  $r->print("  <a href=\"$link\">$title$partLabel</a></td>");
   
Line 1066  sub new_handle { Line 1115  sub new_handle {
   
  $r->print("<td align=\"left\">$discussionHTML$feedbackHTML</td>");   $r->print("<td align=\"left\">$discussionHTML$feedbackHTML</td>");
   
    # Is this the first displayed part of a multi-part problem
    # that has not been condensed, so we should suppress these two
    # columns?
    my $firstDisplayed = !$condensed && $multipart && $part eq "0";
   
  # THIRD ROW: Problem status icon   # THIRD ROW: Problem status icon
  if ($curRes->is_problem()) {   if ($curRes->is_problem() &&
     my $icon = $statusIconMap{$curRes->status()};      !$firstDisplayed) {
       my $icon = $statusIconMap{$curRes->status($part)};
     if ($icon) {      if ($icon) {
  $r->print("<td width=\"50\" align=\"right\">$linkopen<img src=\"/adm/lonIcons/$icon\" border=\"0\" />$linkclose</td>\n");   $r->print("<td width=\"50\" align=\"right\">$linkopen<img src=\"/adm/lonIcons/$icon\" border=\"0\" />$linkclose</td>\n");
     } else {      } else {
Line 1081  sub new_handle { Line 1136  sub new_handle {
   # FOURTH ROW: Text description    # FOURTH ROW: Text description
  $r->print("<td $colorizer align=\"right\">\n");   $r->print("<td $colorizer align=\"right\">\n");
                                   
                 if ($curRes->kind() eq "res" and                   if ($curRes->kind() eq "res" &&
                     $curRes->is_problem() ) {                      $curRes->is_problem() &&
       !$firstDisplayed) {
                     $r->print (getDescription($curRes, $part));                      $r->print (getDescription($curRes, $part));
                 }                  }
   
Line 1399  sub courseMapDefined { Line 1455  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, shift);                                                       shift, undef, shift);
     return $iterator;      return $iterator;
 }  }
   
Line 1608  getIterator behaves as follows: Line 1664  getIterator behaves as follows:
   
 =over 4  =over 4
   
 =item B<getIterator>(nav_map, firstResource, finishResource, filterHash): 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(). It is your responsibility to ensure that the iterator will actually get there. 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 1, then only resource that exist IN the filterHash will be recursed on. If it is a 0, only resources NOT in the filterHash will be recursed on. Defaults to 0.  =item B<getIterator>(nav_map, 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(). It is your responsibility to ensure that the iterator will actually get there. 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.
   
 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.  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.
   
Line 1660  sub new { Line 1716  sub new {
     # A hash, used as a set, of resource already seen      # A hash, used as a set, of resource already seen
     $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;
   
     # 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 1830  sub next { Line 1887  sub next {
   
     # If this is a map and we want to recurse down it... (not filtered out)      # 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() && 
          !defined($self->{FILTER}->{$self->{HERE}->map_pc()})) {            (defined($self->{FILTER}->{$self->{HERE}->map_pc()}) xor $self->{CONDITION})) { 
         $self->{RECURSIVE_ITERATOR_FLAG} = 1;          $self->{RECURSIVE_ITERATOR_FLAG} = 1;
         my $firstResource = $self->{HERE}->map_start();          my $firstResource = $self->{HERE}->map_start();
         my $finishResource = $self->{HERE}->map_finish();          my $finishResource = $self->{HERE}->map_finish();
Line 1840  sub next { Line 1897  sub next {
         # isn't MAIN::new, __PACKAGE__::new or Apache::lonnavmaps::iterator->new          # isn't MAIN::new, __PACKAGE__::new or Apache::lonnavmaps::iterator->new
         $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},
         # prime the new iterator with the first resource       $self->{CONDITION});
         #push @{$self->{RECURSIVE_ITERATOR}->{BRANCH_STACK}}, $firstResource;  
     }      }
   
     return $self->{HERE};      return $self->{HERE};
Line 2509  sub getNext { Line 2565  sub getNext {
         my $next = $choice->goesto();          my $next = $choice->goesto();
         $next = $self->{NAV_MAP}->getById($next);          $next = $self->{NAV_MAP}->getById($next);
   
         # Don't remember it if we've already seen it          # Don't remember it if we've already seen it or if
    # the student doesn't have browse priviledges
    my $browsePriv = &Apache::lonnet::allowed('bre', $self->src);
         if (!defined($alreadySeenHash) ||          if (!defined($alreadySeenHash) ||
             !defined($alreadySeenHash->{$next->{ID}})) {              !defined($alreadySeenHash->{$next->{ID}}) ||
       ($browsePriv ne '2' && $browsePriv ne 'F')) {
                 push @branches, $next;                  push @branches, $next;
             }              }
     }      }

Removed from v.1.60  
changed lines
  Added in v.1.65


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>