Diff for /loncom/interface/lonfeedback.pm between versions 1.341 and 1.347

version 1.341, 2012/03/15 13:27:25 version 1.347, 2012/03/16 18:32:47
Line 277  sub list_discussion { Line 277  sub list_discussion {
     $visit ++;      $visit ++;
   
     my $seeid;      my $seeid;
     if (($group ne '') && ($mode eq 'board') &&       if (&Apache::lonnet::allowed('rin',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))) {
         ($ressymb =~ m|^bulletin___\d+___adm/wrapper/adm/\Q$cdom\E/\Q$cnum\E/\d+/bulletinboard$|)) {          $seeid = 1;
         if (&check_group_priv($group,'dgp') eq 'ok') {  
             $seeid = 1;  
         }  
     } else {  
         $seeid=&Apache::lonnet::allowed('rin',$crs);  
     }      }
       my $seehidden = &can_see_hidden($mode,$ressymb,undef,$group,$cdom,$cnum,$crs);
   
 # Is voting on discussions available  # Is voting on discussions available
     my $realsymb = &get_realsymb($ressymb);      my $realsymb = &get_realsymb($ressymb);
Line 311  sub list_discussion { Line 307  sub list_discussion {
     $discinfo{$visitkey} = $visit;      $discinfo{$visitkey} = $visit;
   
     &Apache::lonnet::put('nohist_'.$cid.'_discuss',\%discinfo,$env{'user.domain'},$env{'user.name'});      &Apache::lonnet::put('nohist_'.$cid.'_discuss',\%discinfo,$env{'user.domain'},$env{'user.name'});
     &build_posting_display(\%usernamesort,\%subjectsort,\%namesort,\%notshown,\%newitem,\%dischash,\%shown,\%alldiscussion,\%imsitems,\%imsfiles,\%roleinfo,\@discussionitems,\@replies,\@depth,\@posters,\$maxdepth,\$visible,\$newpostsflag,\$current,$status,$viewgrades,$seeid,$canvote,$prevread,$sortposts,$encsymb,$readkey,$showunmark,$showonlyunread,$totposters,\@rolefilter,\@sectionpick,\@grouppick,$classgroups,$statusfilter,$toggkey,$outputtarget,\%anonhash,$anoncnt,$group);      &build_posting_display(\%usernamesort,\%subjectsort,\%namesort,\%notshown,\%newitem,\%dischash,\%shown,\%alldiscussion,\%imsitems,\%imsfiles,\%roleinfo,\@discussionitems,\@replies,\@depth,\@posters,\$maxdepth,\$visible,\$newpostsflag,\$current,$status,$viewgrades,$seeid,$seehidden,$canvote,$prevread,$sortposts,$encsymb,$readkey,$showunmark,$showonlyunread,$totposters,\@rolefilter,\@sectionpick,\@grouppick,$classgroups,$statusfilter,$toggkey,$outputtarget,\%anonhash,$anoncnt,$group);
   
     my $discussion='';      my $discussion='';
     my $manifestfile;      my $manifestfile;
Line 467  imscp_v1p1.xsd http://www.imsglobal.org/ Line 463  imscp_v1p1.xsd http://www.imsglobal.org/
                          "\n".'<table width="100%" class="LC_discussion">';                           "\n".'<table width="100%" class="LC_discussion">';
             $discussion .= &action_links_bar($colspan,$ressymb,$visible,              $discussion .= &action_links_bar($colspan,$ressymb,$visible,
                                              $newpostsflag,$group,                                               $newpostsflag,$group,
                                              $prevread,$markondisp);                                               $prevread,$markondisp,$seehidden);
             my $escsymb=&escape($ressymb);              my $escsymb=&escape($ressymb);
             my $numhidden = keys(%notshown);              my $numhidden = keys(%notshown);
             if ($numhidden > 0) {              if ($numhidden > 0) {
Line 671  END Line 667  END
 END  END
             $discussion .= &action_links_bar($colspan,$ressymb,$visible,              $discussion .= &action_links_bar($colspan,$ressymb,$visible,
                                              $newpostsflag,$group,                                               $newpostsflag,$group,
                                              $prevread,$markondisp);                                               $prevread,$markondisp,$seehidden);
             $discussion .= "</table></form>\n";              $discussion .= "</table></form>\n";
         }           } 
         if ($outputtarget eq 'export') {          if ($outputtarget eq 'export') {
Line 788  END Line 784  END
     return $discussion;      return $discussion;
 }  }
   
   sub can_see_hidden {
       my ($mode,$ressymb,$feedurl,$group,$cdom,$cnum,$crs) = @_;
       my $seehidden;
       if ($env{'request.course.id'}) {
           unless ($cdom ne '' && $cnum ne '') {
               $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
               $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
           }
           if ($crs eq '') {
               $crs = '/'.$env{'request.course.id'};
               if ($env{'request.course.sec'}) {
                   $crs.='_'.$env{'request.course.sec'};
               }
               $crs=~s{_}{/}g;
           }
           if ($mode eq '') {
               $mode='board';
               if ($feedurl =~ /$LONCAPA::assess_re/) {
                   $mode='problem';
               }
           }
           if (($group ne '') && ($mode eq 'board') &&
               ($ressymb =~ m{^bulletin___\d+\Q___adm/wrapper/adm/$cdom/$cnum/\E\d+/bulletinboard$})) {
               if (&check_group_priv($group,'dgp') eq 'ok') {
                   $seehidden = 1;
               }
           } else {
               $seehidden=&Apache::lonnet::allowed('rin',$crs);
           }
       }
       return $seehidden;
   }
   
 sub discussion_link {  sub discussion_link {
    my ($ressymb,$linktext,$cmd,$item,$flag,$prev,$adds,$title)=@_;     my ($ressymb,$linktext,$cmd,$item,$flag,$prev,$adds,$title)=@_;
Line 828  sub send_message_link { Line 856  sub send_message_link {
 }  }
   
 sub action_links_bar {  sub action_links_bar {
     my ($colspan,$ressymb,$visible,$newpostsflag,$group,$prevread,$markondisp) = @_;      my ($colspan,$ressymb,$visible,$newpostsflag,$group,$prevread,$markondisp,
           $seehidden) = @_;
     my $discussion = '<tr><td colspan="'.$colspan.'">'.      my $discussion = '<tr><td colspan="'.$colspan.'">'.
                      '<table width="100%"><tr>'.                       '<table width="100%"><tr>'.
                      '<td class="LC_disc_action_left">';                       '<td class="LC_disc_action_left">';
Line 861  sub action_links_bar { Line 890  sub action_links_bar {
     }      }
     $discussion .= &group_args($group);      $discussion .= &group_args($group);
     $discussion .= '">'.&mt('Export').'</a>';      $discussion .= '">'.&mt('Export').'</a>';
     if (&Apache::lonnet::allowed('rin',$env{'request.course.id'})) {      if ($seehidden) {
         $discussion .= '&nbsp;&nbsp;';          $discussion .= '&nbsp;&nbsp;';
         $discussion .='<a href="/adm/feedback?undeleteall='.$escsymb;          $discussion .='<a href="/adm/feedback?undeleteall='.$escsymb;
         if ($newpostsflag) {          if ($newpostsflag) {
Line 968  ENDDISCUSS Line 997  ENDDISCUSS
 }  }
   
 sub build_posting_display {  sub build_posting_display {
     my ($usernamesort,$subjectsort,$namesort,$notshown,$newitem,$dischash,$shown,$alldiscussion,$imsitems,$imsfiles,$roleinfo,$discussionitems,$replies,$depth,$posters,$maxdepth,$visible,$newpostsflag,$current,$status,$viewgrades,$seeid,$canvote,$prevread,$sortposts,$ressymb,$readkey,$showunmark,$showonlyunread,$totposters,$rolefilter,$sectionpick,$grouppick,$classgroups,$statusfilter,$toggkey,$outputtarget,$anonhash,$anoncnt,$group) = @_;      my ($usernamesort,$subjectsort,$namesort,$notshown,$newitem,$dischash,$shown,$alldiscussion,$imsitems,$imsfiles,$roleinfo,$discussionitems,$replies,$depth,$posters,$maxdepth,$visible,$newpostsflag,$current,$status,$viewgrades,$seeid,$seehidden,$canvote,$prevread,$sortposts,$ressymb,$readkey,$showunmark,$showonlyunread,$totposters,$rolefilter,$sectionpick,$grouppick,$classgroups,$statusfilter,$toggkey,$outputtarget,$anonhash,$anoncnt,$group) = @_;
     my @original=();      my @original=();
     my @index=();      my @index=();
     my $skip_group_check = 0;      my $skip_group_check = 0;
Line 1031  sub build_posting_display { Line 1060  sub build_posting_display {
                 my $idx=$id;                  my $idx=$id;
                 next if ($contrib{$idx.':deleted'});                  next if ($contrib{$idx.':deleted'});
                 next if ($contrib{$idx.':hidden'});                  next if ($contrib{$idx.':hidden'});
                 unless ((($hiddens{$idx}) && (!$seeid)) || ($deletions{$idx}) || (!$contrib{$idx.':message'})) {                  unless ((($hiddens{$idx}) && (!$seehidden)) || ($deletions{$idx}) || (!$contrib{$idx.':message'})) {
                     if ($likes{$symb.':'.$idx.':likes'} ne '') {                      if ($likes{$symb.':'.$idx.':likes'} ne '') {
                         push(@theselikes,$likes{$symb.':'.$idx.':likes'});                          push(@theselikes,$likes{$symb.':'.$idx.':likes'});
                         if (ref($likes{$symb.':'.$idx.':likers'}) eq 'HASH') {                          if (ref($likes{$symb.':'.$idx.':likers'}) eq 'HASH') {
Line 1108  sub build_posting_display { Line 1137  sub build_posting_display {
     } else {      } else {
  $$replies[$$depth[$idx]]=1;   $$replies[$$depth[$idx]]=1;
     }      }
             unless ((($hiddens{$idx}) && (!$seeid)) || ($deletions{$idx})) {              unless ((($hiddens{$idx}) && (!$seehidden)) || ($deletions{$idx})) {
  $$visible++;   $$visible++;
                 if ($contrib{$idx.':history'}) {                  if ($contrib{$idx.':history'}) {
                     if ($contrib{$idx.':history'} =~ /:/) {                      if ($contrib{$idx.':history'} =~ /:/) {
Line 1133  sub build_posting_display { Line 1162  sub build_posting_display {
     $$anonhash{$key}=&mt('Anonymous').' '.$anoncnt;      $$anonhash{$key}=&mt('Anonymous').' '.$anoncnt;
  }   }
                 my ($message,$subject,$vgrlink,$ctlink);                  my ($message,$subject,$vgrlink,$ctlink);
                 &get_post_contents(\%contrib,$idx,$seeid,$outputtarget,\%messages,\%subjects,\%allattachments,\%attachtxt,$imsfiles,\$screenname,\$plainname,\$showaboutme,$numoldver);                  &get_post_contents(\%contrib,$idx,$seeid,$seehidden,$outputtarget,\%messages,\%subjects,\%allattachments,\%attachtxt,$imsfiles,\$screenname,\$plainname,\$showaboutme,$numoldver);
   
   
 # Set up for sorting by subject  # Set up for sorting by subject
Line 1223  sub build_posting_display { Line 1252  sub build_posting_display {
                                     if (($env{'user.domain'} eq $contrib{$idx.':senderdomain'}) && ($env{'user.name'} eq $contrib{$idx.':sendername'})) {                                      if (($env{'user.domain'} eq $contrib{$idx.':senderdomain'}) && ($env{'user.name'} eq $contrib{$idx.':sendername'})) {
                                         $sender.=' '.                                          $sender.=' '.
                                          &discussion_link($symb,&mt('Edit'),'editdisc',$idx,$$newpostsflag,$prevread,&group_args($group));                                           &discussion_link($symb,&mt('Edit'),'editdisc',$idx,$$newpostsflag,$prevread,&group_args($group));
                                         unless ($seeid) {                                          unless ($seehidden) {
                                             my $grpargs = &group_args($group);                                              my $grpargs = &group_args($group);
                                             $sender.=" <a href=\"javascript:verifydelete('studentdelete','$escsymb','$idx','$$newpostsflag','$prevread','$grpargs')";                                              $sender.=" <a href=\"javascript:verifydelete('studentdelete','$escsymb','$idx','$$newpostsflag','$prevread','$grpargs')";
                                             $sender .= '">'.&mt('Delete').'</a>';                                              $sender .= '">'.&mt('Delete').'</a>';
                                         }                                          }
                                     }                                      }
                                 }                                  }
         if ($seeid) {          if ($seehidden) {
             if ($hiddens{$idx}) {              if ($hiddens{$idx}) {
                                         unless ($studenthidden) {                                          unless ($studenthidden) {
                             $sender.=' '.                              $sender.=' '.
Line 1333  sub build_posting_display { Line 1362  sub build_posting_display {
                 } else {                  } else {
                     if ($message) {                      if ($message) {
                         my $spansize = 2;                          my $spansize = 2;
                           my ($uname,$udom);
                         if ($showonlyunread && $prevread > $posttime) {                          if ($showonlyunread && $prevread > $posttime) {
                             $$notshown{$idx} = 1;                              $$notshown{$idx} = 1;
                         } elsif ($showunmark && $$dischash{$readkey}=~/\.$idx\./) {                          } elsif ($showunmark && $$dischash{$readkey}=~/\.$idx\./) {
                             $$notshown{$idx} = 1;                              $$notshown{$idx} = 1;
                         } else {                          } else {
 # apply filters  # apply filters
                             my $uname = $contrib{$idx.':sendername'};                              $uname = $contrib{$idx.':sendername'};
                             my $udom = $contrib{$idx.':senderdomain'};                              $udom = $contrib{$idx.':senderdomain'};
                             my $poster = $uname.':'.$udom;                              my $poster = $uname.':'.$udom;
                             if ($env{'form.totposters'} ne '') {                              if ($env{'form.totposters'} ne '') {
                                 if ($totposters == 0) {                                  if ($totposters == 0) {
Line 1424  sub build_posting_display { Line 1454  sub build_posting_display {
                                     '</div></blockquote>';                                      '</div></blockquote>';
                             if ($canvote) {                              if ($canvote) {
 # Put in the like and unlike buttons  # Put in the like and unlike buttons
                                 if ($userlikes{$idx}) {                                  if (($uname eq $env{'user.name'}) && ($udom eq $env{'user.domain'})) {
                                     $$discussionitems[$idx].='<img border="0" src="/res/adm/pages/thumbsup_gray.png" alt="'.&mt('You like this posting').'" />';                                      my $novote = &mt('No voting for your own posts');
                                 } else {                                      $$discussionitems[$idx].=
                                     $$discussionitems[$idx].='&nbsp;'.&discussion_link($symb,'<img border="0" src="/res/adm/pages/thumbsup.png" alt="'.&mt('Like').'" />','like',$idx,$$newpostsflag,$prevread,&group_args($group),&mt("Like this posting"));                                          '<a href="javascript:alert('."'$novote'".');" style="text-decoration: none;">'.
                                 }                                          '<img border="0" src="/res/adm/pages/thumbsup_novote.png" alt="'.$novote.'" />&nbsp;'.
                                 if ($userunlikes{$idx}) {                                          '<img border="0" src="/res/adm/pages/thumbsdown_novote.png" alt="'.$novote.'" /></a>'; 
                                     $$discussionitems[$idx].='<img border="0" src="/res/adm/pages/thumbsdown_gray.png" alt="'.&mt('You unlike this posting').'" />';  
                                 } else {                                  } else {
                                     $$discussionitems[$idx].='&nbsp;'.&discussion_link($symb,'<img border="0" src="/res/adm/pages/thumbsdown.png" alt="'.&mt('Unlike').'" />','unlike',$idx,$$newpostsflag,$prevread,&group_args($group),&mt("Unlike this posting"));                                      if ($userlikes{$idx}) {
                                           $$discussionitems[$idx].='<img border="0" src="/res/adm/pages/thumbsup_gray.png" alt="'.&mt('You like this posting').'" />';
                                       } else {
                                           $$discussionitems[$idx].='&nbsp;'.&discussion_link($symb,'<img border="0" src="/res/adm/pages/thumbsup.png" alt="'.&mt('Like').'" />','like',$idx,$$newpostsflag,$prevread,&group_args($group),&mt("Like this posting"));
                                       }
                                       if ($userunlikes{$idx}) {
                                           $$discussionitems[$idx].='<img border="0" src="/res/adm/pages/thumbsdown_gray.png" alt="'.&mt('You unlike this posting').'" />';
                                       } else {
                                           $$discussionitems[$idx].='&nbsp;'.&discussion_link($symb,'<img border="0" src="/res/adm/pages/thumbsdown.png" alt="'.&mt('Unlike').'" />','unlike',$idx,$$newpostsflag,$prevread,&group_args($group),&mt("Unlike this posting"));
                                       }
                                 }                                  }
                             }                              }
                             if ($seeid || $canvote) {                              if ($seeid || $canvote) {
Line 1447  sub build_posting_display { Line 1485  sub build_posting_display {
                             if ($contrib{$idx.':history'}) {                              if ($contrib{$idx.':history'}) {
                                 my @postversions = ();                                  my @postversions = ();
                                 $$discussionitems[$idx] .= '&nbsp;&nbsp;'.&mt('This post has been edited by the author.');                                  $$discussionitems[$idx] .= '&nbsp;&nbsp;'.&mt('This post has been edited by the author.');
                                 if ($seeid) {                                  if ($seehidden) {
                                     $$discussionitems[$idx] .= '&nbsp;&nbsp;'.                                      $$discussionitems[$idx] .= '&nbsp;&nbsp;'.
                                          &discussion_link($symb,&mt('Display all versions'),'allversions',$idx,$$newpostsflag,$prevread,&group_args($group));                                           &discussion_link($symb,&mt('Display all versions'),'allversions',$idx,$$newpostsflag,$prevread,&group_args($group));
                                 }                                  }
Line 1533  sub filter_regexp { Line 1571  sub filter_regexp {
   
   
 sub get_post_contents {  sub get_post_contents {
     my ($contrib,$idx,$seeid,$type,$messages,$subjects,$allattachments,$attachtxt,$imsfiles,$screenname,$plainname,$showaboutme,$numver) = @_;      my ($contrib,$idx,$seeid,$seehidden,$type,$messages,$subjects,$allattachments,$attachtxt,$imsfiles,$screenname,$plainname,$showaboutme,$numver) = @_;
     my $discussion = '';      my $discussion = '';
     my $start=$numver;      my $start=$numver;
     my $end=$numver + 1;      my $end=$numver + 1;
     %{$$imsfiles{$idx}}=();      %{$$imsfiles{$idx}}=();
     if ($type eq 'allversions') {      if ($type eq 'allversions') {
        unless($seeid) {         unless($seehidden) {
            $discussion=&mt('You do not have privileges to view all versions of posts.').' '.&mt('Please select a different role.');             $discussion=&mt('You do not have privileges to view all versions of posts.').' '.&mt('Please select a different role.');
            return $discussion;             return $discussion;
        }          } 
Line 1931  $latexHelp Line 1969  $latexHelp
 <p>  <p>
 END  END
   
 $r->print(&Apache::lonhtmlcommon::start_pick_box());      $r->print(&Apache::lonhtmlcommon::start_pick_box());
 $r->print(&Apache::lonhtmlcommon::row_title(&mt('Subject')));      $r->print(&Apache::lonhtmlcommon::row_title(&mt('Subject')));
 $r->print('<input type="text" name="subject" size="30" value="'."$subject".'" /></p>');      $r->print('<input type="text" name="subject" size="30" value="'.
 $r->print(&Apache::lonhtmlcommon::row_closure());                $subject.'" /></p>');
 $r->print(&Apache::lonhtmlcommon::row_title(&mt('Message')));      $r->print(&Apache::lonhtmlcommon::row_closure());
 $r->print('<textarea name="comment" id="comment" cols="60" rows="10" $textareaclass>'."$comment".      $r->print(&Apache::lonhtmlcommon::row_title(&mt('Message')));
 '</textarea>');      $r->print('<textarea name="comment" id="comment" cols="60" rows="10" '.
 $r->print(&Apache::lonhtmlcommon::row_closure(1));                $textareaclass.'>'.$comment.
 $r->print(&Apache::lonhtmlcommon::end_pick_box());                '</textarea>');
       $r->print(&Apache::lonhtmlcommon::row_closure(1));
       $r->print(&Apache::lonhtmlcommon::end_pick_box());
   
     if ( ($env{'form.editdisc'}) || ($env{'form.replydisc'}) ) {      if ( ($env{'form.editdisc'}) || ($env{'form.replydisc'}) ) {
         if ($env{'form.origpage'}) {          if ($env{'form.origpage'}) {
Line 2454  sub print_showposters { Line 2494  sub print_showposters {
     $r->send_http_header;      $r->send_http_header;
   
     &Apache::lonenc::check_encrypt(\$symb);      &Apache::lonenc::check_encrypt(\$symb);
     my $crs='/'.$env{'request.course.id'};  
     if ($env{'request.course.sec'}) {  
         $crs.='_'.$env{'request.course.sec'};  
     }  
     $crs=~s/\_/\//g;  
     my $seeid;  
     my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};      my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
     my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};      my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
     my $group = $env{'form.group'};      my $group = $env{'form.group'};
     my $ressymb = &wrap_symb($symb);      my $ressymb = &wrap_symb($symb);
     if (($group ne '') &&      my $seehidden = &can_see_hidden('',$ressymb,$feedurl,$group,$cdom,$cnum);
         ($ressymb =~ m|^bulletin___\d+___adm/wrapper/adm/\Q$cdom\E/\Q$cnum\E/\d+/bulletinboard$|)) {  
         if (&check_group_priv($group,'dgp') eq 'ok') {  
             $seeid = 1;  
         }  
     } else {  
         $seeid=&Apache::lonnet::allowed('rin',$crs);  
     }  
     my %contrib=&Apache::lonnet::restore($symb,$env{'request.course.id'},      my %contrib=&Apache::lonnet::restore($symb,$env{'request.course.id'},
                                          $cdom,$cnum);                                           $cdom,$cnum);
     my %namesort = ();      my %namesort = ();
Line 2487  sub print_showposters { Line 2514  sub print_showposters {
         for (my $idx=1;$idx<=$contrib{'version'};$idx++) {          for (my $idx=1;$idx<=$contrib{'version'};$idx++) {
             my $hidden=($contrib{'hidden'}=~/\.$idx\./);              my $hidden=($contrib{'hidden'}=~/\.$idx\./);
             my $deleted=($contrib{'deleted'}=~/\.$idx\./);              my $deleted=($contrib{'deleted'}=~/\.$idx\./);
             unless ((($hidden) && (!$seeid)) || ($deleted)) {              unless ((($hidden) && (!$seehidden)) || ($deleted)) {
                 if ((!$contrib{$idx.':anonymous'}) || (&Apache::lonnet::allowed('rin',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:'')))) {                  if ((!$contrib{$idx.':anonymous'}) || (&Apache::lonnet::allowed('rin',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:'')))) {
                     my %names = &Apache::lonnet::get('environment',['firstname','lastname'],$contrib{$idx.':senderdomain'},$contrib{$idx.':sendername'});                      my %names = &Apache::lonnet::get('environment',['firstname','lastname'],$contrib{$idx.':senderdomain'},$contrib{$idx.':sendername'});
                     my $lastname = $names{'lastname'};                      my $lastname = $names{'lastname'};
Line 2512  sub print_showposters { Line 2539  sub print_showposters {
                     }                      }
                 }                  }
             }              }
         }          }       
     }      }
   
     my $start_page = &Apache::loncommon::start_page('Discussion options');      my $start_page = &Apache::loncommon::start_page('Discussion options');
Line 3482  END Line 3509  END
                 }                  }
             }              }
         }          }
           if ((ref($currnewattach) eq 'ARRAY') && (@{$currnewattach} > 0)) {
               $r->print($lt{'chth'}.'<br />'."\n");
               foreach my $attach (@{$currnewattach}) {
                   $attach =~ m#/([^/]+)$#;
                   $r->print('<label><input type="checkbox" name="delnewattach" value="'.$attach.'" />&nbsp;'.$1.'</label><br />'."\n");
               }
           }
     }      }
     $r->print(&Apache::lonhtmlcommon::row_closure(1));      $r->print(&Apache::lonhtmlcommon::row_closure(1));
     $r->print(&Apache::lonhtmlcommon::end_pick_box());      $r->print(&Apache::lonhtmlcommon::end_pick_box());
Line 3786  sub handler { Line 3820  sub handler {
   &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},    &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
          ['like','unlike','modal','hide','unhide','deldisc','undeleteall','postdata','preview','replydisc','editdisc','cmd','symb','onlyunread','allposts','onlyunmark','previous','markread','markonread','markondisp','toggoff','toggon','modifydisp','changes','navtime','navmaps','navurl','sortposts','applysort','rolefilter','statusfilter','sectionpick','groupick','posterlist','userpick','attach','origpage','currnewattach','deloldattach','keepold','allversions','export','sendmessageonly','group','ref']);           ['like','unlike','modal','hide','unhide','deldisc','undeleteall','postdata','preview','replydisc','editdisc','cmd','symb','onlyunread','allposts','onlyunmark','previous','markread','markonread','markondisp','toggoff','toggon','modifydisp','changes','navtime','navmaps','navurl','sortposts','applysort','rolefilter','statusfilter','sectionpick','groupick','posterlist','userpick','attach','origpage','currnewattach','deloldattach','keepold','allversions','export','sendmessageonly','group','ref']);
   my $group = $env{'form.group'};    my $group = $env{'form.group'};
     my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
     my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
   
   my %attachmax = (    my %attachmax = (
                     text => &mt('(128 KB max size)'),                      text => &mt('(128 KB max size)'),
                     num  => 131072,                      num  => 131072,
                   );                    );
   if ($env{'form.editdisc'}) {    if ($env{'form.editdisc'}) {
       if (!(&editing_allowed($env{'form.editdisc'},$env{'form.group'}))) {        if (!(&editing_allowed($env{'form.editdisc'},$group))) {
           my $symb=(split(/\:\:\:/,$env{'form.editdisc'}))[0];            my $symb=(split(/\:\:\:/,$env{'form.editdisc'}))[0];
           my ($map,$id,$url)=&Apache::lonnet::decode_symb($symb);            my ($map,$id,$url)=&Apache::lonnet::decode_symb($symb);
           my $feedurl=&Apache::lonnet::clutter($url);            my $feedurl=&Apache::lonnet::clutter($url);
Line 3841  sub handler { Line 3878  sub handler {
   
       $r->print(&Apache::loncommon::start_page('Discussion Post Versions',undef,\%parms));        $r->print(&Apache::loncommon::start_page('Discussion Post Versions',undef,\%parms));
   
       my $crs='/'.$env{'request.course.id'};  
       if ($env{'request.course.sec'}) {  
           $crs.='_'.$env{'request.course.sec'};  
       }  
       $crs=~s|_|/|g;  
       my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};  
       my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};  
       my ($symb,$idx)=split(/\:\:\:/,$env{'form.allversions'});        my ($symb,$idx)=split(/\:\:\:/,$env{'form.allversions'});
       ($symb)=&get_feedurl_and_clean_symb($symb);        ($symb, my $feedurl)=&get_feedurl_and_clean_symb($symb);
       my $ressymb = &wrap_symb($symb);        my $ressymb = &wrap_symb($symb);
       my $group = $env{'form.group'};  
       my $seeid;        my $seeid;
       if (($group ne '') && (($ressymb =~ m|^bulletin___\d+___adm/wrapper/adm/\Q$cdom\E/\Q$cnum\E/\d+/bulletinboard$|))) {        if (&Apache::lonnet::allowed('rin',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))) {
           if (&check_group_priv($group,'dgp') eq 'ok') {            $seeid = 1;
               $seeid = 1;  
           }  
       } else {  
           $seeid = &Apache::lonnet::allowed('rin',$crs);  
       }        }
         my $seehidden = &can_see_hidden('',$ressymb,$feedurl,$group,$cdom,$cnum);
       if ($idx > 0) {        if ($idx > 0) {
           my %messages = ();            my %messages = ();
           my %subjects = ();            my %subjects = ();
Line 3868  sub handler { Line 3894  sub handler {
           my %imsfiles = ();            my %imsfiles = ();
           my ($screenname,$plainname,$showaboutme);            my ($screenname,$plainname,$showaboutme);
           my %contrib=&Apache::lonnet::restore($symb,$env{'request.course.id'},            my %contrib=&Apache::lonnet::restore($symb,$env{'request.course.id'},
                            $env{'course.'.$env{'request.course.id'}.'.domain'},                                                 $cdom,$cnum);
                            $env{'course.'.$env{'request.course.id'}.'.num'});            $r->print(&get_post_contents(\%contrib,$idx,$seeid,$seehidden,'allversions',\%messages,\%subjects,\%allattachments,\%attachmsgs,\%imsfiles,\$screenname,\$plainname,\$showaboutme));
           $r->print(&get_post_contents(\%contrib,$idx,$seeid,'allversions',\%messages,\%subjects,\%allattachments,\%attachmsgs,\%imsfiles,\$screenname,\$plainname,\$showaboutme));  
       }        }
       $r->print(&Apache::loncommon::end_page());        $r->print(&Apache::loncommon::end_page());
       return OK;        return OK;
Line 4008  ENDREDIR Line 4033  ENDREDIR
       my $entry=$env{'form.hide'}?$env{'form.hide'}:$env{'form.unhide'};        my $entry=$env{'form.hide'}?$env{'form.hide'}:$env{'form.unhide'};
       my ($symb,$idx)=split(/\:\:\:/,$entry);        my ($symb,$idx)=split(/\:\:\:/,$entry);
       ($symb,my $feedurl)=&get_feedurl_and_clean_symb($symb);        ($symb,my $feedurl)=&get_feedurl_and_clean_symb($symb);
         my $ressymb = &wrap($symb);
   
       my $crs='/'.$env{'request.course.id'};        my $seehidden = &can_see_hidden('',$ressymb,$feedurl,$group,$cdom,$cnum);
       if ($env{'request.course.sec'}) {        unless (($seehidden) || (&editing_allowed($env{'form.hide'},$group))) {
           $crs.='_'.$env{'request.course.sec'};            &redirect_back($r,$feedurl,&mt('Hiding not permitted').'<br />',
       }                           '0','0','','',$env{'form.previous'},'','','','',
       $crs=~s/\_/\//g;                           undef,undef,$group,);
       my $seeid=&Apache::lonnet::allowed('rin',$crs);  
   
       if ($env{'form.hide'} && !$seeid && !(&editing_allowed($env{'form.hide'},$env{'form.group'}))) {  
           &redirect_back($r,$feedurl,&mt('Deletion not permitted').'<br />',                 '0','0','','',$env{'form.previous'},'','','','',  
                  undef,undef,$group,);  
           return OK;            return OK;
       }        }
   
       my %contrib=&Apache::lonnet::restore($symb,$env{'request.course.id'},        my %contrib=&Apache::lonnet::restore($symb,$env{'request.course.id'},
                           $env{'course.'.$env{'request.course.id'}.'.domain'},                                             $cdom,$cnum);
           $env{'course.'.$env{'request.course.id'}.'.num'});  
   
       my $currenthidden=$contrib{'hidden'};        my $currenthidden=$contrib{'hidden'};
       my $currentstudenthidden=$contrib{'studenthidden'};        my $currentstudenthidden=$contrib{'studenthidden'};
   
       if ($env{'form.hide'}) {        if ($env{'form.hide'}) {
   $currenthidden.='.'.$idx.'.';    $currenthidden.='.'.$idx.'.';
   unless ($seeid) {    unless ($seehidden) {
       $currentstudenthidden.='.'.$idx.'.';        $currentstudenthidden.='.'.$idx.'.';
   }    }
       } else {        } else {
   $currenthidden=~s/\.$idx\.//g;    $currenthidden=~s/\.$idx\.//g;
       }        }
       my %newhash=('hidden' => $currenthidden);        my %newhash=('hidden' => $currenthidden);
       if ( ($env{'form.hide'}) && (!$seeid) ) {        if ( ($env{'form.hide'}) && (!$seehidden) ) {
   $newhash{'studenthidden'} = $currentstudenthidden;    $newhash{'studenthidden'} = $currentstudenthidden;
       }        }
       if ($env{'form.hide'}) {        if ($env{'form.hide'}) {
Line 4047  ENDREDIR Line 4067  ENDREDIR
           ($changelast,$newlast) = &get_discussion_info($idx,%contrib);            ($changelast,$newlast) = &get_discussion_info($idx,%contrib);
           if ($changelast) {            if ($changelast) {
               &Apache::lonnet::put('discussiontimes',{$symb => $newlast},                &Apache::lonnet::put('discussiontimes',{$symb => $newlast},
                      $env{'course.'.$env{'request.course.id'}.'.domain'},                                     $cdom,$cnum);
                      $env{'course.'.$env{'request.course.id'}.'.num'});  
           }            }
       }        }
       &Apache::lonnet::store(\%newhash,$symb,$env{'request.course.id'},        &Apache::lonnet::store(\%newhash,$symb,$env{'request.course.id'},
                            $env{'course.'.$env{'request.course.id'}.'.domain'},                              $cdom,$cnum);
    $env{'course.'.$env{'request.course.id'}.'.num'});  
   
       &redirect_back($r,$feedurl,&mt('Changed discussion status').'<br />',        &redirect_back($r,$feedurl,&mt('Changed discussion status').'<br />',
      '0','0','','',$env{'form.previous'},undef,undef,undef,       '0','0','','',$env{'form.previous'},undef,undef,undef,
Line 4064  ENDREDIR Line 4082  ENDREDIR
       my $entry=$env{'form.like'}?$env{'form.like'}:$env{'form.unlike'};        my $entry=$env{'form.like'}?$env{'form.like'}:$env{'form.unlike'};
       my ($symb,$idx)=split(/\:\:\:/,$entry);        my ($symb,$idx)=split(/\:\:\:/,$entry);
       ($symb,my $feedurl)=&get_feedurl_and_clean_symb($symb);        ($symb,my $feedurl)=&get_feedurl_and_clean_symb($symb);
       my $status='OPEN';  
       if ($Apache::lonhomework::parsing_a_problem ||  
           $Apache::lonhomework::parsing_a_task) {  
           $status=$Apache::inputtags::status[-1];  
       }  
       my $result;        my $result;
       my $realsymb = &get_realsymb($symb);        if ($idx > 0) {
       if (&discussion_vote_available($status,$realsymb)) {            my $realsymb = &get_realsymb($symb);
             my $status='OPEN';
             if ($Apache::lonhomework::parsing_a_problem ||
                 $Apache::lonhomework::parsing_a_task) {
                 $status=$Apache::inputtags::status[-1];
             }
             if (&discussion_vote_available($status,$realsymb)) {
                 my %contrib=&Apache::lonnet::restore($symb,$env{'request.course.id'},
                                                      $cdom,$cnum);
                 if (($contrib{$idx.':sendername'} eq $env{'user.name'}) && 
                     ($contrib{$idx.':senderdomain'} eq $env{'user.domain'})) {
                     $result = &mt("Vote not registered. No voting for your own posts.");
                 } else {
   
 #  #
 # Likes and unlikes are in db-file "disclikes" of the course  # Likes and unlikes are in db-file "disclikes" of the course
 # The prefix is the $symb to identify the resource discussion,  # The prefix is the $symb to identify the resource discussion,
 # and the $idx to identify the entry  # and the $idx to identify the entry
 #  #
           my $prefix=$symb.':'.$idx.':';                    my $prefix=$symb.':'.$idx.':';
           my %contrib=&Apache::lonnet::dump('disclikes',                    my %likes=&Apache::lonnet::dump('disclikes',$cdom,$cnum,
                                         $env{'course.'.$env{'request.course.id'}.'.domain'},                                                    '^'.$prefix);
                                         $env{'course.'.$env{'request.course.id'}.'.num'},  
                                         '^'.$prefix);  
   
 # Get current like or unlike status for the $idx for this user.  # Get current like or unlike status for the $idx for this user.
           my $thisuser=$env{'user.name'}.':'.$env{'user.domain'};                    my $thisuser=$env{'user.name'}.':'.$env{'user.domain'};
           my ($userlikes,$userunlikes);                    my ($userlikes,$userunlikes);
           if (ref($contrib{$prefix.'likers'}) eq 'HASH') {                    if (ref($likes{$prefix.'likers'}) eq 'HASH') {
               if (exists($contrib{$prefix.'likers'}{$thisuser})) {                        if (exists($likes{$prefix.'likers'}{$thisuser})) {
                   $userlikes = 1;                            $userlikes = 1;
               }                        }
           }                    }
           if (ref($contrib{$prefix.'unlikers'}) eq 'HASH') {                    if (ref($likes{$prefix.'unlikers'}) eq 'HASH') {
               if (exists($contrib{$prefix.'unlikers'}{$thisuser})) {                        if (exists($likes{$prefix.'unlikers'}{$thisuser})) {
                   $userunlikes = 1;                            $userunlikes = 1;
               }                        }
           }                    }
 # Get the current "likes" count  # Get the current "likes" count
           my $likes=$contrib{$prefix.'likes'};                    my $likescount=$likes{$prefix.'likes'};
 # Find out if they already voted  # Find out if they already voted
 # Users cannot like a post twice, or unlike it twice.  # Users cannot like a post twice, or unlike it twice.
 # They can change their mind, though.  # They can change their mind, though.
           my $alreadyflag=0;                    my $alreadyflag=0;
           my $thisuser=$env{'user.name'}.':'.$env{'user.domain'};                    if ($env{'form.like'}) {
           if ($env{'form.like'}) {                        if ($userlikes) {
               if ($userlikes) {                            $alreadyflag=1;
                   $alreadyflag=1;                        } elsif ($userunlikes) {
               } elsif ($userunlikes) {                            delete($likes{$prefix.'unlikers'}{$thisuser});
                   delete($contrib{$prefix.'unlikers'}{$thisuser});                            $likescount++;
                   $likes++;                        } else {
               } else {                            if (ref($likes{$prefix.'likers'}) eq 'HASH') {
                   if (ref($contrib{$prefix.'likers'}) eq 'HASH') {                                $likes{$prefix.'likers'}{$thisuser} = 1;
                       $contrib{$prefix.'likers'}{$thisuser} = 1;                            } else {
                   } else {                                $likes{$prefix.'likers'} = {$thisuser => 1};
                       $contrib{$prefix.'likers'} = {$thisuser => 1};                            }
                   }                            $likescount++;
                   $likes++;                        }
               }  
           } else {  
               if ($userunlikes) {  
                   $alreadyflag=1;  
               } elsif ($userlikes) {  
                   delete($contrib{$prefix.'likers'}{$thisuser});  
                   $likes--;  
               } else {  
                   if (ref($contrib{$prefix.'unlikers'}) eq 'HASH') {  
                       $contrib{$prefix.'unlikers'}{$thisuser} = 1;  
                   } else {                    } else {
                       $contrib{$prefix.'unlikers'} = {$thisuser => 1};                        if ($userunlikes) {
                             $alreadyflag=1;
                         } elsif ($userlikes) {
                             delete($likes{$prefix.'likers'}{$thisuser});
                             $likescount--;
                         } else {
                             if (ref($likes{$prefix.'unlikers'}) eq 'HASH') {
                                 $likes{$prefix.'unlikers'}{$thisuser} = 1;
                             } else {
                                 $likes{$prefix.'unlikers'} = {$thisuser => 1};
                             }
                             $likescount--;
                         }
                   }                    }
                   $likes--;  
               }  
           }  
 # $alreadyflag would be 1 if they tried to double-like or double-unlike  # $alreadyflag would be 1 if they tried to double-like or double-unlike
           unless ($alreadyflag) {                    if ($alreadyflag) {
               my %newhash=($prefix.'likes'    => $likes,                        if ($env{'form.like'}) {
                            $prefix.'likers'   => $contrib{$prefix.'likers'},                            $result= &mt("'Like' already registered");
                            $prefix.'unlikers' => $contrib{$prefix.'unlikers'});                        } else {
                             $result= &mt("'Unlike' already registered");
                         }
                     } else {
                         my %newhash=($prefix.'likes'    => $likescount,
                                      $prefix.'likers'   => $likes{$prefix.'likers'},
                                      $prefix.'unlikers' => $likes{$prefix.'unlikers'});
 # Store data in db-file "disclikes"  # Store data in db-file "disclikes"
               if (&Apache::lonnet::put('disclikes',                        if (&Apache::lonnet::put('disclikes',\%newhash,$cdom,$cnum) eq 'ok') {
                                        \%newhash,  
                                        $env{'course.'.$env{'request.course.id'}.'.domain'},  
                                        $env{'course.'.$env{'request.course.id'}.'.num'}) eq 'ok') {  
 # Also store with the person who posted the liked/unliked entry  # Also store with the person who posted the liked/unliked entry
                   if ($env{'form.like'}) {                            if ($env{'form.like'}) {
                       &storediscussionlikes(1,$contrib{$idx.':sendername'},$contrib{$idx.':senderdomain'});                                &storediscussionlikes(1,$contrib{$idx.':sendername'},$contrib{$idx.':senderdomain'});
                       $result=&mt("Registered 'Like'");                                $result=&mt("Registered 'Like'");
                   } else {                            } else {
                       &storediscussionlikes(-1,$contrib{$idx.':sendername'},$contrib{$idx.':senderdomain'});                               &storediscussionlikes(-1,$contrib{$idx.':sendername'},$contrib{$idx.':senderdomain'});
                       $result=&mt("Registered 'Unlike'");                               $result=&mt("Registered 'Unlike'");
                   }                            }
               } else {                        } else {
 # Oops, something went wrong  # Oops, something went wrong
                   $result=&mt("Failed to register vote");                            $result=&mt("Failed to register vote");
                         }
                     }
               }                }
             } else {
                 $result=&mt('Voting unavailable for this discussion');
           }            }
       } else {        } else {
           $result=&mt('Voting unavailable for this discussion');            $result=&mt('Invalid post number'); 
       }        }
       &redirect_back($r,$feedurl,$result.'<br />',        &redirect_back($r,$feedurl,$result.'<br />',
                      '0','0','','',$env{'form.previous'},undef,undef,undef,                       '0','0','','',$env{'form.previous'},undef,undef,undef,
Line 4179  ENDREDIR Line 4209  ENDREDIR
 # --------------------------------------------------------------- Hide for good  # --------------------------------------------------------------- Hide for good
       my ($symb,$idx)=split(/\:\:\:/,$env{'form.deldisc'});        my ($symb,$idx)=split(/\:\:\:/,$env{'form.deldisc'});
       ($symb,my $feedurl)=&get_feedurl_and_clean_symb($symb);        ($symb,my $feedurl)=&get_feedurl_and_clean_symb($symb);
         my $ressymb=&wrap_symb($symb);
   
         unless (&can_see_hidden('',$ressymb,$feedurl,$group,$cdom,$cnum)) {
             &redirect_back($r,$feedurl,&mt('Deletion not permitted').'<br />',
                            '0','0','','',$env{'form.previous'},'','','','',
                            undef,undef,$group);
             return OK;
         }
       my %contrib=&Apache::lonnet::restore($symb,$env{'request.course.id'},        my %contrib=&Apache::lonnet::restore($symb,$env{'request.course.id'},
                           $env{'course.'.$env{'request.course.id'}.'.domain'},                                             $cdom,$cnum);
           $env{'course.'.$env{'request.course.id'}.'.num'});  
       my ($changelast,$newlast) = &get_discussion_info($idx,%contrib);        my ($changelast,$newlast) = &get_discussion_info($idx,%contrib);
       if ($changelast) {        if ($changelast) {
           &Apache::lonnet::put('discussiontimes',{$symb => $newlast},            &Apache::lonnet::put('discussiontimes',{$symb => $newlast},
                    $env{'course.'.$env{'request.course.id'}.'.domain'},                   $env{'course.'.$env{'request.course.id'}.'.num'});                                 $cdom,$cnum);
       }        }
       my %newhash=('deleted' => $contrib{'deleted'}.".$idx.");        my %newhash=('deleted' => $contrib{'deleted'}.".$idx.");
       &Apache::lonnet::store(\%newhash,$symb,$env{'request.course.id'},        &Apache::lonnet::store(\%newhash,$symb,$env{'request.course.id'},
    $env{'course.'.$env{'request.course.id'}.'.domain'},                               $cdom,$cnum);
    $env{'course.'.$env{'request.course.id'}.'.num'});  
       &redirect_back($r,$feedurl,&mt('Changed discussion status').'<br />',        &redirect_back($r,$feedurl,&mt('Changed discussion status').'<br />',
      '0','0','','',$env{'form.previous'},undef,undef,undef,       '0','0','','',$env{'form.previous'},undef,undef,undef,
                      undef,undef,undef,$group);                       undef,undef,undef,$group);
Line 4220  ENDREDIR Line 4256  ENDREDIR
       my $idx = $env{'form.idx'};        my $idx = $env{'form.idx'};
       if ($idx) {        if ($idx) {
           my %contrib=&Apache::lonnet::restore($symb,$env{'request.course.id'},            my %contrib=&Apache::lonnet::restore($symb,$env{'request.course.id'},
                          $env{'course.'.$env{'request.course.id'}.'.domain'},                                                 $cdom,$cnum);
                          $env{'course.'.$env{'request.course.id'}.'.num'});  
           $attachmenturls = $contrib{$idx.':attachmenturl'};            $attachmenturls = $contrib{$idx.':attachmenturl'};
       }        }
       &modify_attachments($r,\@currnewattach,\@currdelold,$symb,$idx,        &modify_attachments($r,\@currnewattach,\@currdelold,$symb,$idx,
Line 4238  ENDREDIR Line 4273  ENDREDIR
           $mode='problem';            $mode='problem';
           $status=$Apache::inputtags::status[-1];            $status=$Apache::inputtags::status[-1];
       }        }
          
       my $discussion = &list_discussion($mode,$status,$symb);         my $discussion = &list_discussion($mode,$status,$symb); 
       my $start_page =         my $start_page = 
   &Apache::loncommon::start_page('Resource Feedback and Discussion');    &Apache::loncommon::start_page('Resource Feedback and Discussion');
Line 4250  ENDREDIR Line 4286  ENDREDIR
       &Apache::loncommon::content_type($r,'text/html');        &Apache::loncommon::content_type($r,'text/html');
       $r->send_http_header;        $r->send_http_header;
       my ($symb,$feedurl) = &get_feedurl_and_clean_symb($env{'form.undeleteall'});        my ($symb,$feedurl) = &get_feedurl_and_clean_symb($env{'form.undeleteall'});
         my $ressymb=&wrap_symb($symb);
       $r->print(&Apache::loncommon::start_page('Undelete all deleted discussion entries'));        $r->print(&Apache::loncommon::start_page('Undelete all deleted discussion entries'));
       if (&Apache::lonnet::allowed('rin',$env{'request.course.id'})) {        if (&can_see_hidden('',$ressymb,$feedurl,$group,$cdom,$cnum)) {
            if (&Apache::lonnet::store({'deleted' => ''},$symb,$env{'request.course.id'},             if (&Apache::lonnet::store({'deleted' => ''},$symb,$env{'request.course.id'},
                      $env{'course.'.$env{'request.course.id'}.'.domain'},                                        $cdom,$cnum) eq 'ok') {
                      $env{'course.'.$env{'request.course.id'}.'.num'}) eq 'ok') {  
                $r->print(&Apache::lonhtmlcommon::confirm_success(&mt("Undeleted all entries")));                 $r->print(&Apache::lonhtmlcommon::confirm_success(&mt("Undeleted all entries")));
            } else {             } else {
                $r->print(&Apache::lonhtmlcommon::confirm_success(&mt("Failed to undelete entries"),1));                 $r->print(&Apache::lonhtmlcommon::confirm_success(&mt("Failed to undelete entries"),1));
Line 4458  sub wrap_symb { Line 4494  sub wrap_symb {
     }      }
     return $ressymb;      return $ressymb;
 }  }
   
 sub dewrapper {  sub dewrapper {
     my ($feedurl)=@_;      my ($feedurl)=@_;
     if ($$feedurl=~m|^/adm/wrapper/adm/.*/bulletinboard$|) {      if ($$feedurl=~m|^/adm/wrapper/adm/.*/bulletinboard$|) {

Removed from v.1.341  
changed lines
  Added in v.1.347


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