Diff for /loncom/interface/lonnavmaps.pm between versions 1.107 and 1.115

version 1.107, 2002/11/15 17:30:33 version 1.115, 2002/11/26 14:45:24
Line 83  sub handler { Line 83  sub handler {
         return HTTP_NOT_ACCEPTABLE;          return HTTP_NOT_ACCEPTABLE;
     }      }
   
       $r->print("<html><head>\n");
       $r->print("<title>Navigate Course Contents</title>");
   
     # Header      # Header
     $r->print(&Apache::loncommon::bodytag('Navigate Course Map','',      $r->print(&Apache::loncommon::bodytag('Navigate Course Contents','',
                                           ''));                                            ''));
     $r->print('<script>window.focus();</script>');      $r->print('<script>window.focus();</script>');
   
Line 113  sub handler { Line 116  sub handler {
         $condition = 1;          $condition = 1;
     }      }
   
       my $currenturl = $ENV{'form.postdata'};
       $currenturl=~s/^http\:\/\///;
       $currenturl=~s/^[^\/]+//;
   
       # alreadyHere allows us to only open the maps necessary to view
       # the current location once, while at the same time remembering
       # the current location. Without that check, the user would never
       # be able to close those maps; the user would close it, and the
       # currenturl scan would re-open it.
       my $queryAdd = "postdata=" . &Apache::lonnet::escape($currenturl) .
           "&alreadyHere=1";
   
     if ($condition) {      if ($condition) {
         $r->print('<a href="navmaps?condition=0&filter=">Close All Folders</a>');          $r->print("<a href=\"navmaps?condition=0&filter=&$queryAdd\">Close All Folders</a>");
     } else {      } else {
         $r->print('<a href="navmaps?condition=1&filter=">Open All Folders</a>');          $r->print("<a href=\"navmaps?condition=1&filter=&$queryAdd\">Open All Folders</a>");
     }      }
   
     $r->print('<br>&nbsp;');      $r->print('<br>&nbsp;');
Line 143  sub handler { Line 158  sub handler {
     my %colormap =       my %colormap = 
     ( $res->NETWORK_FAILURE        => '',      ( $res->NETWORK_FAILURE        => '',
       $res->CORRECT                => '',        $res->CORRECT                => '',
       $res->EXCUSED                => '#BBBBFF',        $res->EXCUSED                => '#3333FF',
       $res->PAST_DUE_ANSWER_LATER  => '',        $res->PAST_DUE_ANSWER_LATER  => '',
       $res->PAST_DUE_NO_ANSWER     => '',        $res->PAST_DUE_NO_ANSWER     => '',
       $res->ANSWER_OPEN            => '#CCFFCC',        $res->ANSWER_OPEN            => '#006600',
       $res->OPEN_LATER             => '',        $res->OPEN_LATER             => '',
       $res->TRIES_LEFT             => '',        $res->TRIES_LEFT             => '',
       $res->INCORRECT              => '',        $res->INCORRECT              => '',
Line 156  sub handler { Line 171  sub handler {
     # is not yet done and due in less then 24 hours      # is not yet done and due in less then 24 hours
     my $hurryUpColor = "#FF0000";      my $hurryUpColor = "#FF0000";
   
       # Keep these mappings in sync with lonquickgrades, which uses the colors
       # instead of the icons.
     my %statusIconMap =       my %statusIconMap = 
         ( $res->NETWORK_FAILURE    => '',          ( $res->NETWORK_FAILURE    => '',
           $res->NOTHING_SET        => '',            $res->NOTHING_SET        => '',
Line 192  sub handler { Line 209  sub handler {
     # maps in their own folders, in favor of "inlining" them.      # maps in their own folders, in favor of "inlining" them.
     my $topResource = $navmap->getById("0.0");      my $topResource = $navmap->getById("0.0");
     my $inlineTopLevelMaps = $topResource->src() =~ m|^/uploaded/.*default\.sequence$|;      my $inlineTopLevelMaps = $topResource->src() =~ m|^/uploaded/.*default\.sequence$|;
       my $inlinedelta = $inlineTopLevelMaps? -1 : 0;
     my $currenturl = $ENV{'form.postdata'};  
     $currenturl=~s/^http\:\/\///;  
     $currenturl=~s/^[^\/]+//;  
   
     # alreadyHere allows us to only open the maps necessary to view  
     # the current location once, while at the same time remembering  
     # the current location. Without that check, the user would never  
     # be able to close those maps; the user would close it, and the  
     # currenturl scan would re-open it.  
     my $queryAdd = "postdata=" . &Apache::lonnet::escape($currenturl) .  
         "&alreadyHere=1";  
   
     # 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
Line 285  sub handler { Line 291  sub handler {
                                            $condition);                                             $condition);
     $mapIterator->next();      $mapIterator->next();
     $curRes = $mapIterator->next();      $curRes = $mapIterator->next();
     my $deltadepth = 0;  
     $depth = 1;      $depth = 1;
   
     my @backgroundColors = ("#FFFFFF", "#F6F6F6");      my @backgroundColors = ("#FFFFFF", "#F6F6F6");
Line 299  sub handler { Line 304  sub handler {
     }      }
   
     while ($depth > 0) {      while ($depth > 0) {
         # If this is an inlined map, cancel the shift to the right,  
         # which has the effect of making the map look inlined  
         if ($inlineTopLevelMaps && scalar(@{$mapIterator->getStack()}) == 1 &&  
             ref($curRes) && $curRes->is_map()) {  
             $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 324  sub handler { Line 320  sub handler {
   
         if (ref($curRes)) { $counter++; }          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 ignored because it is in a random-out          # Is this resource being ignored because it is in a random-out
         # map and it was not selected?          # map and it was not selected?
         if (ref($curRes) && !advancedUser() && $curRes->randomout()) {          if (ref($curRes) && !advancedUser() && $curRes->randomout()) {
Line 336  sub handler { Line 329  sub handler {
   
         if (ref($curRes) && $curRes->src()) {          if (ref($curRes) && $curRes->src()) {
   
               my $deltalevel = $isNewBranch? 1 : 0; # reserves space for branch icon
   
               if ($indentLevel - $deltalevel + $inlinedelta < 0) {
                   # If this would be at a negative depth (top-level maps in
                   # new-style courses, we want to suppress their title display)
                   # then ignore it.
                   $curRes = $mapIterator->next();
                   next;
               }
   
             # Step one: Decide which parts to show              # Step one: Decide which parts to show
             my @parts = @{$curRes->parts()};              my @parts = @{$curRes->parts()};
             my $multipart = scalar(@parts) > 1;              my $multipart = scalar(@parts) > 1;
Line 421  sub handler { Line 424  sub handler {
             # For each part we intend to display...              # For each part we intend to display...
             foreach my $part (@parts) {              foreach my $part (@parts) {
   
                 my $deltalevel = 0; # for inserting the branch icon  
                 my $nonLinkedText = ""; # unlinked stuff after title                  my $nonLinkedText = ""; # unlinked stuff after title
                                   
                 my $stack = $mapIterator->getStack();                  my $stack = $mapIterator->getStack();
Line 443  sub handler { Line 445  sub handler {
                 if ($isNewBranch) {                  if ($isNewBranch) {
                     $newBranchText = "<img src=\"/adm/lonIcons/branch.gif\" border=\"0\">";                      $newBranchText = "<img src=\"/adm/lonIcons/branch.gif\" border=\"0\">";
                     $isNewBranch = 0;                      $isNewBranch = 0;
                     $deltalevel = 1; # reserves space for the branch icon  
                 }                  }
   
                 # links to open and close the folders                  # links to open and close the folders
Line 479  sub handler { Line 480  sub handler {
                 my $colorizer = "";                  my $colorizer = "";
                 my $color;                  my $color;
                 if ($curRes->is_problem()) {                  if ($curRes->is_problem()) {
                     my $status = $curRes->status($part);                      $color = $colormap{$curRes->status};
                     $color = $colormap{$status};  
   
                     # Special case in the navmaps: If in less then                      if (dueInLessThen24Hours($curRes, $part) ||
                     # 24 hours, give it a bit of urgency                          lastTry($curRes, $part)) {
                     if (($status == $curRes->OPEN() || $status == $curRes->ATTEMPTED() ||  
                          $status == $curRes->TRIES_LEFT())  
                         && $curRes->duedate() &&  
                         $curRes->duedate() < time()+(24*60*60) &&   
                         $curRes->duedate() > time()) {  
                         $color = $hurryUpColor;  
                     }  
                     # Special case: If this is the last try, and there is  
                     # more then one available, and it's not due yet, give a bit of urgency  
                     my $tries = $curRes->tries($part);  
                     my $maxtries = $curRes->maxtries($part);  
                     if ($tries && $maxtries && $maxtries > 1 &&  
                         $maxtries - $tries == 1 && $curRes->duedate() &&  
                         $curRes->duedate() > time()) {  
                         $color = $hurryUpColor;                          $color = $hurryUpColor;
                     }                      }
   
                     if ($color ne "") {                      if ($color ne "") {
                         $colorizer = "bgcolor=\"$color\"";                          $colorizer = "bgcolor=\"$color\"";
                     }                      }
Line 521  sub handler { Line 508  sub handler {
                 }                  }
   
                 # print indentation                  # print indentation
                 for (my $i = 0; $i < $indentLevel - $deltalevel + $deltadepth; $i++) {                  for (my $i = 0; $i < $indentLevel - $deltalevel + $inlinedelta; $i++) {
                     $r->print($indentString);                      $r->print($indentString);
                 }                  }
   
                 $r->print("  ${newBranchText}${linkopen}$icon${linkclose}\n");                  $r->print("  ${newBranchText}${linkopen}$icon${linkclose}\n");
                 #$r->print($curRes->awarded($part));  
   
                 my $curMarkerBegin = "";                  my $curMarkerBegin = "";
                 my $curMarkerEnd = "";                  my $curMarkerEnd = "";
Line 553  sub handler { Line 539  sub handler {
                                               '<font size="-1">Host down</font>'));                                                '<font size="-1">Host down</font>'));
                     }                      }
   
                   $r->print("</td>\n");
   
                 # SECOND COL: Is there text, feedback, errors??                  # SECOND COL: Is there text, feedback, errors??
                 my $discussionHTML = ""; my $feedbackHTML = "";                  my $discussionHTML = ""; my $feedbackHTML = "";
   
Line 611  sub handler { Line 599  sub handler {
                 }                  }
   
                 $r->print("&nbsp;</td></tr>\n");                  $r->print("&nbsp;</td></tr>\n");
   
                   if (!($counter % 20)) { $r->rflush(); }
                   if ($counter == 2) { $r->rflush(); }
             }              }
         }          }
         $curRes = $mapIterator->next();          $curRes = $mapIterator->next();
Line 728  sub getDescription { Line 719  sub getDescription {
     }      }
 }  }
   
   # Convenience function, so others can use it: Is the problem due in less then
   # 24 hours, and still can be done?
   
   sub dueInLessThen24Hours {
       my $res = shift;
       my $part = shift;
       my $status = $res->status($part);
   
       return ($status == $res->OPEN() || $status == $res->ATTEMPTED() ||
               $status == $res->TRIES_LEFT()) &&
              $res->duedate() && $res->duedate() < time()+(24*60*60) &&
              $res->duedate() > time();
   }
   
   # Convenience function, so others can use it: Is there only one try remaining for the
   # part, with more then one try to begin with, not due yet and still can be done?
   sub lastTry {
       my $res = shift;
       my $part = shift;
   
       my $tries = $res->tries($part);
       my $maxtries = $res->maxtries($part);
       return $tries && $maxtries && $maxtries > 1 &&
           $maxtries - $tries == 1 && $res->duedate() &&
           $res->duedate() > time();
   }
   
 # This puts a human-readable name on the ENV variable.  # This puts a human-readable name on the ENV variable.
 sub advancedUser {  sub advancedUser {
     return $ENV{'user.adv'};      return $ENV{'user.adv'};
Line 893  sub new { Line 911  sub new {
               &GDBM_READER(), 0640))) {                &GDBM_READER(), 0640))) {
         return undef;          return undef;
     }      }
     $self->{NAV_HASH} = \%navmaphash;  
           
     my %parmhash;      my %parmhash;
     if (!(tie(%parmhash, 'GDBM_File', $self->{PARM_HASH_FILE},      if (!(tie(%parmhash, 'GDBM_File', $self->{PARM_HASH_FILE},
Line 902  sub new { Line 919  sub new {
         untie $self->{PARM_HASH};          untie $self->{PARM_HASH};
         return undef;          return undef;
     }      }
     $self->{PARM_HASH} = \%parmhash;  
     $self->{HASH_TIED} = 1;      # Now copy the hashes for speed (?)
       my %realnav; my %realparm;
       foreach (%navmaphash) { $realnav{$_} = $navmaphash{$_}; }
       foreach (%parmhash) { $realparm{$_} = $navmaphash{$_}; }
       $self->{NAV_HASH} = \%realnav;
       $self->{PARM_HASH} = \%realparm;
   
     bless($self);      bless($self);
       $self->untieHashes();
                   
     return $self;      return $self;
 }  }
Line 1019  sub init { Line 1042  sub init {
     $self->{PARM_CACHE} = {};      $self->{PARM_CACHE} = {};
 }  }
   
   # Internal function: Takes a key to look up in the nav hash and implements internal
   # memory caching of that key.
   sub navhash {
       my $self = shift; my $key = shift;
       return $self->{NAV_HASH}->{$key};
   }
   
 # Checks to see if coursemap is defined, matching test in old lonnavmaps  # Checks to see if coursemap is defined, matching test in old lonnavmaps
 sub courseMapDefined {  sub courseMapDefined {
     my $self = shift;      my $self = shift;
     my $uri = &Apache::lonnet::clutter($ENV{'request.course.uri'});      my $uri = &Apache::lonnet::clutter($ENV{'request.course.uri'});
   
     my $firstres = $self->{NAV_HASH}->{"map_start_$uri"};      my $firstres = $self->navhash("map_start_$uri");
     my $lastres = $self->{NAV_HASH}->{"map_finish_$uri"};      my $lastres = $self->navhash("map_finish_$uri");
     return $firstres && $lastres;      return $firstres && $lastres;
 }  }
   
Line 1105  sub getById { Line 1135  sub getById {
   
 sub firstResource {  sub firstResource {
     my $self = shift;      my $self = shift;
     my $firstResource = $self->{NAV_HASH}->{'map_start_' .      my $firstResource = $self->navhash('map_start_' .
                      &Apache::lonnet::clutter($ENV{'request.course.uri'})};                       &Apache::lonnet::clutter($ENV{'request.course.uri'}));
     return $self->getById($firstResource);      return $self->getById($firstResource);
 }  }
   
Line 1118  sub firstResource { Line 1148  sub firstResource {
   
 sub finishResource {  sub finishResource {
     my $self = shift;      my $self = shift;
     my $firstResource = $self->{NAV_HASH}->{'map_finish_' .      my $firstResource = $self->navhash('map_finish_' .
                      &Apache::lonnet::clutter($ENV{'request.course.uri'})};                       &Apache::lonnet::clutter($ENV{'request.course.uri'}));
     return $self->getById($firstResource);      return $self->getById($firstResource);
 }  }
   
Line 1510  sub next { Line 1540  sub next {
     # BC branch and gets to C, it will see F as the only next resource, but it's      # BC branch and gets to C, it will see F as the only next resource, but it's
     # one level lower. Thus, this is the end of the branch, since there are no      # one level lower. Thus, this is the end of the branch, since there are no
     # more resources added to this level or above.      # more resources added to this level or above.
       # We don't do this if the examined resource is the finish resource,
       # because the condition given above is true, but the "END_MAP" will
       # take care of things and we should already be at depth 0.
     my $isEndOfBranch = $maxDepthAdded < $self->{CURRENT_DEPTH};      my $isEndOfBranch = $maxDepthAdded < $self->{CURRENT_DEPTH};
     if ($isEndOfBranch) { # **9**      if ($isEndOfBranch && $here != $self->{FINISH_RESOURCE}) { # **9**
         push @{$self->{STACK}->[$self->{CURRENT_DEPTH}]}, END_BRANCH();          push @{$self->{STACK}->[$self->{CURRENT_DEPTH}]}, END_BRANCH();
     }      }
   
Line 1775  sub navHash { Line 1808  sub navHash {
     my $self = shift;      my $self = shift;
     my $param = shift;      my $param = shift;
     my $id = shift;      my $id = shift;
     return $self->{NAV_MAP}->{NAV_HASH}->{$param . ($id?$self->{ID}:"")};      return $self->{NAV_MAP}->navhash($param . ($id?$self->{ID}:""));
 }  }
   
 =pod  =pod
Line 2005  sub answerdate { Line 2038  sub answerdate {
     }      }
     return $self->parmval("answerdate", $part);      return $self->parmval("answerdate", $part);
 }  }
 sub awarded {  sub awarded { my $self = shift; return $self->queryRestoreHash('awarded', shift); }
     (my $self, my $part) = @_;  
     return $self->parmval("awarded", $part);  
 }  
 sub duedate {  sub duedate {
     (my $self, my $part) = @_;      (my $self, my $part) = @_;
     return $self->parmval("duedate", $part);      return $self->parmval("duedate", $part);
Line 2033  sub tol { Line 2063  sub tol {
     (my $self, my $part) = @_;      (my $self, my $part) = @_;
     return $self->parmval("tol", $part);      return $self->parmval("tol", $part);
 }  }
 sub tries {  sub tries { 
     my $self = shift;      my $self = shift; 
     my $part = shift;      my $tries = $self->queryRestoreHash('tries', shift);
     $part = '0' if (!defined($part));      if (!defined($tries)) { return '0';}
   
     # Make sure return hash is loaded, should error check  
     $self->getReturnHash();  
       
     my $tries = $self->{RETURN_HASH}->{'resource.'.$part.'.tries'};  
     if (!defined($tries)) {return '0';}  
     return $tries;      return $tries;
 }  }
 sub type {  sub type {
     (my $self, my $part) = @_;      (my $self, my $part) = @_;
     return $self->parmval("type", $part);      return $self->parmval("type", $part);
 }  }
 sub weight {  sub weight { 
     (my $self, my $part) = @_;      my $self = shift; my $part = shift;
     return $self->parmval("weight", $part);      return $self->parmval("weight", $part);
 }  }
   
Line 2312  sub ATTEMPTED             { return 16; } Line 2336  sub ATTEMPTED             { return 16; }
   
 sub getCompletionStatus {  sub getCompletionStatus {
     my $self = shift;      my $self = shift;
     my $part = shift;  
     $part = "0" if (!defined($part));  
     return $self->NETWORK_FAILURE if ($self->{NAV_MAP}->{NETWORK_FAILURE});      return $self->NETWORK_FAILURE if ($self->{NAV_MAP}->{NETWORK_FAILURE});
   
     # Make sure return hash exists      my $status = $self->queryRestoreHash('solved', shift);
     $self->getReturnHash();  
       
     my $status = $self->{RETURN_HASH}->{'resource.'.$part.'.solved'};  
   
     # Left as seperate if statements in case we ever do more with this      # Left as seperate if statements in case we ever do more with this
     if ($status eq 'correct_by_student') {return $self->CORRECT;}      if ($status eq 'correct_by_student') {return $self->CORRECT;}
Line 2331  sub getCompletionStatus { Line 2350  sub getCompletionStatus {
     return $self->NOT_ATTEMPTED;      return $self->NOT_ATTEMPTED;
 }  }
   
   sub queryRestoreHash {
       my $self = shift;
       my $hashentry = shift;
       my $part = shift;
       $part = "0" if (!defined($part));
       return $self->NETWORK_FAILURE if ($self->{NAV_MAP}->{NETWORK_FAILURE});
   
       $self->getReturnHash();
   
       return $self->{RETURN_HASH}->{'resource.'.$part.'.'.$hashentry};
   }
   
 =pod  =pod
   
 B<Composite Status>  B<Composite Status>
Line 2456  sub getNext { Line 2487  sub getNext {
   
         # Don't remember it if the student doesn't have browse priviledges          # Don't remember it if the student doesn't have browse priviledges
         # future note: this may properly belong in the client of the resource          # future note: this may properly belong in the client of the resource
         my $browsePriv = &Apache::lonnet::allowed('bre', $self->src);          my $browsePriv = $self->{BROWSE_PRIV};
           if (!defined($browsePriv)) {
               $browsePriv = &Apache::lonnet::allowed('bre', $self->src);
               $self->{BROWSE_PRIV} = $browsePriv;
           }
         if (!($browsePriv ne '2' && $browsePriv ne 'F')) {          if (!($browsePriv ne '2' && $browsePriv ne 'F')) {
             push @branches, $next;              push @branches, $next;
         }          }
Line 2475  sub getPrevious { Line 2510  sub getPrevious {
   
         # Don't remember it if the student doesn't have browse priviledges          # Don't remember it if the student doesn't have browse priviledges
         # future note: this may properly belong in the client of the resource          # future note: this may properly belong in the client of the resource
         my $browsePriv = &Apache::lonnet::allowed('bre', $self->src);          my $browsePriv = $self->{BROWSE_PRIV};
           if (!defined($browsePriv)) {
               $browsePriv = &Apache::lonnet::allowed('bre', $self->src);
               $self->{BROWSE_PRIV} = $browsePriv;
           }
         if (!($browsePriv ne '2' && $browsePriv ne 'F')) {          if (!($browsePriv ne '2' && $browsePriv ne 'F')) {
             push @branches, $prev;              push @branches, $prev;
         }          }

Removed from v.1.107  
changed lines
  Added in v.1.115


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