Diff for /loncom/interface/lonnavmaps.pm between versions 1.437 and 1.444.2.3

version 1.437, 2009/10/26 10:16:56 version 1.444.2.3, 2010/12/30 21:32:17
Line 49  described at http://www.lon-capa.org. Line 49  described at http://www.lon-capa.org.
   
 =head1 OVERVIEW  =head1 OVERVIEW
   
 X<lonnavmaps, overview When a user enters a course, LON-CAPA examines the  X<lonnavmaps, overview> When a user enters a course, LON-CAPA examines the
 course structure and caches it in what is often referred to as the  course structure and caches it in what is often referred to as the
 "big hash" X<big hash>. You can see it if you are logged into  "big hash" X<big hash>. You can see it if you are logged into
 LON-CAPA, in a course, by going to /adm/test. (You may need to  LON-CAPA, in a course, by going to /adm/test. (You may need to
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 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 492  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 505  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 527  my %colormap =
       $resObj->INCORRECT              => '',        $resObj->INCORRECT              => '',
       $resObj->OPEN                   => '',        $resObj->OPEN                   => '',
       $resObj->NOTHING_SET            => '',        $resObj->NOTHING_SET            => '',
         $resObj->CREDIT_ATTEMPTED       => '',
       $resObj->ATTEMPTED              => '',        $resObj->ATTEMPTED              => '',
       $resObj->ANSWER_SUBMITTED       => '',        $resObj->ANSWER_SUBMITTED       => '',
       $resObj->PARTIALLY_CORRECT      => '#006600'        $resObj->PARTIALLY_CORRECT      => '#006600'
Line 696  sub getDescription { Line 701  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 1034  sub render_communication_status { Line 1048  sub render_communication_status {
     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 1044  sub render_communication_status { Line 1058  sub render_communication_status {
             if ($msgid) {              if ($msgid) {
                 $feedbackHTML .= '&nbsp;<a '.$target.' href="/adm/email?display='                  $feedbackHTML .= '&nbsp;<a '.$target.' 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 1058  sub render_communication_status { Line 1072  sub render_communication_status {
                 $errorcount++;                  $errorcount++;
                 $errorHTML .= '&nbsp;<a '.$target.' href="/adm/email?display='                  $errorHTML .= '&nbsp;<a '.$target.' 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 1091  sub render_quick_status { Line 1105  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 1433  sub render { Line 1447  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 1461  sub render { Line 1478  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 1482  END Line 1502  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><td>&nbsp;</td>'.
  if ($env{'environment.remotenavmap'} ne 'on') {                     '<td class="LC_middle">'.&mt('Tools:').'</td>'.
     $result .= '<td>&nbsp;</td>';                      &show_linkitems_toolbar($args->{'linkitems'});
         } else {  
     $result .= '</tr><tr>';   
         }  
  $result.="<td class=\"LC_middle\">".mt('Tools:')."</td>";  
  $result.=&show_linkitems_toolbar($args->{'linkitems'});  
         if ($args->{'sort_html'}) {          if ($args->{'sort_html'}) {
     if ($env{'environment.remotenavmap'} ne 'on') {      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 {              } else {
  $result.='</tr><tr><td align="left"><br />'.          $result .= '</tr><tr><td align="left" colspan="4"><br />'.
     $args->{'sort_html'}.'</td></tr>';                             $args->{'sort_html'}.'</td></tr>';
     }              }
  }          } else {
               $result .= '</tr>';
           }
         $result .= '</table>';          $result .= '</table>';
     } elsif ($args->{'sort_html'}) {       } elsif ($args->{'sort_html'}) { 
         $result.=$args->{'sort_html'};           $result.=$args->{'sort_html'}; 
Line 1525  END Line 1541  END
         ( $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 1753  END Line 1768  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 .= &Apache::loncommon::start_data_table_row();              $result .= &Apache::loncommon::start_data_table_row();
   
Line 1816  END Line 1830  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 1841  sub add_linkitem { Line 1854  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 = ("launchnav","closenav","firsthomework",
      "everything","uncompleted","changefolder","clearbubbles");       "everything","uncompleted","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 2376  resource object. Line 2356  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 3531  sub navHash { Line 3511  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 3774  sub is_problem { Line 3758  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 3809  sub is_survey { Line 3822  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 3817  sub is_survey { Line 3830  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 3870  resource of the map. Line 3892  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 3900  sub map_type { Line 3928  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 4655  Information not available due to network Line 4689  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 4666  sub CORRECT               { return 13; } Line 4704  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 4684  sub getCompletionStatus { Line 4723  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 4773  The item is open and not yet tried. Line 4819  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 4846  sub status { Line 4896  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 5038  my %compositeToSimple = Line 5092  my %compositeToSimple =
       INCORRECT()             => INCORRECT,        INCORRECT()             => INCORRECT,
       OPEN()                  => OPEN,        OPEN()                  => OPEN,
       ATTEMPTED()             => ATTEMPTED,        ATTEMPTED()             => ATTEMPTED,
         CREDIT_ATTEMPTED()      => CORRECT,
       ANSWER_SUBMITTED()      => ATTEMPTED        ANSWER_SUBMITTED()      => ATTEMPTED
      );       );
   
Line 5111  sub completable { Line 5166  sub completable {
         # "If any of the parts are open, or have tries left (implies open),          # "If any of the parts are open, or have tries left (implies open),
         # 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() ||
     $status == ANSWER_SUBMITTED() ) {              $self->getCompletionStatus($part) == CREDIT_ATTEMPTED() ||
               $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.437  
changed lines
  Added in v.1.444.2.3


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