Diff for /loncom/interface/lonnavmaps.pm between versions 1.443 and 1.468

version 1.443, 2010/01/26 11:33:48 version 1.468, 2011/11/27 22:51:28
Line 478  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 Apache::lonmap;
   
 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;
 use DateTime();  use DateTime();
   
   # For debugging
   
   use Data::Dumper;
   
   
 # symbolic constants  # symbolic constants
 sub SYMB { return 1; }  sub SYMB { return 1; }
 sub URL { return 2; }  sub URL { return 2; }
Line 509  my %statusIconMap = Line 515  my %statusIconMap =
 my %iconAltTags =   #texthash does not work here  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'     => 'Is Open',
       'navmap.partial.gif'  => 'Partially Correct',        'navmap.partial.gif'  => 'Partially Correct',
       'navmap.ellipsis.gif' => 'Attempted',        'navmap.ellipsis.gif' => 'Attempted',
      );       );
Line 528  my %colormap = Line 534  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 538  my $hurryUpColor = "#FF0000"; Line 545  my $hurryUpColor = "#FF0000";
 my $future_slots_checked = 0;  my $future_slots_checked = 0;
 my $future_slots = 0;  my $future_slots = 0;
   
 sub close {  
     if ($env{'environment.remotenavmap'} ne 'on') { return ''; }  
     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;
     my $addition = shift;      my $addition = shift;
Line 637  sub getDescription { Line 615  sub getDescription {
         return &mt("Having technical difficulties; please check status later");           return &mt("Having technical difficulties; please check status later"); 
     }      }
     if ($status == $res->NOTHING_SET) {      if ($status == $res->NOTHING_SET) {
         return &mt("Not currently assigned.");          return &Apache::lonhtmlcommon::direct_parm_link(&mt("Not currently assigned.",$res->symb(),'opendate'),$part);
     }      }
     if ($status == $res->OPEN_LATER) {      if ($status == $res->OPEN_LATER) {
         return &mt("Open ") .timeToHumanString($open,'start');          return &mt("Open [_1]",&Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($open,'start'),$res->symb(),'opendate',$part));
     }      }
     if ($res->simpleStatus($part) == $res->OPEN) {      if ($res->simpleStatus($part) == $res->OPEN) {
         unless (&Apache::lonnet::allowed('mgr',$env{'request.course.id'})) {          unless (&Apache::lonnet::allowed('mgr',$env{'request.course.id'})) {
Line 674  sub getDescription { Line 652  sub getDescription {
     if ($status == $res->OPEN) {      if ($status == $res->OPEN) {
         if ($due) {          if ($due) {
     if ($res->is_practice()) {      if ($res->is_practice()) {
  return &mt("Closes ")."  " .timeToHumanString($due,'start');   return &mt("Closes [_1]",&Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($due,'start'),$res->symb(),'duedate',$part));
     } else {      } else {
  return &mt("Due")."  " .timeToHumanString($due,'end');   return &mt("Due [_1]",&Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($due,'end'),$res->symb(),'duedate',$part));
     }      }
         } else {          } else {
             return &mt("Open, no due date");              return &Apache::lonhtmlcommon::direct_parm_link(&mt("Open, no due date"),$res->symb(),'duedate',$part);
         }          }
     }      }
     if ($status == $res->PAST_DUE_ANSWER_LATER) {      if ($status == $res->PAST_DUE_ANSWER_LATER) {
         return &mt("Answer open")." " .timeToHumanString($answer,'start');          return &mt("Answer open [_1]",&Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($answer,'start'),$res->symb(),'answerdate',$part));
     }      }
     if ($status == $res->PAST_DUE_NO_ANSWER) {      if ($status == $res->PAST_DUE_NO_ANSWER) {
  if ($res->is_practice()) {   if ($res->is_practice()) {
     return &mt("Closed")." " . timeToHumanString($due,'start');      return &mt("Closed [_1]",&Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($due,'start'),$res->symb(),'answerdate,duedate',$part));
  } else {   } else {
     return &mt("Was due")." " . timeToHumanString($due,'end');      return &mt("Was due [_1]",&Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($due,'end'),$res->symb(),'answerdate,duedate',$part));
  }   }
     }      }
     if (($status == $res->ANSWER_OPEN || $status == $res->PARTIALLY_CORRECT)      if (($status == $res->ANSWER_OPEN || $status == $res->PARTIALLY_CORRECT)
  && $res->handgrade($part) ne 'yes') {   && $res->handgrade($part) ne 'yes') {
         return &mt("Answer available");          return &Apache::lonhtmlcommon::direct_parm_link(&mt("Answer available"),$res->symb(),'answerdate,duedate',$part);
     }      }
     if ($status == $res->EXCUSED) {      if ($status == $res->EXCUSED) {
         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 713  sub getDescription { Line 700  sub getDescription {
             }              }
         }          }
         if ($due) {          if ($due) {
             return &mt("Due")." " . timeToHumanString($due,'end') .              return &mt("Due [_1]",&Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($due,'end'),$res->symb(),'duedate',$part)) .
                 " $triesString";                  " $triesString";
         } else {          } else {
             return &mt("No due date")." $triesString";              return &Apache::lonhtmlcommon::direct_parm_link(&mt("No due date"),$res->symb(),'duedate',$part)." $triesString";
         }          }
     }      }
     if ($status == $res->ANSWER_SUBMITTED) {      if ($status == $res->ANSWER_SUBMITTED) {
Line 798  sub timeToHumanString { Line 785  sub timeToHumanString {
   
         # Less than an hour          # Less than an hour
         if ( $delta < $hour ) {          if ( $delta < $hour ) {
             # If so, use minutes              # If so, use minutes; or minutes, seconds (if format requires)
             my $minutes = floor($delta / 60);              my $minutes = floor($delta / 60);
               if (($format ne '') && ($format =~ /\%(T|S)/)) {
                   my $display;
                   if ($minutes == 1) {
                       $display = "${prefix}1 minute";
                   } else {
                       $display = "$prefix$minutes minutes";
                   }
                   my $seconds = $delta % $minute;
                   if ($seconds == 0) {
                       $display .= $tense;
                   } elsif ($seconds == 1) {
                       $display .= ", 1 second$tense";
                   } else {
                       $display .= ", $seconds seconds$tense";
                   }
                   return $display;
               }
             if ($minutes == 1) { return "${prefix}1 minute$tense"; }              if ($minutes == 1) { return "${prefix}1 minute$tense"; }
             return "$prefix$minutes minutes$tense";              return "$prefix$minutes minutes$tense";
         }          }
                   
         # Is it less than 24 hours away? If so,          # Is it less than 24 hours away? If so,
         # display hours + minutes          # display hours + minutes, (and + seconds, if format specified it)  
         if ( $delta < $hour * 24) {          if ( $delta < $hour * 24) {
             my $hours = floor($delta / $hour);              my $hours = floor($delta / $hour);
             my $minutes = floor(($delta % $hour) / $minute);              my $minutes = floor(($delta % $hour) / $minute);
Line 820  sub timeToHumanString { Line 824  sub timeToHumanString {
             if ($minutes == 0) {              if ($minutes == 0) {
                 $minuteString = "";                  $minuteString = "";
             }              }
               if (($format ne '') && ($format =~ /\%(T|S)/)) {
                   my $display = "$prefix$hourString$minuteString";
                   my $seconds = $delta-(($hours * $hour)+($minutes * $minute));
                   if ($seconds == 0) {
                       $display .= $tense;
                   } elsif ($seconds == 1) {
                       $display .= ", 1 second$tense";
                   } else {
                       $display .= ", $seconds seconds$tense";
                   }
                   return $display;
               }
             return "$prefix$hourString$minuteString$tense";              return "$prefix$hourString$minuteString$tense";
         }          }
   
           # Date/time is more than 24 hours away
   
  my $dt = DateTime->from_epoch(epoch => $time)   my $dt = DateTime->from_epoch(epoch => $time)
                  ->set_time_zone(&Apache::lonlocal::gettimezone());                   ->set_time_zone(&Apache::lonlocal::gettimezone());
   
  # If there's a caller supplied format, use it.   # If there's a caller supplied format, use it, unless it only displays
           # H:M:S or H:M.
   
  if ($format ne '') {   if (($format ne '') && ($format ne '%T') && ($format ne '%R')) {
     my $timeStr = $dt->strftime($format);      my $timeStr = $dt->strftime($format);
     return $timeStr.' ('.$dt->time_zone_short_name().')';      return $timeStr.' ('.$dt->time_zone_short_name().')';
  }   }
Line 964  sub render_resource { Line 983  sub render_resource {
     }      }
   
     if ($resource->randomout()) {      if ($resource->randomout()) {
         $nonLinkedText .= ' <i>('.&mt('hidden').')</i> ';          $nonLinkedText .= ' <span class="LC_warning">('.&mt('hidden').')</span> ';
     }      }
     if (!$resource->condval()) {      if (!$resource->condval()) {
         $nonLinkedText .= ' <i>('.&mt('conditionally hidden').')</i> ';          $nonLinkedText .= ' <span class="LC_info">('.&mt('conditionally hidden').')</span> ';
     }      }
     if (($resource->is_practice()) && ($resource->is_raw_problem())) {      if (($resource->is_practice()) && ($resource->is_raw_problem())) {
         $nonLinkedText .=' <font color="green"><b>'.&mt('not graded').'</b></font>';          $nonLinkedText .=' <font color="green"><b>'.&mt('not graded').'</b></font>';
Line 1011  sub render_resource { Line 1030  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 1029  sub render_communication_status { Line 1044  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()) {
Line 1046  sub render_communication_status { Line 1057  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" title="'.&mt('New E-mail').'"/></a>';                      . '<img alt="'.&mt('New E-mail').'" src="'.$location.'/feedback.gif" title="'.&mt('New E-mail').'"/></a>';
             }              }
Line 1060  sub render_communication_status { Line 1071  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" title="'.&mt('New Error').'"/></a>';                      . '<img alt="'.&mt('New Error').'" src="'.$location.'/bomb.gif" title="'.&mt('New Error').'"/></a>';
             }              }
Line 1080  sub render_quick_status { Line 1091  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 1122  sub render_long_status { Line 1129  sub render_long_status {
     }      }
           
     if ($resource->kind() eq "res" &&      if ($resource->kind() eq "res" &&
         ($resource->is_problem() || $resource->is_practice()) &&          $resource->is_raw_problem() &&
         !$firstDisplayed) {          !$firstDisplayed) {
         if ($color) {$result .= "<font color=\"$color\"><b>"; }          if ($color) {$result .= "<font color=\"$color\"><b>"; }
         $result .= getDescription($resource, $part);          $result .= getDescription($resource, $part);
         if ($color) {$result .= "</b></font>"; }          if ($color) {$result .= "</b></font>"; }
     }      }
       if ($resource->is_map()) {
           if (&Apache::lonnet::allowed('mdc')) {
               if ($resource->symb=~/^uploaded/) {
                  $result.="&nbsp;<a href='/adm/coursedocs?command=direct&symb=".&escape($resource->symb())."'>".
                                 "<span class='LC_setting'>".&mt("Edit Content").'</span></a>&nbsp;';
               }
           }
       }
     if ($resource->is_map() && &advancedUser() && $resource->randompick()) {      if ($resource->is_map() && &advancedUser() && $resource->randompick()) {
         $result .= &mt('(randomly select [_1])', $resource->randompick());          $result .= &mt('(randomly select [_1])', $resource->randompick());
     }      }
Line 1437  sub render { Line 1452  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 1465  sub render { Line 1483  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 1486  END Line 1507  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.="<td class=\"LC_middle\">".mt('Tools:')."</td>";  
  $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 1756  END Line 1767  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
Line 1818  END Line 1829  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.=&Apache::loncommon::end_data_table();      $result.=&Apache::loncommon::end_data_table();
Line 1843  sub add_linkitem { Line 1853  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 1998  sub new { Line 1975  sub new {
     my $proto = shift;      my $proto = shift;
     my $class = ref($proto) || $proto;      my $class = ref($proto) || $proto;
     my $self = {};      my $self = {};
       bless($self); # So we can call change_user if neceesary
   
       $self->{USERNAME} = shift || $env{'user.name'};
       $self->{DOMAIN}   = shift || $env{'user.domain'};
   
   
   
     # Resource cache stores navmap resources as we reference them. We generate      # Resource cache stores navmap resources as we reference them. We generate
     # them on-demand so we don't pay for creating resources unless we use them.      # them on-demand so we don't pay for creating resources unless we use them.
Line 2007  sub new { Line 1990  sub new {
     # failed      # failed
     $self->{NETWORK_FAILURE} = 0;      $self->{NETWORK_FAILURE} = 0;
   
     # tie the nav hash      # We can only tie the nav hash as done below if the username/domain
       # match the env one. Otherwise change_user does everything we need...since we can't
       # assume there are course hashes for the specific requested user@domamin:
       #
   
     my %navmaphash;      if (($self->{USERNAME} eq $env{'user.name'}) && ($self->{DOMAIN} eq $env{'user.domain'})) {
     my %parmhash;  
     my $courseFn = $env{"request.course.fn"};   # tie the nav hash
     if (!(tie(%navmaphash, 'GDBM_File', "${courseFn}.db",  
               &GDBM_READER(), 0640))) {   my %navmaphash;
         return undef;   my %parmhash;
    my $courseFn = $env{"request.course.fn"};
    if (!(tie(%navmaphash, 'GDBM_File', "${courseFn}.db",
     &GDBM_READER(), 0640))) {
       return undef;
    }
   
    if (!(tie(%parmhash, 'GDBM_File', "${courseFn}_parms.db",
     &GDBM_READER(), 0640)))
    {
       untie %{$self->{PARM_HASH}};
       return undef;
    }
   
    $self->{NAV_HASH} = \%navmaphash;
    $self->{PARM_HASH} = \%parmhash;
    $self->{PARM_CACHE} = {};
       } else {
    $self->change_user($self->{USERNAME}, $self->{DOMAIN});
     }      }
           
       return $self;
   }
   
   #
   #  In some instances it is useful to be able to dynamically change the
   # username/domain associated with a navmap (e.g. to navigate for someone
   # else besides the current user...if sufficiently privileged.
   # Parameters:
   #    user  - New user.
   #    domain- Domain the user belongs to.
   # Implicit inputs:
   #   
   sub change_user {
       my $self = shift;
       $self->{USERNAME} = shift;
       $self->{DOMAIN}   = shift;
   
       # If the hashes are already tied make sure to break that bond:
   
       untie %{$self->{NAV_HASH}}; 
       untie %{$self->{PARM_HASH}};
   
       # The assumption is that we have to
       # use lonmap here to re-read the hash and from it reconstruct
       # new big and parameter hashes.  An implicit assumption at this time
       # is that the course file is probably not created locally yet
       # an that we will therefore just read without tying.
   
       my ($cdom, $cnum) = split(/\_/, $env{'request.course.id'});
   
       my %big_hash;
       &Apache::lonmap::loadmap($cnum, $cdom, $self->{USERNAME}, $self->{DOMAIN}, \%big_hash);
       $self->{NAV_HASH} = \%big_hash;
   
       # Now clear the parm cache and reconstruct the parm hash fromt he big_hash
       # param.xxxx keys.
   
       $self->{PARM_CACHE} = {};
           
     if (!(tie(%parmhash, 'GDBM_File', "${courseFn}_parms.db",      my %parm_hash = {};
               &GDBM_READER(), 0640)))      foreach my $key (keys %big_hash) {
     {   if ($key =~ /^param\./) {
         untie %{$self->{PARM_HASH}};      my $param_key = $key;
         return undef;      $param_key =~ s/^param\.//;
       $parm_hash{$param_key} = $big_hash{$key};
    }
     }      }
   
     $self->{NAV_HASH} = \%navmaphash;      $self->{PARM_HASH} = \%parm_hash;
     $self->{PARM_HASH} = \%parmhash;  
     $self->{PARM_CACHE} = {};  
   
     bless($self);  
               
     return $self;  } 
 }  
   
 sub generate_course_user_opt {  sub generate_course_user_opt {
     my $self = shift;      my $self = shift;
     if ($self->{COURSE_USER_OPT_GENERATED}) { return; }      if ($self->{COURSE_USER_OPT_GENERATED}) { return; }
   
     my $uname=$env{'user.name'};      my $uname=$self->{USERNAME};
     my $udom=$env{'user.domain'};      my $udom=$self->{DOMAIN};
   
     my $cid=$env{'request.course.id'};      my $cid=$env{'request.course.id'};
     my $cdom=$env{'course.'.$cid.'.domain'};      my $cdom=$env{'course.'.$cid.'.domain'};
     my $cnum=$env{'course.'.$cid.'.num'};      my $cnum=$env{'course.'.$cid.'.num'};
Line 2081  sub generate_email_discuss_status { Line 2124  sub generate_email_discuss_status {
     my $cdom=$env{'course.'.$cid.'.domain'};      my $cdom=$env{'course.'.$cid.'.domain'};
     my $cnum=$env{'course.'.$cid.'.num'};      my $cnum=$env{'course.'.$cid.'.num'};
           
     my %emailstatus = &Apache::lonnet::dump('email_status');      my %emailstatus = &Apache::lonnet::dump('email_status',$self->{DOMAIN},$self->{USERNAME});
     my $logoutTime = $emailstatus{'logout'};      my $logoutTime = $emailstatus{'logout'};
     my $courseLeaveTime = $emailstatus{'logout_'.$env{'request.course.id'}};      my $courseLeaveTime = $emailstatus{'logout_'.$env{'request.course.id'}};
     $self->{LAST_CHECK} = (($courseLeaveTime > $logoutTime) ?      $self->{LAST_CHECK} = (($courseLeaveTime > $logoutTime) ?
Line 2089  sub generate_email_discuss_status { Line 2132  sub generate_email_discuss_status {
     my %discussiontime = &Apache::lonnet::dump('discussiontimes',       my %discussiontime = &Apache::lonnet::dump('discussiontimes', 
        $cdom, $cnum);         $cdom, $cnum);
     my %lastread = &Apache::lonnet::dump('nohist_'.$cid.'_discuss',      my %lastread = &Apache::lonnet::dump('nohist_'.$cid.'_discuss',
                                         $env{'user.domain'},$env{'user.name'},'lastread');                                          $self->{DOMAIN},$self->{USERNAME},'lastread');
     my %lastreadtime = ();      my %lastreadtime = ();
     foreach my $key (keys %lastread) {      foreach my $key (keys %lastread) {
         my $shortkey = $key;          my $shortkey = $key;
Line 2099  sub generate_email_discuss_status { Line 2142  sub generate_email_discuss_status {
   
     my %feedback=();      my %feedback=();
     my %error=();      my %error=();
     my @keys = &Apache::lonnet::getkeys('nohist_email',$env{'user.domain'},      my @keys = &Apache::lonnet::getkeys('nohist_email',$self->{DOMAIN},
  $env{'user.name'});   $self->{USERNAME});
           
     foreach my $msgid (@keys) {      foreach my $msgid (@keys) {
  if ((!$emailstatus{$msgid}) || ($emailstatus{$msgid} eq 'new')) {   if ((!$emailstatus{$msgid}) || ($emailstatus{$msgid} eq 'new')) {
Line 2148  sub get_user_data { Line 2191  sub get_user_data {
   
     # Retrieve performance data on problems      # Retrieve performance data on problems
     my %student_data = Apache::lonnet::currentdump($env{'request.course.id'},      my %student_data = Apache::lonnet::currentdump($env{'request.course.id'},
    $env{'user.domain'},     $self->{DOMAIN},
    $env{'user.name'});     $self->{USERNAME});
     $self->{STUDENT_DATA} = \%student_data;      $self->{STUDENT_DATA} = \%student_data;
   
     $self->{RETRIEVED_USER_DATA} = 1;      $self->{RETRIEVED_USER_DATA} = 1;
Line 2378  resource object. Line 2421  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 2463  sub parmval { Line 2506  sub parmval {
     my $self = shift;      my $self = shift;
     my ($what,$symb,$recurse)=@_;      my ($what,$symb,$recurse)=@_;
     my $hashkey = $what."|||".$symb;      my $hashkey = $what."|||".$symb;
       my $cache = $self->{PARM_CACHE};
     if (defined($self->{PARM_CACHE}->{$hashkey})) {      if (defined($self->{PARM_CACHE}->{$hashkey})) {
         if (ref($self->{PARM_CACHE}->{$hashkey}) eq 'ARRAY') {           if (ref($self->{PARM_CACHE}->{$hashkey}) eq 'ARRAY') { 
             if (defined($self->{PARM_CACHE}->{$hashkey}->[0])) {              if (defined($self->{PARM_CACHE}->{$hashkey}->[0])) {
Line 2500  sub parmval_real { Line 2543  sub parmval_real {
         @cgrps = sort(@cgrps);          @cgrps = sort(@cgrps);
         $cgroup = $cgrps[0];          $cgroup = $cgrps[0];
     }       } 
     my $uname=$env{'user.name'};      my $uname=$self->{USERNAME};
     my $udom=$env{'user.domain'};      my $udom=$self->{DOMAIN};
   
     unless ($symb) { return ['']; }      unless ($symb) { return ['']; }
     my $result='';      my $result='';
Line 2648  in the filter function. Line 2691  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 2903  sub new { Line 2946  sub new {
     weaken($self->{NAV_MAP} = shift);      weaken($self->{NAV_MAP} = shift);
     return undef unless ($self->{NAV_MAP});      return undef unless ($self->{NAV_MAP});
   
       $self->{USERNAME} = $self->{NAV_MAP}->{USERNAME};
       $self->{DOMAIN}   = $self->{NAV_MAP}->{DOMAIN};
   
     # Handle the parameters      # Handle the parameters
     $self->{FIRST_RESOURCE} = shift || $self->{NAV_MAP}->firstResource();      $self->{FIRST_RESOURCE} = shift || $self->{NAV_MAP}->firstResource();
     $self->{FINISH_RESOURCE} = shift || $self->{NAV_MAP}->finishResource();      $self->{FINISH_RESOURCE} = shift || $self->{NAV_MAP}->finishResource();
Line 3276  sub new { Line 3322  sub new {
     weaken($self->{NAV_MAP} = shift);      weaken($self->{NAV_MAP} = shift);
     return undef unless ($self->{NAV_MAP});      return undef unless ($self->{NAV_MAP});
   
       $self->{USERNAME} = $self->{NAV_MAP}->{USERNAME};
       $self->{DOMAIN}   = $self->{NAV_MAP}->{DOMAIN};
   
     $self->{FIRST_RESOURCE} = shift || $self->{NAV_MAP}->firstResource();      $self->{FIRST_RESOURCE} = shift || $self->{NAV_MAP}->firstResource();
     $self->{FINISH_RESOURCE} = shift || $self->{NAV_MAP}->finishResource();      $self->{FINISH_RESOURCE} = shift || $self->{NAV_MAP}->finishResource();
   
Line 3512  sub new { Line 3561  sub new {
     weaken($self->{NAV_MAP} = shift);      weaken($self->{NAV_MAP} = shift);
     $self->{ID} = shift;      $self->{ID} = shift;
   
       $self->{USERNAME} = $self->{NAV_MAP}->{USERNAME};
       $self->{DOMAIN}   = $self->{NAV_MAP}->{DOMAIN};
   
     # Store this new resource in the parent nav map's cache.      # Store this new resource in the parent nav map's cache.
     $self->{NAV_MAP}->{RESOURCE_CACHE}->{$self->{ID}} = $self;      $self->{NAV_MAP}->{RESOURCE_CACHE}->{$self->{ID}} = $self;
     $self->{RESOURCE_ERROR} = 0;      $self->{RESOURCE_ERROR} = 0;
Line 3534  sub navHash { Line 3586  sub navHash {
     my $param = shift;      my $param = shift;
     my $id = shift;      my $id = shift;
     my $arg = $param . ($id?$self->{ID}:"");      my $arg = $param . ($id?$self->{ID}:"");
     if (defined($arg)) {      if (ref($self) && ref($self->{NAV_MAP}) && defined($arg)) {
         return $self->{NAV_MAP}->navhash($arg);          return $self->{NAV_MAP}->navhash($arg);
     }      }
     return;      return;
Line 3775  sub is_practice { Line 3827  sub is_practice {
 sub is_problem {  sub is_problem {
     my $self=shift;      my $self=shift;
     my $src = $self->src();      my $src = $self->src();
     if ($src =~ /\.(problem|exam|quiz|assess|survey|form|library|task)$/) {      if ($src =~ /$LONCAPA::assess_re/) {
  return !($self->is_practice());   return !($self->is_practice());
     }      }
     return 0;      return 0;
Line 3798  my %incomplete_hash = Line 3850  my %incomplete_hash =
 sub is_incomplete {  sub is_incomplete {
     my $self = shift;      my $self = shift;
     if ($self->is_problem()) {      if ($self->is_problem()) {
  &Apache::lonnet::logthis('is problem');  
  foreach my $part (@{$self->parts()}) {   foreach my $part (@{$self->parts()}) {
     &Apache::lonnet::logthis("$part status ".$self->status($part));  
     if (exists($incomplete_hash{$self->status($part)})) {      if (exists($incomplete_hash{$self->status($part)})) {
  return 1;   return 1;
     }      }
Line 3812  sub is_incomplete { Line 3862  sub is_incomplete {
 sub is_raw_problem {  sub is_raw_problem {
     my $self=shift;      my $self=shift;
     my $src = $self->src();      my $src = $self->src();
     if ($src =~ /\.(problem|exam|quiz|assess|survey|form|library|task)$/) {      if ($src =~ /$LONCAPA::assess_re/) {
         return 1;          return 1;
     }      }
     return 0;      return 0;
Line 3844  sub is_survey { Line 3894  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 3852  sub is_survey { Line 3902  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 3905  resource of the map. Line 3964  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 3935  sub map_type { Line 4000  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 3965  their code.) Line 4035  their code.)
   
 =over 4  =over 4
   
 =item * B<acc>:  =item * B<printable>
   
   returns true if the current date is such that the 
   specified resource part is printable.
   
   =item * B<resprintable>
   
   Returns true if all parts in the resource are printable making the
   entire resource printable.
   
   =item * B<acc>
   
 Get the Client IP/Name Access Control information.  Get the Client IP/Name Access Control information.
   
Line 4018  Get the weight for the problem. Line 4098  Get the weight for the problem.
   
 =cut  =cut
   
   sub printable {
   
       my ($self, $part) = @_;
   
       # Get the print open/close dates for the resource.
   
       my $start = $self->parmval("prinstartdate", $part);
       my $end   = $self->parmval("printenddate", $part);
   
       #  The following cases apply:
       #  - No dates set: Printable.
       #  - Start date set but no end date: Printable if now >= start date.
       #  - End date set but no start date: Printable if now <= end date.
       #  - both defined: printable if start <= now <= end
       #
       my $now  = time();
   
       my $startok = 1;
       my $endok   = 1;
   
       if ((defined $start) && ($start ne '')) {
    $startok = $start <= $now;
       }
       if ((defined $end) && ($end != '')) {
    $endok = $end >= $now;
       }
       return $startok && $endok;
   }
   
   sub resprintable {
       my $self = shift;
   
       # get parts...or realize there are no parts.
   
       my $partsref = $self->parts();
       my @parts    = @$partsref;
   
       if ((!defined(@parts)) || (scalar(@parts) == 0)) {
    return $self->printable(0);
       } else {
    foreach my $part  (@parts) {
       if (!$self->printable($part)) { 
    return 0; 
       }
    }
    return 1;
       }
   }
   
 sub acc {  sub acc {
     (my $self, my $part) = @_;      (my $self, my $part) = @_;
     my $acc = $self->parmval("acc", $part);      my $acc = $self->parmval("acc", $part);
Line 4070  sub checkedin { Line 4199  sub checkedin {
     }      }
 }  }
 # this should work exactly like the copy in lonhomework.pm  # this should work exactly like the copy in lonhomework.pm
   # Why is there a copy in lonhomework?  Why not centralized?
   #
   #  TODO: Centralize duedate.
   #
   
 sub duedate {  sub duedate {
     (my $self, my $part) = @_;      (my $self, my $part) = @_;
     my $date;      my $date;
Line 4149  sub weight { Line 4283  sub weight {
     my $self = shift; my $part = shift;      my $self = shift; my $part = shift;
     if (!defined($part)) { $part = '0'; }      if (!defined($part)) { $part = '0'; }
     my $weight = &Apache::lonnet::EXT('resource.'.$part.'.weight',      my $weight = &Apache::lonnet::EXT('resource.'.$part.'.weight',
                                 $self->symb(), $env{'user.domain'},                                  $self->symb(), $self->{DOMAIN},
                                 $env{'user.name'},                                  $self->{USERNAME},
                                 $env{'request.course.sec'});                                  $env{'request.course.sec'});
     return $weight;      return $weight;
 }  }
Line 4178  sub getReturnHash { Line 4312  sub getReturnHash {
     my $self = shift;      my $self = shift;
           
     if (!defined($self->{RETURN_HASH})) {      if (!defined($self->{RETURN_HASH})) {
         my %tmpHash  = &Apache::lonnet::restore($self->symb());          my %tmpHash  = &Apache::lonnet::restore($self->symb(),undef,$self->{DOMAIN},$self->{USERNAME});
         $self->{RETURN_HASH} = \%tmpHash;          $self->{RETURN_HASH} = \%tmpHash;
     }      }
 }         }       
Line 4690  Information not available due to network Line 4824  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 4701  sub CORRECT               { return 13; } Line 4839  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 4719  sub getCompletionStatus { Line 4858  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 4808  The item is open and not yet tried. Line 4954  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 4881  sub status { Line 5031  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 4983  sub check_for_slot { Line 5137  sub check_for_slot {
                 my $taskstatus = $self->taskstatus();                  my $taskstatus = $self->taskstatus();
                 $is_correct = (($taskstatus eq 'pass') ||                   $is_correct = (($taskstatus eq 'pass') || 
                                ($self->solved() =~ /^correct_/));                                 ($self->solved() =~ /^correct_/));
                 $got_grade = ($self->solved() =~ /^(?:pass|fail)$/);                  $got_grade = ($taskstatus =~ /^(?:pass|fail)$/);
             } else {              } else {
                 $got_grade = 1;                  $got_grade = 1;
                 $is_correct = ($self->solved() =~ /^correct_/);                     $is_correct = ($self->solved() =~ /^correct_/);   
Line 5073  my %compositeToSimple = Line 5227  my %compositeToSimple =
       INCORRECT()             => INCORRECT,        INCORRECT()             => INCORRECT,
       OPEN()                  => OPEN,        OPEN()                  => OPEN,
       ATTEMPTED()             => ATTEMPTED,        ATTEMPTED()             => ATTEMPTED,
         CREDIT_ATTEMPTED()      => CORRECT,
       ANSWER_SUBMITTED()      => ATTEMPTED        ANSWER_SUBMITTED()      => ATTEMPTED
      );       );
   
Line 5147  sub completable { Line 5302  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.443  
changed lines
  Added in v.1.468


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