Diff for /loncom/interface/lonnavmaps.pm between versions 1.430 and 1.450

version 1.430, 2009/02/25 21:06:27 version 1.450, 2010/08/12 16:03:24
Line 2 Line 2
 # Navigate Maps Handler  # Navigate Maps Handler
 #  #
 # $Id$  # $Id$
   
 #  #
 # Copyright Michigan State University Board of Trustees  # Copyright Michigan State University Board of Trustees
 #  #
Line 31 Line 32
   
 =head1 NAME  =head1 NAME
   
 Apache::lonnavmaps.pm  Apache::lonnavmaps - Subroutines to handle and render the navigation
   
 =head1 SYNOPSIS  =head1 SYNOPSIS
   
Line 477  use Apache::loncommon(); Line 478  use Apache::loncommon();
 use Apache::lonenc();  use Apache::lonenc();
 use Apache::lonlocal;  use Apache::lonlocal;
 use Apache::lonnet;  use Apache::lonnet;
   
 use POSIX qw (floor strftime);  use POSIX qw (floor strftime);
 use Time::HiRes qw( gettimeofday tv_interval );  use Time::HiRes qw( gettimeofday tv_interval );
 use LONCAPA;  use LONCAPA;
Line 491  sub NOTHING { return 3; } Line 493  sub NOTHING { return 3; }
   
 my $resObj = "Apache::lonnavmaps::resource";  my $resObj = "Apache::lonnavmaps::resource";
   
 # Keep these mappings in sync with lonquickgrades, which uses the colors  # Keep these mappings in sync with lonquickgrades, which usesthe colors
 # instead of the icons.  # instead of the icons.
 my %statusIconMap =   my %statusIconMap = 
     (      (
Line 504  my %statusIconMap = Line 506  my %statusIconMap =
      $resObj->ERROR        => ''       $resObj->ERROR        => ''
      );       );
   
 my %iconAltTags =   my %iconAltTags =   #texthash does not work here
     ( 'navmap.correct.gif' => 'Correct',      ( 'navmap.correct.gif'  => 'Correct',
       'navmap.wrong.gif'   => 'Incorrect',        'navmap.wrong.gif'    => 'Incorrect',
       'navmap.open.gif'    => 'Open' );        'navmap.open.gif'     => 'Open',
         'navmap.partial.gif'  => 'Partially Correct',
         'navmap.ellipsis.gif' => 'Attempted',
        );
   
 # Defines a status->color mapping, null string means don't color  # Defines a status->color mapping, null string means don't color
 my %colormap =   my %colormap = 
Line 523  my %colormap = Line 528  my %colormap =
       $resObj->OPEN                   => '',        $resObj->OPEN                   => '',
       $resObj->NOTHING_SET            => '',        $resObj->NOTHING_SET            => '',
       $resObj->ATTEMPTED              => '',        $resObj->ATTEMPTED              => '',
         $resObj->CREDIT_ATTEMPTED       => '',
       $resObj->ANSWER_SUBMITTED       => '',        $resObj->ANSWER_SUBMITTED       => '',
       $resObj->PARTIALLY_CORRECT      => '#006600'        $resObj->PARTIALLY_CORRECT      => '#006600'
       );        );
Line 530  my %colormap = Line 536  my %colormap =
 # is not yet done and due in less than 24 hours  # is not yet done and due in less than 24 hours
 my $hurryUpColor = "#FF0000";  my $hurryUpColor = "#FF0000";
   
 sub close {  my $future_slots_checked = 0;
     if ($env{'environment.remotenavmap'} ne 'on') { return ''; }  my $future_slots = 0;
     return(<<ENDCLOSE);  
 <script type="text/javascript">  
 window.status='Accessing Nav Control';  
 menu=window.open("/adm/rat/empty.html","loncapanav",  
                  "height=600,width=400,scrollbars=1");  
 window.status='Closing Nav Control';  
 menu.close();  
 window.status='Done.';  
 </script>  
 ENDCLOSE  
 }  
   
 sub update {  
     if ($env{'environment.remotenavmap'} ne 'on') { return ''; }  
     if (!$env{'request.course.id'}) { return ''; }  
     if ($ENV{'REQUEST_URI'}=~m|^/adm/navmaps|) { return ''; }  
     return(<<ENDUPDATE);  
 <form name="navform"></form>  
 <script type="text/javascript">  
 this.document.navform.action='/adm/navmaps#curloc';  
 this.document.navform.target='loncapanav';  
 this.document.navform.submit();  
 </script>  
 ENDUPDATE  
 }  
   
   
 sub addToFilter {  sub addToFilter {
     my $hashIn = shift;      my $hashIn = shift;
Line 594  sub getLinkForResource { Line 574  sub getLinkForResource {
     my ($map,$id,$src)=&Apache::lonnet::decode_symb($res->symb());      my ($map,$id,$src)=&Apache::lonnet::decode_symb($res->symb());
     if ($map=~/\.page$/) {      if ($map=~/\.page$/) {
  my $url=&Apache::lonnet::clutter($map);   my $url=&Apache::lonnet::clutter($map);
  $anchor=&escape($src->shown_symb());   $anchor=&escape($res->shown_symb());
  return ($url,$res->shown_symb(),$anchor);   return ($url,$res->shown_symb(),$anchor);
     }      }
         }          }
Line 634  sub getDescription { Line 614  sub getDescription {
     if ($status == $res->OPEN_LATER) {      if ($status == $res->OPEN_LATER) {
         return &mt("Open ") .timeToHumanString($open,'start');          return &mt("Open ") .timeToHumanString($open,'start');
     }      }
       if ($res->simpleStatus($part) == $res->OPEN) {
           unless (&Apache::lonnet::allowed('mgr',$env{'request.course.id'})) {
               my ($slot_status,$slot_time,$slot_name)=$res->check_for_slot($part);
               if ($slot_status == $res->UNKNOWN) {
                   return &mt('Reservation status unknown');
               } elsif ($slot_status == $res->RESERVED) {
                   return &mt('Reserved - ends [_1]',
                              timeToHumanString($slot_time,'end'));
               } elsif ($slot_status == $res->RESERVED_LOCATION) {
                   return &mt('Reserved - specific location(s) - ends [_1]',
                              timeToHumanString($slot_time,'end'));
               } elsif ($slot_status == $res->RESERVED_LATER) {
                   return &mt('Reserved - next open [_1]',
                              timeToHumanString($slot_time,'start'));
               } elsif ($slot_status == $res->RESERVABLE) {
                   return &mt('Reservable ending [_1]',
                              timeToHumanString($slot_time,'end'));
               } elsif ($slot_status == $res->RESERVABLE_LATER) {
                   return &mt('Reservable starting [_1]',
                              timeToHumanString($slot_time,'start'));
               } elsif ($slot_status == $res->NOT_IN_A_SLOT) {
                   return &mt('Reserve a time/place to work');
               } elsif ($slot_status == $res->NOTRESERVABLE) {
                   return &mt('Reservation not available');
               } elsif ($slot_status == $res->WAITING_FOR_GRADE) {
                   return &mt('Submission in grading queue');
               }
           }
       }
     if ($status == $res->OPEN) {      if ($status == $res->OPEN) {
         if ($due) {          if ($due) {
     if ($res->is_practice()) {      if ($res->is_practice()) {
Line 663  sub getDescription { Line 672  sub getDescription {
         return &mt("Excused by instructor");          return &mt("Excused by instructor");
     }      }
     if ($status == $res->ATTEMPTED) {      if ($status == $res->ATTEMPTED) {
         return &mt("Answer submitted, not yet graded");          if ($res->is_anonsurvey($part) || $res->is_survey($part)) {
               return &mt("Survey submission recorded");
           } else {
               return &mt("Answer submitted, not yet graded");
           }
       }
       if ($status == $res->CREDIT_ATTEMPTED) {
           if ($res->is_anonsurvey($part) || $res->is_survey($part)) {
               return &mt("Credit for survey submission");
           }
     }      }
     if ($status == $res->TRIES_LEFT) {      if ($status == $res->TRIES_LEFT) {
         my $tries = $res->tries($part);          my $tries = $res->tries($part);
Line 848  sub render_resource { Line 866  sub render_resource {
     my $link = $params->{"resourceLink"};      my $link = $params->{"resourceLink"};
   
     #  The URL part is not escaped at this point, but the symb is...       #  The URL part is not escaped at this point, but the symb is... 
     #  The stuff to the left of the ? must have ' replaced by \' since  
     #  it will be quoted with ' in the href.  
   
     my ($left,$right) = split(/\?/, $link);  
     $link = $left.'?'.$right;  
   
     my $src = $resource->src();      my $src = $resource->src();
     my $it = $params->{"iterator"};      my $it = $params->{"iterator"};
Line 979  sub render_resource { Line 992  sub render_resource {
         $nonLinkedText .= ' ('.&mt('[_1] parts', $resource->countParts()).')';          $nonLinkedText .= ' ('.&mt('[_1] parts', $resource->countParts()).')';
     }      }
   
     my $target;  
     if ($env{'environment.remotenavmap'} eq 'on') {  
  $target=' target="loncapaclient" ';  
     }  
     if (!$params->{'resource_nolink'} && !$resource->is_sequence() && !$resource->is_empty_sequence) {      if (!$params->{'resource_nolink'} && !$resource->is_sequence() && !$resource->is_empty_sequence) {
         $result .= "$curMarkerBegin<a $target href=\"$link\">$title$partLabel</a>$curMarkerEnd$nonLinkedText</td>";          $result .= "$curMarkerBegin<a href=\"$link\">$title$partLabel</a>$curMarkerEnd$nonLinkedText</td>";
     } else {      } else {
         $result .= "$curMarkerBegin$linkopen$title$partLabel</a>$curMarkerEnd$nonLinkedText</td>";          $result .= "$curMarkerBegin$linkopen$title$partLabel</a>$curMarkerEnd$nonLinkedText</td>";
     }      }
Line 997  sub render_communication_status { Line 1006  sub render_communication_status {
     my $discussionHTML = ""; my $feedbackHTML = ""; my $errorHTML = "";      my $discussionHTML = ""; my $feedbackHTML = ""; my $errorHTML = "";
   
     my $link = $params->{"resourceLink"};      my $link = $params->{"resourceLink"};
     my $target;      my $linkopen = "<a href=\"$link\">";
     if ($env{'environment.remotenavmap'} eq 'on') {  
  $target=' target="loncapaclient" ';  
     }  
     my $linkopen = "<a $target href=\"$link\">";  
     my $linkclose = "</a>";      my $linkclose = "</a>";
     my $location=&Apache::loncommon::lonhttpdurl("/adm/lonMisc");      my $location=&Apache::loncommon::lonhttpdurl("/adm/lonMisc");
     if ($resource->hasDiscussion()) {      if ($resource->hasDiscussion()) {
         $discussionHTML = $linkopen .          $discussionHTML = $linkopen .
             '<img alt="'.&mt('New Discussion').'" src="'.$location.'/chat.gif" />' .              '<img alt="'.&mt('New Discussion').'" src="'.$location.'/chat.gif" title="'.&mt('New Discussion').'"/>' .
             $linkclose;              $linkclose;
     }      }
           
Line 1014  sub render_communication_status { Line 1019  sub render_communication_status {
         my $feedback = $resource->getFeedback();          my $feedback = $resource->getFeedback();
         foreach my $msgid (split(/\,/, $feedback)) {          foreach my $msgid (split(/\,/, $feedback)) {
             if ($msgid) {              if ($msgid) {
                 $feedbackHTML .= '&nbsp;<a '.$target.' href="/adm/email?display='                  $feedbackHTML .= '&nbsp;<a href="/adm/email?display='
                     . &escape($msgid) . '">'                      . &escape($msgid) . '">'
                     . '<img alt="'.&mt('New E-mail').'" src="'.$location.'/feedback.gif" /></a>';                      . '<img alt="'.&mt('New E-mail').'" src="'.$location.'/feedback.gif" title="'.&mt('New E-mail').'"/></a>';
             }              }
         }          }
     }      }
Line 1028  sub render_communication_status { Line 1033  sub render_communication_status {
             last if ($errorcount>=10); # Only output 10 bombs maximum              last if ($errorcount>=10); # Only output 10 bombs maximum
             if ($msgid) {              if ($msgid) {
                 $errorcount++;                  $errorcount++;
                 $errorHTML .= '&nbsp;<a '.$target.' href="/adm/email?display='                  $errorHTML .= '&nbsp;<a href="/adm/email?display='
                     . &escape($msgid) . '">'                      . &escape($msgid) . '">'
                     . '<img alt="'.&mt('New Error').'" src="'.$location.'/bomb.gif" /></a>';                      . '<img alt="'.&mt('New Error').'" src="'.$location.'/bomb.gif" title="'.&mt('New Error').'"/></a>';
             }              }
         }          }
     }      }
Line 1048  sub render_quick_status { Line 1053  sub render_quick_status {
         $params->{'multipart'} && $part eq "0";          $params->{'multipart'} && $part eq "0";
   
     my $link = $params->{"resourceLink"};      my $link = $params->{"resourceLink"};
     my $target;      my $linkopen = "<a href=\"$link\">";
     if ($env{'environment.remotenavmap'} eq 'on') {  
  $target=' target="loncapaclient" ';  
     }  
     my $linkopen = "<a $target href=\"$link\">";  
     my $linkclose = "</a>";      my $linkclose = "</a>";
   
  $result .= '<td class="LC_middle">';   $result .= '<td class="LC_middle">';
Line 1063  sub render_quick_status { Line 1064  sub render_quick_status {
         if ($icon) {          if ($icon) {
     my $location=      my $location=
  &Apache::loncommon::lonhttpdurl("/adm/lonIcons/$icon");   &Apache::loncommon::lonhttpdurl("/adm/lonIcons/$icon");
             $result .= "$linkopen<img src='$location' alt='$alt' />$linkclose";   $result .= $linkopen.'<img src="'.$location.'" alt="'.&mt($alt).'" title="'.&mt($alt).'" />'.$linkclose;            
         } else {          } else {
             $result .= "&nbsp;";              $result .= "&nbsp;";
         }          }
Line 1387  sub render { Line 1388  sub render {
  my $location=&Apache::loncommon::lonhttpdurl("/adm/lonMisc");   my $location=&Apache::loncommon::lonhttpdurl("/adm/lonMisc");
         if ($navmap->{LAST_CHECK}) {          if ($navmap->{LAST_CHECK}) {
             $result .=               $result .= 
                 '<img src="'.$location.'/chat.gif"> '.&mt('New discussion since').' '.                  '<img src="'.$location.'/chat.gif" alt="" /> '.&mt('New discussion since').' '.
                 strftime("%A, %b %e at %I:%M %P", localtime($navmap->{LAST_CHECK})).                  strftime("%A, %b %e at %I:%M %P", localtime($navmap->{LAST_CHECK})).
                 '</td><td align="center" valign="bottom">&nbsp;&nbsp;'.                  '</td><td align="center" valign="bottom">&nbsp;&nbsp;'.
                 '<img src="'.$location.'/feedback.gif"> '.&mt('New message (click to open)').'<p>'.                  '<img src="'.$location.'/feedback.gif" alt="" /> '.&mt('New message (click to open)').'<p>'.
                 '</td>';                   '</td>'; 
         } else {          } else {
             $result .= '<td align="center" valign="bottom">&nbsp;&nbsp;'.              $result .= '<td align="center" valign="bottom">&nbsp;&nbsp;'.
                 '<img src="'.$location.'/chat.gif"> '.&mt('Discussions').'</td><td align="center" valign="bottom">'.                  '<img src="'.$location.'/chat.gif" alt="" /> '.&mt('Discussions').'</td><td align="center" valign="bottom">'.
                 '&nbsp;&nbsp;<img src="'.$location.'/feedback.gif"> '.&mt('New message (click to open)').                  '&nbsp;&nbsp;<img src="'.$location.'/feedback.gif" alt="" /> '.&mt('New message (click to open)').
                 '</td>';                   '</td>'; 
         }          }
   
Line 1405  sub render { Line 1406  sub render {
     if ($printCloseAll && !$args->{'resource_no_folder_link'}) {      if ($printCloseAll && !$args->{'resource_no_folder_link'}) {
  my ($link,$text);   my ($link,$text);
         if ($condition) {          if ($condition) {
     $link='"navmaps?condition=0&amp;filter=&amp;'.$queryString.      $link='navmaps?condition=0&amp;filter=&amp;'.$queryString.
  '&here='.&escape($here).'"';   '&amp;here='.&escape($here);
     $text='Close all folders';      $text='Close all folders';
         } else {          } else {
     $link='"navmaps?condition=1&amp;filter=&amp;'.$queryString.      $link='navmaps?condition=1&amp;filter=&amp;'.$queryString.
  '&here='.&escape($here).'"';   '&amp;here='.&escape($here);
     $text='Open all folders';      $text='Open all folders';
         }          }
           if ($env{'form.register'}) {
               $link .= '&amp;register='.$env{'form.register'};
           }
  if ($args->{'caller'} eq 'navmapsdisplay') {   if ($args->{'caller'} eq 'navmapsdisplay') {
     &add_linkitem($args->{'linkitems'},'changefolder',      &add_linkitem($args->{'linkitems'},'changefolder',
   'location.href='.$link,$text);    "location.href='$link'",$text);
  } else {   } else {
     $result.='<a href='.$link.'>'.&mt($text).'</a>';      $result.= '<a href="'.$link.'">'.&mt($text).'</a>';
  }   }
         $result .= "\n";          $result .= "\n";
     }      }
Line 1433  sub render { Line 1437  sub render {
  <input type="hidden" name="navurl" value="$ENV{'QUERY_STRING'}" />   <input type="hidden" name="navurl" value="$ENV{'QUERY_STRING'}" />
  <input type="hidden" name="navtime" value="$time" />   <input type="hidden" name="navtime" value="$time" />
 END  END
           if ($env{'form.register'}) {
               $result .= '<input type="hidden" name="register" value="'.$env{'form.register'}.'" />';
           }
         if ($args->{'sort'} eq 'discussion') {           if ($args->{'sort'} eq 'discussion') { 
     my $totdisc = 0;      my $totdisc = 0;
     my $haveDisc = '';      my $haveDisc = '';
Line 1454  END Line 1461  END
  $result.='</form>';   $result.='</form>';
     }      }
   
      
     if ($args->{'caller'} eq 'navmapsdisplay') {      if ($args->{'caller'} eq 'navmapsdisplay') {
         $result .= '<table><tr><td>'.          $result .= '<table><tr><td>'.
                    &Apache::loncommon::help_open_menu('Navigation Screen','Navigation_Screen',undef,'RAT').'</td>';                     &Apache::loncommon::help_open_menu('Navigation Screen','Navigation_Screen',undef,'RAT').'</td>';
  if ($env{'environment.remotenavmap'} ne 'on') {  
     $result .= '<td>&nbsp;</td>';       $result .= '<td>&nbsp;</td>'; 
         } else {   $result.='<td class="LC_middle">'.&mt('Tools:').'</td>';
     $result .= '</tr><tr>';   
         }  
  $result.=&show_linkitems_toolbar($args->{'linkitems'});   $result.=&show_linkitems_toolbar($args->{'linkitems'});
         if ($args->{'sort_html'}) {          if ($args->{'sort_html'}) {
     if ($env{'environment.remotenavmap'} ne 'on') {              $result.='<td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>'.
  $result.='<td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>'.                  '<td align="right">'.$args->{'sort_html'}.'</td></tr>';
     '<td align="right">'.$args->{'sort_html'}.'</td></tr>';          }
     } else {  
  $result.='</tr><tr><td align="left"><br />'.  
     $args->{'sort_html'}.'</td></tr>';  
     }  
  }  
         $result .= '</table>';          $result .= '</table>';
     } elsif ($args->{'sort_html'}) {       } elsif ($args->{'sort_html'}) { 
         $result.=$args->{'sort_html'};           $result.=$args->{'sort_html'}; 
Line 1489  END Line 1487  END
     $result .= "<br />\n";      $result .= "<br />\n";
   
     # Data      # Data
     $result .= '<table id="LC_tableOfContent">' ."\n";      $result.=&Apache::loncommon::start_data_table("LC_tableOfContent");    
   
     my $res = "Apache::lonnavmaps::resource";      my $res = "Apache::lonnavmaps::resource";
     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 );
     my @backgroundColors = ("LC_trEven", "LC_trOdd");  
   
     # Shared variables      # Shared variables
     $args->{'counter'} = 0; # counts the rows      $args->{'counter'} = 0; # counts the rows
Line 1724  END Line 1721  END
     if (defined($anchor)) { $anchor='#'.$anchor; }      if (defined($anchor)) { $anchor='#'.$anchor; }
     my $srcHasQuestion = $src =~ /\?/;      my $srcHasQuestion = $src =~ /\?/;
     $args->{"resourceLink"} = $src.      $args->{"resourceLink"} = $src.
  ($srcHasQuestion?'&':'?') .   ($srcHasQuestion?'&amp;':'?') .
  'symb=' . &escape($symb).$anchor;   'symb=' . &escape($symb).$anchor;
  }   }
         # Now, we've decided what parts to show. Loop through them and          # Now, we've decided what parts to show. Loop through them and
         # show them.          # show them.
         foreach my $part (@parts) {          foreach my $part (@parts) {
             $rownum ++;              $rownum ++;
             my $backgroundColor = $backgroundColors[$rownum % scalar(@backgroundColors)];  
                           
             $result .= "  <tr class='$backgroundColor'>\n";              $result .= &Apache::loncommon::start_data_table_row();
   
             # Set up some data about the parts that the cols might want              # Set up some data about the parts that the cols might want
             my $filter = $it->{FILTER};              my $filter = $it->{FILTER};
Line 1759  END Line 1755  END
                 }                  }
                 $result .= $colHTML . "\n";                  $result .= $colHTML . "\n";
             }              }
             $result .= "    </tr>\n";              $result .= &Apache::loncommon::end_data_table_row();
             $args->{'isNewBranch'} = 0;              $args->{'isNewBranch'} = 0;
         }          }
   
Line 1787  END Line 1783  END
     # it's quite likely this might fix other browsers, too, and       # it's quite likely this might fix other browsers, too, and 
     # certainly won't hurt anything.      # certainly won't hurt anything.
     if ($displayedJumpMarker) {      if ($displayedJumpMarker) {
         $result .= "          $result .= &Apache::lonhtmlcommon::scripttag("
 <script>  
 if (location.href.indexOf('#curloc')==-1) {  if (location.href.indexOf('#curloc')==-1) {
     setTimeout(\"location += '#curloc';\", 0)      setTimeout(\"location += '#curloc';\", 0)
 }  }
 </script>";  ");
     }      }
   
     $result .= "</table>";      $result.=&Apache::loncommon::end_data_table();
       
     if ($r) {      if ($r) {
         $r->print($result);          $r->print($result);
         $result = "";          $result = "";
Line 1812  sub add_linkitem { Line 1807  sub add_linkitem {
     $$linkitems{$name}{'text'}=&mt($text);      $$linkitems{$name}{'text'}=&mt($text);
 }  }
   
 sub show_linkitems {  
     my ($linkitems)=@_;  
     my @linkorder = ("blank","launchnav","closenav","firsthomework",  
      "everything","uncompleted","changefolder","clearbubbles");  
       
     my $result .= (<<ENDBLOCK);  
               <td align="left">  
 <script type="text/javascript">  
     function changeNavDisplay () {  
  var navchoice = document.linkitems.toplink[document.linkitems.toplink.selectedIndex].value;  
 ENDBLOCK  
     foreach my $link (@linkorder) {  
  $result.= "if (navchoice == '$link') {".  
     $linkitems->{$link}{'cmd'}."}\n";  
     }  
     $result.='}  
               </script>  
                    <form name="linkitems" method="post">  
                        <span class="LC_nobreak"><select name="toplink">'."\n";  
     foreach my $link (@linkorder) {  
  if (defined($linkitems->{$link})) {  
     if ($linkitems->{$link}{'text'} ne '') {  
  $result .= ' <option value="'.$link.'">'.  
     $linkitems->{$link}{'text'}."</option>\n";  
     }  
  }  
     }  
     $result .= '</select>&nbsp;<input type="button" name="chgnav"  
                    value="Go" onClick="javascript:changeNavDisplay()" />  
                 </span></form></td>'."\n";  
   
     return $result;  
 }  
   
 sub show_linkitems_toolbar {  sub show_linkitems_toolbar {
     my ($linkitems,$condition)=@_;      my ($linkitems,$condition)=@_;
     my @linkorder = ("blank","launchnav","closenav","firsthomework",      my @linkorder = ('firsthomework','everything','uncompleted',
      "everything","uncompleted","changefolder","clearbubbles");                       'changefolder','clearbubbles');
           my $result .='<td align="left">'."\n". 
     my $result .='                    '<span class="LC_nobreak">'."\n".
               <td align="left">                   '<ul id="LC_toolbar">';
                        <span class="LC_nobreak">'."\n<ul id=\"LC_toolbar\">";      foreach my $link (@linkorder) {
  foreach my $link (@linkorder) {          my $link_id = 'LC_content_toolbar_'.$link;
         my $link_id = "LC_content_toolbar_".$link;          if (defined($linkitems->{$link})) {
  if (defined($linkitems->{$link})) {              if ($linkitems->{$link}{'text'} ne '') {
     if ($linkitems->{$link}{'text'} ne '') {                  $linkitems->{$link}{'cmd'}=~s/"/'/g;
  $linkitems->{$link}{'cmd'}=~s/"/'/g;                  if ($linkitems->{$link}{'cmd'}) {
  if($linkitems->{$link}{'cmd'}){                      if ($link eq 'changefolder') {
                    if($link eq 'changefolder'){                          if ($condition) {
                       if($condition){$link_id='LC_content_toolbar_changefolder_toggled'}                              $link_id='LC_content_toolbar_changefolder_toggled';
                       else{$link_id='LC_content_toolbar_changefolder'}                          } else {
                    }                              $link_id='LC_content_toolbar_changefolder';
                           $result .=  ' <li><a href="#"'.                          }
      ' onClick="'.$linkitems->{$link}{'cmd'}.'"'.                      }
                                 ' id="'.$link_id.'"'.                      $result .= '<li><a href="#" '.
                                 ' class="LC_toolbarItem"'.                                 'onclick="'.$linkitems->{$link}{'cmd'}.'" '.
    ' title="'.$linkitems->{$link}{'text'}.'"></a></li>'."\n";                                 'id="'.$link_id.'" '.
  }                                 'class="LC_toolbarItem" '.
                                  'title="'.$linkitems->{$link}{'text'}.'">'.
     }                                 '</a></li>'."\n";
  }                  }
               }
           }
     }      }
     $result .= '</ul>';      $result .= '</ul>'.
     $result .= ' </span></td>'."\n";                 '</span></td>'."\n";
   
     return $result;      return $result;
 }  }
   
Line 2347  resource object. Line 2309  resource object.
 Based on the symb of the resource, get a resource object for that  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.  resource. This is one of the proper ways to get a resource object.
   
 =item * B<getMapByMapPc>(map_pc):  =item * B<getByMapPc>(map_pc):
   
 Based on the map_pc of the resource, get a resource object for  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.  the given map. This is one of the proper ways to get a resource object.
Line 2617  in the filter function. Line 2579  in the filter function.
 Retrieves version infomation for a url. Returns the version (a number, or   Retrieves version infomation for a url. Returns the version (a number, or 
 the string "mostrecent") for resources which have version information in    the string "mostrecent") for resources which have version information in  
 the big hash.  the big hash.
       
 =cut  =cut
   
   
Line 3502  sub navHash { Line 3464  sub navHash {
     my $self = shift;      my $self = shift;
     my $param = shift;      my $param = shift;
     my $id = shift;      my $id = shift;
     return $self->{NAV_MAP}->navhash($param . ($id?$self->{ID}:""));      my $arg = $param . ($id?$self->{ID}:"");
       if (defined($arg)) {
           return $self->{NAV_MAP}->navhash($arg);
       }
       return;
 }  }
   
 =pod  =pod
Line 3745  sub is_problem { Line 3711  sub is_problem {
     }      }
     return 0;      return 0;
 }  }
   #
   #  The has below is the set of status that are considered 'incomplete'
   #
   my %incomplete_hash = 
   (
    TRIES_LEFT()     => 1,
    OPEN()           => 1,
    ATTEMPTED()      => 1
   
    );
   #
   #  Return tru if a problem is incomplete... for now incomplete means that
   #  any part of the problem is incomplete. 
   #  Note that if the resources is not a problem, 0 is returned.
   #
   sub is_incomplete {
       my $self = shift;
       if ($self->is_problem()) {
    &Apache::lonnet::logthis('is problem');
    foreach my $part (@{$self->parts()}) {
       &Apache::lonnet::logthis("$part status ".$self->status($part));
       if (exists($incomplete_hash{$self->status($part)})) {
    return 1;
       }
    }
       }
       return 0;
          
   }
 sub is_raw_problem {  sub is_raw_problem {
     my $self=shift;      my $self=shift;
     my $src = $self->src();      my $src = $self->src();
Line 3780  sub is_survey { Line 3775  sub is_survey {
     my $self = shift();      my $self = shift();
     my $part = shift();      my $part = shift();
     my $type = $self->parmval('type',$part);      my $type = $self->parmval('type',$part);
     if ($type eq 'survey') {      if (($type eq 'survey') || ($type eq 'surveycred')) {
         return 1;          return 1;
     }      }
     if ($self->src() =~ /\.(survey)$/) {      if ($self->src() =~ /\.(survey)$/) {
Line 3788  sub is_survey { Line 3783  sub is_survey {
     }      }
     return 0;      return 0;
 }  }
   sub is_anonsurvey {
       my $self = shift();
       my $part = shift();
       my $type = $self->parmval('type',$part);
       if (($type eq 'anonsurvey') || ($type eq 'anonsurveycred')) {
           return 1;
       }
       return 0;
   }
 sub is_task {  sub is_task {
     my $self=shift;      my $self=shift;
     my $src = $self->src();      my $src = $self->src();
Line 3841  resource of the map. Line 3845  resource of the map.
   
 Returns a string with the type of the map in it.  Returns a string with the type of the map in it.
   
   =item *B<map_hierarchy>:
   
   Returns a string with a comma-separated ordered list of map_pc IDs
   for the hierarchy of maps containing a map, with the top level
   map first, then descending to deeper levels, with the enclosing map last.
   
 =back  =back
   
 =cut  =cut
Line 3871  sub map_type { Line 3881  sub map_type {
     my $pc = $self->map_pc();      my $pc = $self->map_pc();
     return $self->navHash("map_type_$pc", 0);      return $self->navHash("map_type_$pc", 0);
 }  }
   sub map_hierarchy {
       my $self = shift;
       my $pc = $self->map_pc();
       return $self->navHash("map_hierarchy_$pc", 0);
   }
   
 #####  #####
 # Property queries  # Property queries
Line 3976  sub awarded { Line 3991  sub awarded {
     if (!defined($part)) { $part = '0'; }      if (!defined($part)) { $part = '0'; }
     return $self->{NAV_MAP}->{STUDENT_DATA}->{$self->symb()}->{'resource.'.$part.'.awarded'};      return $self->{NAV_MAP}->{STUDENT_DATA}->{$self->symb()}->{'resource.'.$part.'.awarded'};
 }  }
   sub taskversion {
       my $self = shift; my $part = shift;
       $self->{NAV_MAP}->get_user_data();
       if (!defined($part)) { $part = '0'; }
       return $self->{NAV_MAP}->{STUDENT_DATA}->{$self->symb()}->{'resource.'.$part.'.version'};
   }
   sub taskstatus {
       my $self = shift; my $part = shift;
       $self->{NAV_MAP}->get_user_data();
       if (!defined($part)) { $part = '0'; }
       return $self->{NAV_MAP}->{STUDENT_DATA}->{$self->symb()}->{'resource.'.$self->taskversion($part).'.'.$part.'.status'};
   }
   sub solved {
       my $self = shift; my $part = shift;
       $self->{NAV_MAP}->get_user_data();
       if (!defined($part)) { $part = '0'; }
       return $self->{NAV_MAP}->{STUDENT_DATA}->{$self->symb()}->{'resource.'.$part.'.solved'};
   }
   sub checkedin {
       my $self = shift; my $part = shift;
       $self->{NAV_MAP}->get_user_data();
       if (!defined($part)) { $part = '0'; }
       if ($self->is_task()) {
           my $version = $self->taskversion($part);
           return ($self->{NAV_MAP}->{STUDENT_DATA}->{$self->symb()}->{'resource.'.$version .'.'.$part.'.checkedin'},$self->{NAV_MAP}->{STUDENT_DATA}->{$self->symb()}->{'resource.'.$version .'.'.$part.'.checkedin.slot'});
       } else {
           return ($self->{NAV_MAP}->{STUDENT_DATA}->{$self->symb()}->{'resource.'.$part.'.checkedin'},$self->{NAV_MAP}->{STUDENT_DATA}->{$self->symb()}->{'resource.'.$part.'.checkedin.slot'});
       }
   }
 # this should work exactly like the copy in lonhomework.pm  # this should work exactly like the copy in lonhomework.pm
 sub duedate {  sub duedate {
     (my $self, my $part) = @_;      (my $self, my $part) = @_;
Line 4071  sub part_display { Line 4115  sub part_display {
     }      }
     return $display;      return $display;
 }  }
   sub slot_control {
       my $self=shift(); my $part = shift();
       if (!defined($part)) { $part = '0'; }
       my $useslots = $self->parmval("useslots", $part);
       my $availablestudent = $self->parmval("availablestudent", $part);
       my $available = $self->parmval("available", $part); 
       return ($useslots,$availablestudent,$available);
   }
   
 # Multiple things need this  # Multiple things need this
 sub getReturnHash {  sub getReturnHash {
Line 4503  sub OPEN                   { return 1; } Line 4555  sub OPEN                   { return 1; }
 sub PAST_DUE_NO_ANSWER     { return 2; }  sub PAST_DUE_NO_ANSWER     { return 2; }
 sub PAST_DUE_ANSWER_LATER  { return 3; }  sub PAST_DUE_ANSWER_LATER  { return 3; }
 sub ANSWER_OPEN            { return 4; }  sub ANSWER_OPEN            { return 4; }
 sub NOTHING_SET            { return 5; }   sub NOTHING_SET            { return 5; }
 sub NETWORK_FAILURE        { return 100; }  sub NETWORK_FAILURE        { return 100; }
   
 # getDateStatus gets the date status for a given problem part.   # getDateStatus gets the date status for a given problem part. 
Line 4589  Information not available due to network Line 4641  Information not available due to network
   
 Attempted, and not yet graded.  Attempted, and not yet graded.
   
   =item * B<CREDIT_ATTEMPTED>:
   
   Attempted, and credit received for attempt (survey and anonymous survey only).
   
 =back  =back
   
 =cut  =cut
Line 4600  sub CORRECT               { return 13; } Line 4656  sub CORRECT               { return 13; }
 sub CORRECT_BY_OVERRIDE   { return 14; }  sub CORRECT_BY_OVERRIDE   { return 14; }
 sub EXCUSED               { return 15; }  sub EXCUSED               { return 15; }
 sub ATTEMPTED             { return 16; }  sub ATTEMPTED             { return 16; }
   sub CREDIT_ATTEMPTED      { return 17; }
   
 sub getCompletionStatus {  sub getCompletionStatus {
     my $self = shift;      my $self = shift;
Line 4618  sub getCompletionStatus { Line 4675  sub getCompletionStatus {
     if ($status eq 'incorrect_by_override') {return $self->INCORRECT_BY_OVERRIDE; }      if ($status eq 'incorrect_by_override') {return $self->INCORRECT_BY_OVERRIDE; }
     if ($status eq 'excused') {return $self->EXCUSED; }      if ($status eq 'excused') {return $self->EXCUSED; }
     if ($status eq 'ungraded_attempted') {return $self->ATTEMPTED; }      if ($status eq 'ungraded_attempted') {return $self->ATTEMPTED; }
       if ($status eq 'credit_attempted') {
           if ($self->is_anonsurvey($part) || $self->is_survey($part)) {
               return $self->CREDIT_ATTEMPTED;
           } else {
               return $self->ATTEMPTED;
           }
       }
     return $self->NOT_ATTEMPTED;      return $self->NOT_ATTEMPTED;
 }  }
   
Line 4707  The item is open and not yet tried. Line 4771  The item is open and not yet tried.
   
 The problem has been attempted.  The problem has been attempted.
   
   =item * B<CREDIT_ATTEMPTED>:
   
   The problem has been attempted, and credit given for the attempt (survey and anonymous survey only).
   
 =item * B<ANSWER_SUBMITTED>:  =item * B<ANSWER_SUBMITTED>:
   
 An answer has been submitted, but the student should not see it.  An answer has been submitted, but the student should not see it.
Line 4715  An answer has been submitted, but the st Line 4783  An answer has been submitted, but the st
   
 =cut  =cut
   
 sub TRIES_LEFT       { return 20; }  sub TRIES_LEFT        { return 20; }
 sub ANSWER_SUBMITTED { return 21; }  sub ANSWER_SUBMITTED  { return 21; }
 sub PARTIALLY_CORRECT{ return 22; }  sub PARTIALLY_CORRECT { return 22; }
   
   sub RESERVED_LATER    { return 30; }
   sub RESERVED          { return 31; }
   sub RESERVED_LOCATION { return 32; }
   sub RESERVABLE        { return 33; }
   sub RESERVABLE_LATER  { return 34; }
   sub NOTRESERVABLE     { return 35; }
   sub NOT_IN_A_SLOT     { return 36; }
   sub NEEDS_CHECKIN     { return 37; }
   sub WAITING_FOR_GRADE { return 38; }
   sub UNKNOWN           { return 39; }
   
 sub status {  sub status {
     my $self = shift;      my $self = shift;
Line 4769  sub status { Line 4848  sub status {
         return ATTEMPTED;          return ATTEMPTED;
     }      }
   
       if ($completionStatus == CREDIT_ATTEMPTED) {
           return CREDIT_ATTEMPTED;
       }
   
     # If it's EXCUSED, then return that no matter what      # If it's EXCUSED, then return that no matter what
     if ($completionStatus == EXCUSED) {      if ($completionStatus == EXCUSED) {
         return EXCUSED;           return EXCUSED; 
Line 4810  sub status { Line 4893  sub status {
     return OPEN;       return OPEN; 
 }  }
   
   sub check_for_slot {
       my $self = shift;
       my $part = shift;
       my ($use_slots,$available,$availablestudent) = $self->slot_control($part);
       if (($use_slots ne '') && ($use_slots !~ /^\s*no\s*$/i)) {
           my @slots = (split(/:/,$availablestudent),split(/:/,$available));
           my $cid=$env{'request.course.id'};
           my $cdom=$env{'course.'.$cid.'.domain'};
           my $cnum=$env{'course.'.$cid.'.num'};
           my $now = time;
           if (@slots > 0) {
               my %slots=&Apache::lonnet::get('slots',[@slots],$cdom,$cnum);
               if (&Apache::lonnet::error(%slots)) {
                   return (UNKNOWN);
               }
               my @sorted_slots = &Apache::loncommon::sorted_slots(\@slots,\%slots);
               my ($checkedin,$checkedinslot);
               foreach my $slot_name (@sorted_slots) {
                   next if (!defined($slots{$slot_name}) ||
                            !ref($slots{$slot_name}));
                   my $end = $slots{$slot_name}->{'endtime'};
                   my $start = $slots{$slot_name}->{'starttime'};
                   my $ip = $slots{$slot_name}->{'ip'};
                   if ($self->simpleStatus() == OPEN) {
                       my $startreserve = $slots{$slot_name}->{'startreserve'};
                       my @proctors;
                       if ($slots{$slot_name}->{'proctor'} ne '') {
                           @proctors = split(',',$slots{$slot_name}->{'proctor'});
                       }
                       if ($end > $now) {
                           ($checkedin,$checkedinslot) = $self->checkedin();
                           if ($startreserve < $now) {
                               if ($start > $now) {
                                   return (RESERVED_LATER,$start,$slot_name);
                               } else {
                                   if ($ip ne '') {
                                       if (!&Apache::loncommon::check_ip_acc($ip)) {
                                           return (RESERVED_LOCATION,$ip,$slot_name);
                                       }
                                   } 
                                   if (@proctors > 0) {
                                       unless ((grep(/^\Q$checkedin\E/,@proctors)) &&
                                           ($checkedinslot eq $slot_name)) {
                                           return (NEEDS_CHECKIN,undef,$slot_name); 
                                       }
                                   }
                                   return (RESERVED,$end,$slot_name);
                               }
                           } else {
                               if ($start > $now) {
                                   return (RESERVABLE,$startreserve,$slot_name);
                               }
                           }
                       }
                   }
               }
               my ($is_correct,$got_grade);
               if ($self->is_task()) {
                   my $taskstatus = $self->taskstatus();
                   $is_correct = (($taskstatus eq 'pass') || 
                                  ($self->solved() =~ /^correct_/));
                   $got_grade = ($self->solved() =~ /^(?:pass|fail)$/);
               } else {
                   $got_grade = 1;
                   $is_correct = ($self->solved() =~ /^correct_/);   
               }
               ($checkedin,$checkedinslot) = $self->checkedin();
               if ($checkedin) {
                   if (!$got_grade) {
                       return (WAITING_FOR_GRADE);
                   } elsif ($is_correct) {
                       return (CORRECT); 
                   }
               }
               return(NOT_IN_A_SLOT);
           } else {
               if (!$future_slots_checked) {
                   $future_slots = &get_future_slots($cdom,$cnum,$now);
                   $future_slots_checked = 1;
               }
               if ($future_slots) {
                   return(NOT_IN_A_SLOT);
               }
               return(NOTRESERVABLE);
           }
       }
       return;
   }
   
   sub get_future_slots {
       my ($cdom,$cnum,$now) = @_;
       my %slots=&Apache::lonnet::dump('slots',$cdom,$cnum);
       my $future_slots = 0;
       foreach my $slot (keys(%slots)) {
           if (($slots{$slot}->{'starttime'} > $now) &&
               ($slots{$slot}->{'endtime'} > $now)) {
               $future_slots ++;
           }
       }
       return $future_slots;
   }
   
 sub CLOSED { return 23; }  sub CLOSED { return 23; }
 sub ERROR { return 24; }  sub ERROR { return 24; }
   
Line 4859  my %compositeToSimple = Line 5044  my %compositeToSimple =
       INCORRECT()             => INCORRECT,        INCORRECT()             => INCORRECT,
       OPEN()                  => OPEN,        OPEN()                  => OPEN,
       ATTEMPTED()             => ATTEMPTED,        ATTEMPTED()             => ATTEMPTED,
         CREDIT_ATTEMPTED()      => CORRECT,
       ANSWER_SUBMITTED()      => ATTEMPTED        ANSWER_SUBMITTED()      => ATTEMPTED
      );       );
   
Line 4933  sub completable { Line 5119  sub completable {
         # and it is not "attempted" (manually graded problem), it is          # and it is not "attempted" (manually graded problem), it is
         # not "complete"          # not "complete"
  if ($self->getCompletionStatus($part) == ATTEMPTED() ||   if ($self->getCompletionStatus($part) == ATTEMPTED() ||
               $self->getCompletionStatus($part) == CREDIT_ATTEMPTED() ||
     $status == ANSWER_SUBMITTED() ) {      $status == ANSWER_SUBMITTED() ) {
     # did this part already, as well as we can      # did this part already, as well as we can
     next;      next;

Removed from v.1.430  
changed lines
  Added in v.1.450


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