Diff for /loncom/interface/loncoursegroups.pm between versions 1.9 and 1.130

version 1.9, 2006/03/19 22:31:41 version 1.130, 2017/03/19 17:56:04
Line 1 Line 1
   # The LearningOnline Network with CAPA
   #
   # $Id$
 #  #
 # Copyright Michigan State University Board of Trustees  # Copyright Michigan State University Board of Trustees
 #  #
Line 26  package Apache::loncoursegroups; Line 29  package Apache::loncoursegroups;
   
 use strict;  use strict;
 use Apache::lonnet;  use Apache::lonnet;
 use Apache::loncommon;  use Apache::loncommon();
 use Apache::lonhtmlcommon;  use Apache::lonhtmlcommon();
   use Apache::lonhtmlgateway;
 use Apache::lonlocal;  use Apache::lonlocal;
 use Apache::lonnavmaps;  use Apache::lonnavmaps();
   use Apache::longroup();
   use Apache::portfolio();
 use Apache::Constants qw(:common :http);  use Apache::Constants qw(:common :http);
   use HTML::Entities;
   use LONCAPA::map();
   use lib '/home/httpd/lib/perl/';
   use LONCAPA;
   
 sub handler {  sub handler {
     my ($r) = @_;      my ($r) = @_;
   
     &Apache::loncommon::content_type($r,'text/html');      &Apache::loncommon::content_type($r,'text/html');
     $r->send_http_header;      $r->send_http_header;
                                                                                   
     if ($r->header_only) {      if ($r->header_only) {
         return OK;          return OK;
     }      }
Line 46  sub handler { Line 56  sub handler {
     if (! ($env{'request.course.fn'})) {      if (! ($env{'request.course.fn'})) {
         # Not in a course          # Not in a course
         $env{'user.error.msg'}=          $env{'user.error.msg'}=
      "/adm/coursegroups:mdg:0:0:Cannot edit or view course groups";       "/adm/coursegroups:mdg:0:0:Cannot edit or view course/community groups";
         return HTTP_NOT_ACCEPTABLE;          return HTTP_NOT_ACCEPTABLE;
     }      }
   
     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},      &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                         ['action','refpage','state','groupname','branch']);                          ['action','refpage','state','groupname','branch']);
     my $function = &Apache::loncommon::get_users_function();  
     my $tabcol = &Apache::loncommon::designparm($function.'.tabbg');  
     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 $view_permission =      my $view_permission =
           &Apache::lonnet::allowed('vcg',$env{'request.course.id'});            &Apache::lonnet::allowed('vcg',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''));
     my $manage_permission =      my $manage_permission =
           &Apache::lonnet::allowed('mdg',$env{'request.course.id'});            &Apache::lonnet::allowed('mdg',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''));
     &Apache::lonhtmlcommon::clear_breadcrumbs();      &Apache::lonhtmlcommon::clear_breadcrumbs();
   
       my $gpterm = &Apache::loncommon::group_term();
       my $ucgpterm = $gpterm;
       $ucgpterm =~ s/^(\w)/uc($1)/e;
       my $crstype = &Apache::loncommon::course_type();
   
     my %functions = (      my %functions = (
                       email => 'E-mail',                        email => 'Send Messages', 
                       discussion => 'Discussion boards',                        discussion => 'Discussion Boards',
                       chat => 'Chat',                        chat => 'Chat Room',
                       files => 'File repository',                        files => 'Group Portfolio',
                       roster => 'Membership roster',                        roster => 'Membership Roster',
                       homepage => 'Group home page',                        homepage => $ucgpterm.' home page',
                     );                      );
   
     my %idx = ();      my %idx = ();
Line 77  sub handler { Line 90  sub handler {
     $idx{fullname} = &Apache::loncoursedata::CL_FULLNAME();      $idx{fullname} = &Apache::loncoursedata::CL_FULLNAME();
     $idx{udom} = &Apache::loncoursedata::CL_SDOM();      $idx{udom} = &Apache::loncoursedata::CL_SDOM();
     $idx{uname} = &Apache::loncoursedata::CL_SNAME();      $idx{uname} = &Apache::loncoursedata::CL_SNAME();
       $idx{section} = &Apache::loncoursedata::CL_SECTION();
     my $rowColor1 = "#dddddd";  
     my $rowColor2 = "#eeeeee";  
   
     my $action = $env{'form.action'};      my $action = $env{'form.action'};
     if ($action eq 'create' || $action eq 'modify' || $action eq 'view') {       my $state = $env{'form.state'};
       if ((!defined($action)) || ($action eq 'view') || ($action eq 'modify') || ($action eq 'delete') || ($action eq 'reenable')) {
           if (!defined($state)) {
               $state = 'view';
           }
       }
       if ($action eq 'create' || $action eq 'modify' || $action eq 'view' || 
           $action eq 'delete' || $action eq 'reenable') { 
         if ($view_permission || $manage_permission) {          if ($view_permission || $manage_permission) {
             &group_administration($r,$action,$cdom,$cnum,$function,$tabcol,              if ($state eq 'view') {
                                   \%functions,\%idx,$view_permission,                  &print_main_menu($r,$cdom,$cnum,\%functions,\%idx,
                                   $manage_permission,$rowColor1,$rowColor2);                                   $view_permission,$manage_permission,
                                    $action,$state,$gpterm,$ucgpterm,$crstype);
               } else {
                   &group_administration($r,$action,$state,$cdom,$cnum,
                                         \%functions,\%idx,$view_permission,
                                         $manage_permission,$gpterm,$ucgpterm,
           $crstype);
               }
         } else {          } else {
             $r->print(&mt('You do not have group administration '.              $r->print('<div class="LC_warning">'
                           'privileges in this course'));                       .&mt('You do not have '.$gpterm.' administration '
                            .'privileges in this '.lc($crstype).'.')
                        .'</div>');
         }          }
     } else {      } else {
         &print_main_menu($r,$cdom,$cnum,$function,$tabcol,\%functions,\%idx,          &print_main_menu($r,$cdom,$cnum,\%functions,\%idx,$view_permission,
                          $view_permission,$manage_permission,$action,   $manage_permission,$action,$state,$gpterm,$ucgpterm,
                          $rowColor1,$rowColor2);   $crstype);
     }      }
     return OK;      return OK;
 }  }
   
 sub print_main_menu {  sub print_main_menu {
     my ($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,$view_permission,      my ($r,$cdom,$cnum,$functions,$idx,$view_permission,$manage_permission,
         $manage_permission,$action,$rowColor1,$rowColor2) = @_;   $action,$state,$gpterm,$ucgpterm,$crstype) = @_;
     $r->print(&header('Course Groups',undef,undef,undef,undef,$function));      my $jscript = qq|
   function changeSort(caller) {
       document.$state.sortby.value = caller;
       document.$state.submit();
   }
   function openGroupRoster(group,status) {
       var url = '/adm/grouproster?';
       url += 'group='+group+'&amp;status='+status+'&amp;ref=popup';
       var title = 'Group_Membership';
       var options = 'scrollbars=1,resizable=1,menubar=0';
       options += ',width=700,height=600';
       rosterbrowser = open(url,title,options,'1');
       rosterbrowser.focus();
   }\n|;
       $r->print(&header('My Space',$jscript,$action,$state));
       if ($env{'form.refpage'} eq 'cusr') {
           &Apache::lonhtmlcommon::add_breadcrumb
               ({href=>"/adm/createuser",
                 text=>"User Management"});
       }
     &Apache::lonhtmlcommon::add_breadcrumb      &Apache::lonhtmlcommon::add_breadcrumb
         ({href=>"/adm/coursegroups",          ({href=>"/adm/coursegroups",
           text=>"Course Groups",});            text=>"Groups"});
     $r->print(&Apache::lonhtmlcommon::breadcrumbs      my $helpitem;
               (undef,'Course Groups'));      if ($manage_permission) {
     &display_groups($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,          $helpitem = 'Creating_Groups';
                     $view_permission,$manage_permission,$action,$rowColor1,      }
                     $rowColor2);      $r->print(&Apache::lonhtmlcommon::breadcrumbs('Groups',$helpitem));
       &display_groups($r,$cdom,$cnum,$functions,$idx,$view_permission,
       $manage_permission,$action,$state,$gpterm,$ucgpterm,
       $crstype);
     $r->print(&footer());      $r->print(&footer());
     return;      return;
 }  }
   
 sub display_groups {  sub display_groups {
     my ($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,$view_permission,      my ($r,$cdom,$cnum,$functions,$idx,$view_permission,
         $manage_permission,$action,$rowColor1,$rowColor2) = @_;          $manage_permission,$action,$state,$gpterm,$ucgpterm,$crstype) = @_;
     my %curr_groups = ();      my %curr_groups = ();
     my %grp_info = ();      my %grp_info = ();
   
     my %actionlinks = (      my %actionlinks = (
       modify => '<a href="/adm/coursegroups?action=modify&state=pick_task&refpage='.        modify   => '/adm/coursegroups?action=modify&refpage='.
                 $env{'form.refpage'}.'&groupname=',                    $env{'form.refpage'}.'&state=pick_task&groupname=',
       view => '<a href="/adm/'.$cdom.'/'.$cnum.'/',        view     => '',
       delete => '<a href="/adm/coursegroups?action=delete&refpage='.        delete   => '/adm/coursegroups?action=delete&refpage='.
                 $env{'form.refpage'}.'&groupname=',                    $env{'form.refpage'}.'&state=verify&groupname=',
         reenable => '/adm/coursegroups?action=reenable&refpage='.
                     $env{'form.refpage'}.'&state=verify&groupname=',
     );      );
     my %lt = &Apache::lonlocal::texthash(       my %lt = &Apache::lonlocal::texthash( 
                           modify => 'Modify',                            modify => 'Modify',
                           view   => 'View',                            view   => 'View',
                           delete => 'Delete',                            delete => 'Delete',
                             reenable => 'Re-enable',
                           act    => 'Action',                            act    => 'Action',
                           gname  => 'Group Name',                            gname  => 'Group Name',
                           desc   => 'Description',                            desc   => 'Group Title',
                           crea   => 'Creator',                            crea   => 'Creator',
                           crtd   => 'Created',                            crtd   => 'Created',
                           last   => 'Last Modified',                            last   => 'Last Modified',
                           func   => 'Functionality',                            func   => 'Collaborative Tools',
                           quot   => 'Quota (Mb)',                            quot   => 'Quota (MB)',
                           memb   => 'Members',                            memb   => 'Members',
                           file   => 'Files',                            file   => 'Files',
                           dibd   => 'Discussion Boards',                            dibd   => 'Discussion Boards',
                           dius   => 'Disk Use',                            dius   => 'Disk Use (%)',
                           nogr   => 'No groups exist.',                            nogr   => 'No groups exist.',
                           crng   => 'Create a new group',                            crng   => 'Create a new group',
                             redg   => 'Re-enable a deleted group',
                           alth   => 'Although your current role has privileges'.                            alth   => 'Although your current role has privileges'.
                                     ' to view any existing groups in this course,'.                                      ' to view any existing groups in this '.
                                     ' you do not have privileges to create new'.                                      lc($crstype).', you do not have privileges '.
                                     ' groups.',                                      'to create new groups.',
                      );                       );
     if ($view_permission) {      if ($view_permission) {
         if (!defined($action)) {          if (!defined($action)) {
             $action = 'view';              $action = 'view';
         }          }
         my %curr_groups;          my ($status,$reenable_link);
         if (&Apache::loncommon::coursegroups(\%curr_groups,$cdom,$cnum)) {          if ($action eq 'reenable') {
               $status = 'deleted_groups';
           } else {
               if ($manage_permission) {
                   my %deleted_groups = 
                       &Apache::longroup::coursegroups($cdom,$cnum,undef,'deleted_groups');
                   if (keys(%deleted_groups) > 0) {
                       $reenable_link = '&nbsp;&nbsp;&nbsp;&nbsp;<a href="/adm/coursegroups?action=reenable&amp;refpage='.$env{'form.refpage'}.'">'.$lt{'redg'}.'</a>';
                   }
               }
           }
           my %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum,undef,
                                                             $status);
   
           if (%curr_groups) {
               my $navmap=Apache::lonnavmaps::navmap->new();
               if (!defined($navmap)) {
                   $r->print('<div class="LC_error">'.
                             &mt('An error occurred retrieving information about resources in the course.').'<br />'.
                             &mt('It is recommended that you [_1]re-initialize the course[_2] and then return to this page.','<a href="/adm/roles?selectrole=1&amp;newrole='.$env{'request.role'}.'&amp;orgurl=%2fadm%2fcoursegroups">','</a>').
                             '</div>');
                   return;
               }
               if ($manage_permission) {
                   if ($action ne 'reenable') {
                       $r->print('<br /><a href="/adm/coursegroups?action=create&amp;refpage='.$env{'form.refpage'}.'">'.$lt{'crng'}.'</a>');
                   }
                   if ($reenable_link) {
                       $r->print($reenable_link);
                   }
               }
             $r->print('<br /><br />');              $r->print('<br /><br />');
             $r->print(&Apache::lonhtmlcommon::start_pick_box());      $r->print(&Apache::loncommon::start_data_table().
         &Apache::loncommon::start_data_table_header_row());
         
             $r->print(<<"END");              $r->print(<<"END");
       <table border="0" cellpadding="4" cellspacing="1">          <th>$lt{'act'}</th>
        <tr bgcolor="$tabcol" align="center">          <th><a href="javascript:changeSort('groupname')">$lt{'gname'}</a></th>
         <td><b>$lt{'act'}</b></td>          <th><a href="javascript:changeSort('description')">$lt{'desc'}</a></th>
         <td><b><a href="javascript:changeSort('groupname')">$lt{'gname'}</a></b></td>          <th><a href="javascript:changeSort('creator')">$lt{'crea'}</a></th>
         <td><b><a href="javascript:changeSort('description')">$lt{'desc'}</a></b></td>          <th><a href="javascript:changeSort('creation')">$lt{'crtd'}</a></th>
         <td><b><a href="javascript:changeSort('creator')">$lt{'crea'}</a></b>          <th><a href="javascript:changeSort('modified')">$lt{'last'}</a></th>
         </td>          <th>$lt{'func'}</th>
         <td><b><a href="javascript:changeSort('creation')">$lt{'crtd'}</a></b>          <th><a href="javascript:changeSort('quota')">$lt{'quot'}</a></th>
         </td>          <th><a href="javascript:changeSort('totalmembers')">$lt{'memb'}</a></th>
         <td><b><a href="javascript:changeSort('modified')">$lt{'last'}</a></b>          <th><a href="javascript:changeSort('totalfiles')">$lt{'file'}</a></th>
         </td>          <th><a href="javascript:changeSort('boards')">$lt{'dibd'}</a></th>
         <td><b>$lt{'func'}</b>          <th><a href="javascript:changeSort('diskuse')">$lt{'dius'}</a></th>
         </td>  
         <td><b><a href="javascript:changeSort('quota')">$lt{'quot'}</a></b></td>  
         <td><b><a href="javascript:changeSort('totalmembers)">$lt{'memb'}</a></b></td>  
         <td><b><a href="javascript:changeSort('totalfiles')">$lt{'file'}</a></b></td>  
         <td><b><a href="javascript:changeSort('boards')">$lt{'dibd'}</a></b></td>  
         <td><b><a href="javascript:changeSort('diskuse')">$lt{'dius'}</a></b></td>  
        </tr>  
 END  END
       $r->print(&Apache::loncommon::end_data_table_header_row());
             my %Sortby = ();              my %Sortby = ();
             foreach my $group (sort(keys(%curr_groups))) {              foreach my $group (sort(keys(%curr_groups))) {
                 %{$grp_info{$group}} =                   %{$grp_info{$group}} = 
                                   &Apache::loncommon::get_group_settings(                                    &Apache::longroup::get_group_settings(
                                                          $curr_groups{$group});                                                           $curr_groups{$group});
                 my $members_result = &group_members($cdom,$cnum,$group,                  my $members_result = &group_members($cdom,$cnum,$group,
                                                     \%grp_info);                                                      \%grp_info);
                 my $files_result = &group_files($group,\%grp_info);                   my $port_path = '/userfiles/groups/'.$group.'/portfolio';
                   my $totaldirs = 0;
                   my $totalfiles = 0;
                   &group_files($group,$port_path,\$totalfiles,\$totaldirs);
                   $grp_info{$group}{'totalfiles'} = $totalfiles;
                   $grp_info{$group}{'totaldirs'} = $totaldirs;
                   my $getpropath = 1;  
                   my $diskuse = &Apache::lonnet::diskusage($cdom,$cnum,$port_path,                                                         $getpropath);
                   if ($grp_info{$group}{'quota'} > 0) {
                       my $pct_use = 0.1 * $diskuse/$grp_info{$group}{'quota'};
                       $grp_info{$group}{'diskuse'} = sprintf("%.0f",$pct_use);
                   } else {
                       $grp_info{$group}{'diskuse'} = 'N/A';
                   }
                   my ($groupboards,$boardshash)=&Apache::longroup::get_group_bbinfo(
                                                                  $cdom,$cnum,$group);
                   $grp_info{$group}{'boards'} = scalar(@{$groupboards});
                 if ($env{'form.sortby'} eq 'groupname') {                  if ($env{'form.sortby'} eq 'groupname') {
                     push(@{$Sortby{$group}},$group);                      push(@{$Sortby{$group}},$group);
                 } elsif ($env{'form.sortby'} eq 'description') {                  } elsif ($env{'form.sortby'} eq 'description') {
                     push(@{$Sortby{$grp_info{$group}{'description'}}},                      push(@{$Sortby{$grp_info{$group}{'description'}}},$group);
                                                                      $group);  
                 } elsif ($env{'form.sortby'} eq 'creator') {                  } elsif ($env{'form.sortby'} eq 'creator') {
                     push(@{$Sortby{$grp_info{$group}{'creator'}}},$group);                      push(@{$Sortby{$grp_info{$group}{'creator'}}},$group);
                 } elsif ($env{'form.sortby'} eq 'creation') {                  } elsif ($env{'form.sortby'} eq 'creation') {
Line 214  END Line 307  END
                     push(@{$Sortby{$group}},$group);                      push(@{$Sortby{$group}},$group);
                 }                  }
             }              }
             my $rowNum = 0;  
             my $rowColor;  
             foreach my $key (sort(keys(%Sortby))) {              foreach my $key (sort(keys(%Sortby))) {
                 foreach my $group (@{$Sortby{$key}}) {                  foreach my $group (@{$Sortby{$key}}) {
                     if ($rowNum %2 == 1) {  
                         $rowColor = $rowColor1;  
                     } else {  
                         $rowColor = $rowColor2;  
                     }  
                     my $description =                       my $description = 
                    &Apache::lonnet::unescape($grp_info{$group}{'description'});   &unescape($grp_info{$group}{'description'});
                     my $creator = $grp_info{$group}{'creator'};                      my $creator = $grp_info{$group}{'creator'};
                     my $creation = $grp_info{$group}{'creation'};                      my $creation = $grp_info{$group}{'creation'};
                     my $modified = $grp_info{$group}{'modified'};                       my $modified = $grp_info{$group}{'modified'}; 
                     my $quota = $grp_info{$group}{'quota'};                      my $quota = $grp_info{$group}{'quota'};
                     my $totalmembers = $grp_info{$group}{'totalmembers'};                      my $totalmembers = $grp_info{$group}{'totalmembers'};
                     my $totalfiles = $grp_info{$group}{'totalfiles'};                      my $totalfiles = $grp_info{$group}{'totalfiles'};
                       my $totaldirs = $grp_info{$group}{'totaldirs'};
                     my $boards = $grp_info{$group}{'boards'};                      my $boards = $grp_info{$group}{'boards'};
                     my $diskuse = $grp_info{$group}{'diskuse'};                      my $diskuse = $grp_info{$group}{'diskuse'};
                     my $functionality;                      my $functionality;
Line 242  END Line 329  END
                     if (!$functionality) {                      if (!$functionality) {
                         $functionality = &mt('None available');                          $functionality = &mt('None available');
                     }                      }
                     my $link = $actionlinks{$action};                      my $link;
                     if ($action eq 'modify' || $action eq 'delete') {                      if ($action eq 'modify' || $action eq 'delete' || 
                         $link .= $group;                          $action eq 'reenable') {
                           $link = '<a href="'.&HTML::Entities::encode($actionlinks{$action}.$group,'<>&"').
                                   '">'.$lt{$action}.'</a>';
                     } else {                      } else {
                         $link .= $group.'/grppg?register=1';                          $link =
                               &Apache::longroup::get_group_link($cdom,$cnum,$group,$navmap,
                                                                 $view_permission);
                           if ($link) {
                               $link = '<a href="'.$link;
                               $link .= (($link=~/\?/)?'&amp;':'?').'ref=grouplist';
                               if (exists($env{'form.refpage'})) {
                                   $link .= '&amp;refpage='.$env{'form.refpage'};
                               }
                               $link .= '">'.$lt{$action}.'</a>';
                           }
                       }
                       if ($action eq 'view') { 
                           if ($manage_permission) { 
                               $link .= '&nbsp;&nbsp;<a href="'.
                                         &HTML::Entities::encode($actionlinks{'modify'}.$group,'<>&"').
                                         '">'.$lt{'modify'}.'</a>&nbsp;&nbsp;<a href="'.
                                         &HTML::Entities::encode($actionlinks{'delete'}.$group,'<>&"').
                                         '">'.$lt{'delete'}.'</a>';
                           }
                     }                      }
                     $link .= '">'.$lt{$action}.'</a>';                        $r->print(&Apache::loncommon::start_data_table_row('LC_data_table_dense').
                     $r->print('<tr bgcolor="'.$rowColor.'"><td><small>'.$link.'</small></td><td><small>'.$group.'</small></td><td><small>'.$description.'</small></td><td><small>'.$creator.'</small></td><td><small>'. &Apache::lonnavmaps::timeToHumanString($creation).'</small></td><td><small>'. &Apache::lonnavmaps::timeToHumanString($modified).'</small></td><td><small>'.$functionality.'</small></td><td><small>'.$quota.'</small></td><td><small>'.$totalmembers.'</small></td><td><small>'.$totalfiles.'</small></td><td><small>'.$boards.'</small></td><td><small>'.$diskuse.'</small></td></tr>');        '<td>'.$link.'</td>'.
                     $rowNum ++;        '<td>'.$group.'</td>'.
         '<td>'.$description.'</td>'.
         '<td>'.$creator.'</td>'.
         '<td>'. &Apache::lonnavmaps::timeToHumanString($creation).'</td>'.
         '<td>'. &Apache::lonnavmaps::timeToHumanString($modified).'</td>'.
         '<td>'.$functionality.'</td>'.
         '<td align="right">'.$quota.'</td>'.
         '<td align="right">'.$totalmembers.'</td>'.
         '<td align="right">'.
                                     '<span class="LC_nobreak">'.&mt('Files: [_1]',$totalfiles).'</span><br />'.
                                     '<span class="LC_nobreak">'.&mt('Folders: [_1]',$totaldirs).'</span>'.
                                     '</td>'.
         '<td align="right">'.$boards.'</td>'.
         '<td align="right">'.$diskuse.'</td>'.
         &Apache::loncommon::end_data_table_row());
                   }
               }
               $r->print(&Apache::loncommon::end_data_table());
               $r->print('<input type="hidden" name="refpage" '.
                         'value="'.$env{'form.refpage'}.'" />');
               if ($action eq 'view') {
                   if (!defined($state)) {
                       $state = 'view';
                 }                  }
                   $r->print('<input type="hidden" name="state" value="'.
                         $state.'" />');
             }              }
             $r->print('</table>');  
             $r->print(&Apache::lonhtmlcommon::end_pick_box());  
         } else {          } else {
             $r->print($lt{'nogr'});              $r->print($lt{'nogr'});
             if ($manage_permission) {              if ($manage_permission) {
                 $r->print('<br /><br /><a href="/adm/coursegroups?action=create&refpage='.$env{'form.refpage'}.'">'.$lt{'crng'}.'</a>');                  $r->print('<br /><br /><a href="/adm/coursegroups?action=create&amp;refpage='.$env{'form.refpage'}.'">'.$lt{'crng'}.'</a>');
                   if ($action ne 'reenable') {
                       if ($reenable_link) {
                           $r->print($reenable_link);
                       }
                   }
             } else {              } else {
                 $r->print('<br /><br />'.$lt{'crng'});                  $r->print('<br /><br />'.$lt{'alth'});
   
             }              }
         }          }
     } else {      } else {
         my @coursegroups = split(/:/,$env{'request.course.groups'});          my @coursegroups = split(/:/,$env{'request.course.groups'});
         if (@coursegroups > 0) {          if (@coursegroups > 0) {
               my $numlinks = 0;
             $r->print('<br /><br />');              $r->print('<br /><br />');
             my %curr_groups;              my %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum);
             if (&Apache::loncommon::coursegroups(\%curr_groups,$cdom,$cnum)) {              if (%curr_groups) {
                   my $navmap=Apache::lonnavmaps::navmap->new();
                   if (!defined($navmap)) {
                       $r->print('<div class="LC_error">'.
                                 &mt('An error occurred retrieving information about resources in the course.').'<br />'.
                                 &mt('It is recommended that you [_1]re-initialize the course[_2] and then return to this page.','<a href="/adm/roles?selectrole=1&amp;newrole='.$env{'request.role'}.'&amp;orgurl=%2fadm%2fcoursegroups">','</a>').
                                 '</div>');
                       return;
                   }
                 foreach my $group (@coursegroups) {                  foreach my $group (@coursegroups) {
                     my %group_info =  &Apache::loncommon::get_group_settings(                      my %group_info =  &Apache::longroup::get_group_settings(
                                         $curr_groups{$group});                                          $curr_groups{$group});
                     my $description = &Apache::lonnet::unescape(                      my $description = &unescape(
                                         $group_info{description});                                          $group_info{description});
                     my ($uname,$udom) = split(/:/,$group_info{creator});                      my ($link,$hidden) = 
                     $r->print('<font size="+1"><a href="/adm/'.$udom.'/'.$uname.'/'.$group.'/grppg?register=1">'.$group,'</a><font><br /><small>'.$description.'</small><br /><br />');                          &Apache::longroup::get_group_link($cdom,$cnum,$group,$navmap,
                                                             $view_permission);
                       if ($link) {
                           $link .= '&amp;ref=grouplist';
                           $r->print('<span style="font-size: larger"><a href="'.$link.'">'.
                                     $description.'</a></span><br /><br />');
                           $numlinks ++;
                       } elsif ($hidden) {
                           my $numtools = 0;
                           my $refarg = '&amp;ref=grouplist'; 
                           my $output =
                               &Apache::longroup::display_group_links($r,$env{'form.grade_target'},$group,'view',
                                                                      $refarg,\$numtools,$hidden,%group_info);
                           if ($numtools) {
                               $r->print('<span style="font-size: larger">'.$description.'</a></span>'.
                                         '<br />'.$output.'<br /><br />');
                               $numlinks ++;
                           }
                       }
                 }                  }
             }              }
               if (!$numlinks) {
                   $r->print(
                       '<p class="LC_info">'
                      .&mt('You do not currently have access to any '.$gpterm.'s'
                      .' in this '.lc($crstype).'.')
                      .'</p>'
                   );
               }
         } else {          } else {
             $r->print(&mt('You are not currently a member of any '.              $r->print(
                           'active groups in this course'));                  '<p class="LC_info">'
                  .&mt('You are not currently a member of any active '.$gpterm.'s'
                      .' in this '.lc($crstype).'.')
                  .'</p>'
               );
         }          }
     }      }
     return;      return;
 }  }
   
 sub group_administration {  sub group_administration {
     my ($r,$action,$cdom,$cnum,$function,$tabcol,$functions,$idx,      my ($r,$action,$state,$cdom,$cnum,$functions,$idx,$view_permission,
         $view_permission,$manage_permission,$rowColor1,$rowColor2) = @_;   $manage_permission,$gpterm,$ucgpterm,$crstype) = @_;
     my %sectioncount = ();      my %sectioncount = ();
     my @tools = ();      my @tools = ();
     my @types = ();      my @types = ();
Line 303  sub group_administration { Line 476  sub group_administration {
     my %memchg;      my %memchg;
     my @member_changes = ('deletion','expire','activate','reenable',      my @member_changes = ('deletion','expire','activate','reenable',
                           'changefunc','changepriv');                            'changefunc','changepriv');
     my $state = $env{'form.state'};      my ($groupname,$description,$startdate,$enddate,$granularity,$specificity,
     my ($groupname,$description,$startdate,$enddate,$granularity,$specificity);          $quota,$validate_script);
   
     if (defined($env{'form.groupname'})) {      if (defined($env{'form.groupname'})) {
         $groupname = $env{'form.groupname'};          $groupname = $env{'form.groupname'};
Line 328  sub group_administration { Line 501  sub group_administration {
         if (defined($env{'form.specificity'})) {          if (defined($env{'form.specificity'})) {
             $specificity=$env{'form.specificity'};              $specificity=$env{'form.specificity'};
         }          }
           if (defined($env{'form.quota'})) {
               $quota=$env{'form.quota'};
           }
     }      }
     if (($action eq 'create') || (($action eq 'modify')       if (($action eq 'create') || (($action eq 'modify') 
         && (($state eq 'pick_privs') || ($state eq 'addresult')))) {          && (($state eq 'pick_privs') || ($state eq 'addresult')))) {
Line 342  sub group_administration { Line 517  sub group_administration {
   
     if ($action eq 'modify') {      if ($action eq 'modify') {
         if ($state eq '') {          if ($state eq '') {
             $state = 'pick_group';              if (defined($env{'form.groupname'})) {
                   $state = 'pick_task';
               }
         } else {          } else {
             %stored = &retrieve_settings($cdom,$cnum,$groupname);              %stored = &retrieve_settings($cdom,$cnum,$groupname,$action);
             if (ref($stored{'types'}) eq 'ARRAY') {              if (ref($stored{'types'}) eq 'ARRAY') {
                 @types = @{$stored{'types'}};                  @types = @{$stored{'types'}};
             }              }
Line 363  sub group_administration { Line 540  sub group_administration {
                 $description = $stored{'description'};                  $description = $stored{'description'};
                 $granularity = $stored{'granularity'};                  $granularity = $stored{'granularity'};
                 $specificity =  $stored{'specificity'};                  $specificity =  $stored{'specificity'};
                   $quota = $stored{'quota'};
             }              }
         }          }
     }      }
   
     my %toolprivs = ();      my $toolprivs = &Apache::longroup::get_tool_privs($gpterm);
     %{$toolprivs{'email'}} = (  
                                  sgm => 'Send group mail',      my $fixedprivs = &Apache::longroup::get_fixed_privs();
                                  sgb => 'Broadcast mail',  
                              );      my %elements = 
     %{$toolprivs{'discussion'}} =  (   (
                                      cgb => 'Create boards',   create => {
                                      pgd => 'Post',       pick_name => {
                                      pag => 'Anon. posts',   startdate_month  => 'selectbox',
                                      rgi => 'Get identities',    startdate_hour   => 'selectbox',
                                      vgb => 'View boards',   enddate_month    => 'selectbox',
                                    );   enddate_hour     => 'selectbox',
     %{$toolprivs{'chat'}} =  (   startdate_day    => 'text',
                                 pgc => 'Chat',   startdate_year   => 'text',
                              );   startdate_minute => 'text',
     %{$toolprivs{'files'}} =  (   startdate_second => 'text',
                                  rgf => 'Retrieve',   enddate_day      => 'text',
                                  ugf => 'Upload',   enddate_year     => 'text',
                                  dgf => 'Delete',   enddate_minute   => 'text',
                               );   enddate_second   => 'text',
     %{$toolprivs{'roster'}} = (   groupname        => 'text',
                                  vgm => 'View',   description      => 'text',
                               );                   quota            => 'text',
     %{$toolprivs{'homepage'}} = (   tool             => 'checkbox',
                                 vgh => 'View page',   granularity      => 'radio',
                                 mgh => 'Modify page',   no_end_date      => 'checkbox',
                               );       },
     my %fixedprivs = ();       pick_members => {
     %{$fixedprivs{'email'}} = ('sgm' => 1);   member          => 'checkbox',
     %{$fixedprivs{'discussion'}} = ('vgb' => 1);   defpriv         => 'checkbox',
     %{$fixedprivs{'chat'}} = ('pgc' => 1);       },
     %{$fixedprivs{'files'}} = ('rgf' => 1);   },
     %{$fixedprivs{'roster'}} = ('vgm' => 1);   );
     %{$fixedprivs{'homepage'}} = ('vgh' => 1);      
       $elements{'modify'} = {
     my %elements = ();   change_settings => {
     %{$elements{'create'}} = ();      %{$elements{'create'}{'pick_name'}},
     %{$elements{'modify'}} = ();      specificity => 'radio',
     %{$elements{'create'}{'pick_name'}} = (      defpriv     => 'checkbox',
         startdate_month => 'selectbox',      autorole    => 'checkbox',
         startdate_hour => 'selectbox',      autoadd     => 'radio',
         enddate_month => 'selectbox',      autodrop    => 'radio',
         enddate_hour => 'selectbox',   },
         startdate_day => 'text',   add_members => {
         startdate_year => 'text',      types       => 'selectbox',
         startdate_minute => 'text',      roles       => 'selectbox',
         startdate_second => 'text',   },
         enddate_day => 'text',      };
         enddate_year => 'text',  
         enddate_minute => 'text',  
         enddate_second => 'text',  
         groupname => 'text',  
         description => 'text',  
         tool => 'checkbox',  
         granularity => 'radio',  
         no_end_date => 'checkbox',  
     );  
     %{$elements{'modify'}{'change_settings'}} = (  
                                    %{$elements{'create'}{'pick_name'}},  
                                                 specificity => 'radio',  
                                                 defpriv => 'checkbox',  
                                                 autorole => 'checkbox',  
                                                 autoadd => 'radio',  
                                                 autodrop => 'radio',  
                                    );  
     if (ref($stored{'autorole'}) eq 'ARRAY') {      if (ref($stored{'autorole'}) eq 'ARRAY') {
         foreach my $role (@{$stored{'autorole'}}) {          foreach my $role (@{$stored{'autorole'}}) {
             $elements{'modify'}{'change_settings'}{'sec_'.$role} = 'selectbox';               unless (($role eq 'cc') || ($role eq 'co')) {
                   $elements{'modify'}{'change_settings'}{'sec_'.$role} = 
                                                                      'selectbox';
               }
         }          }
     }      }
     %{$elements{'create'}{'pick_members'}} = (  
         member => 'checkbox',  
         defpriv => 'checkbox',  
     );  
   
     %{$elements{'modify'}{'add_members'}} = (  
         types => 'selectbox',  
         roles => 'selectbox',  
     );  
   
     if (($action eq 'create') && ($state eq 'pick_name')) {      if (($action eq 'create') && ($state eq 'pick_name')) {
         $elements{'create'}{'pick_name'}{'types'} = 'selectbox';          $elements{'create'}{'pick_name'}{'types'} = 'selectbox';
Line 455  sub group_administration { Line 611  sub group_administration {
         (($state eq 'pick_name') || ($state eq 'pick_privs'))) ||          (($state eq 'pick_name') || ($state eq 'pick_privs'))) ||
        (($action eq 'modify') && (($state eq 'change_settings') ||         (($action eq 'modify') && (($state eq 'change_settings') ||
                                   ($state eq 'add_members')))) {                                    ($state eq 'add_members')))) {
         my $numsections = &Apache::loncommon::get_sections($cdom,$cnum,          %sectioncount = &Apache::loncommon::get_sections($cdom,$cnum);
                                                            \%sectioncount);          $elements{'create'}{'pick_name'}{'sectionpick'} = 'selectbox';
         if ($numsections > 0) {          $elements{'modify'}{'change_mapping'}{'sectionpick'} = 'selectbox';
             $elements{'create'}{'pick_name'}{'sectionpick'} = 'selectbox';          $elements{'modify'}{'add_members'}{'sectionpick'} = 'selectbox';
             $elements{'modify'}{'change_mapping'}{'sectionpick'} = 'selectbox';  
             $elements{'modify'}{'add_members'}{'sectionpick'} = 'selectbox';  
         }  
     }      }
   
     if ($action eq 'create') {      if (($action eq 'create') || 
           ($action eq 'modify' && $state eq 'pick_members')) {
         if (defined($env{'form.types'})) {          if (defined($env{'form.types'})) {
             @types=&Apache::loncommon::get_env_multiple('form.types');              @types=&Apache::loncommon::get_env_multiple('form.types');
         }          }
Line 473  sub group_administration { Line 627  sub group_administration {
         }          }
         if (defined($env{'form.sectionpick'})) {          if (defined($env{'form.sectionpick'})) {
             @sections=&Apache::loncommon::get_env_multiple('form.sectionpick');              @sections=&Apache::loncommon::get_env_multiple('form.sectionpick');
             if (grep/^_all$/,@sections) {  
                 @sections = sort {$a cmp $b} keys(%sectioncount);  
             }  
         }          }
     }      }
   
Line 516  sub group_administration { Line 667  sub group_administration {
                         $num_reenable ++;                          $num_reenable ++;
                         next;                          next;
                     } elsif (($start > $now)) {                      } elsif (($start > $now)) {
                         $num_activate = 1;                          $num_activate ++;
                         next;                          next;
                     } else {                      } else {
                         $num_expire ++;                          $num_expire ++;
Line 557  sub group_administration { Line 708  sub group_administration {
     }      }
   
     if (($state eq 'pick_privs') || ($state eq 'change_privs') ||      if (($state eq 'pick_privs') || ($state eq 'change_privs') ||
         (($specificity eq 'No') &&            (($specificity eq 'No') && 
          (($state eq 'result') || ($state eq 'memresult')))) {            ($state eq 'memresult' || $state eq 'result' || $state eq 'addresult'))) { 
         foreach my $tool (@tools) {          foreach my $tool (@tools) {
             my @values = &Apache::loncommon::get_env_multiple('form.user_'.$tool);              my @values = &Apache::loncommon::get_env_multiple('form.user_'.$tool);
             foreach my $user (@values) {              foreach my $user (@values) {
                   if ($state eq 'pick_privs' || $state eq 'result' 
                       || $state eq 'addresult') {
                       if (!grep(/^\Q$user\E$/,@members)) {
                           next;
                       }
                   }
                 unless(exists($usertools{$user}{$tool})) {                  unless(exists($usertools{$user}{$tool})) {
                     $usertools{$user}{$tool} = 1;                      $usertools{$user}{$tool} = 1;
                 }                  }
Line 593  sub group_administration { Line 750  sub group_administration {
                         }                          }
                         my @currtools = ();                          my @currtools = ();
                         if (@userprivs > 0) {                          if (@userprivs > 0) {
                             foreach my $tool (sort(keys(%fixedprivs))) {                              foreach my $tool (sort(keys(%{$fixedprivs}))) {
                                 foreach my $priv (keys(%{$fixedprivs{$tool}})) {                                  foreach my $priv (keys(%{$$fixedprivs{$tool}})) {
                                     if (grep/^$priv$/,@userprivs) {                                      if (grep/^$priv$/,@userprivs) {
                                         push(@currtools,$tool);                                          push(@currtools,$tool);
                                         last;                                          last;
Line 664  sub group_administration { Line 821  sub group_administration {
         && ($specificity eq 'Yes')) {          && ($specificity eq 'Yes')) {
         foreach my $user (sort(keys(%usertools))) {          foreach my $user (sort(keys(%usertools))) {
             foreach my $tool (keys(%{$usertools{$user}})) {              foreach my $tool (keys(%{$usertools{$user}})) {
                 foreach my $priv (keys(%{$toolprivs{$tool}})) {                  foreach my $priv (keys(%{$$toolprivs{$tool}})) {
                     unless (exists($fixedprivs{$tool}{$priv})) {                      unless (exists($$fixedprivs{$tool}{$priv})) {
                         $elements{$action}{$state}{'userpriv_'.$priv} = 'checkbox';                          $elements{$action}{$state}{'userpriv_'.$priv} = 'checkbox';
                     }                      }
                 }                  }
             }              }
         }          }
     }      }
    
       if (($action eq 'create' && $state eq 'pick_name') || 
           ($action eq 'modify' && $state eq 'change_settings')) {
           my ($crsquota,$freespace,$maxposs) = &get_quota_constraints($action,\%stored);
           my $space_trim = '/^\s*|\s*\$/g,""';
           my $float_check = '/^([0-9]*\.?[0-9]*)$/';
           $validate_script = '
       var newquota = new String(document.'.$state.'.quota.value);
       newquota.replace('.$space_trim.');
       if (newquota == "" ) {
           document.'.$state.'.quota.value = 0;
           newquota = "0";
       }
       var maxposs = '.sprintf("%.2f",$maxposs).';
       if (newquota > maxposs) {
           alert("The group portfolio quota you entered for this group ("+newquota+" MB) exceeds the maximum possible ("+maxposs+" MB). Please enter a smaller number.");
           return;
       }
       var re_quota = '.$float_check.';
       var check_quota = newquota.match(re_quota);
       if (check_quota == null) {
           alert("The quota you entered contains invalid characters, the quota should only include numbers, with or without a decimal point.");
           return;
       }
       if (newquota == 0) {
           var warn_zero = 0;
           for (var i=0; i<document.'.$state.'.tool.length; i++) {
               if (document.'.$state.'.tool[i].value == "files") {
                   if (document.'.$state.'.tool[i].checked) {
                       warn_zero = 1;
                   }
               }
           }
           if (warn_zero == 1) {
               alert("You have indicated that the group portfolio should be enabled, but you have set the repository quota to 0 MB.\nThis will prevent any upload of files.\nPlease set a value or disable the repository feature.");
               return;
           }
       } 
   ';
       }
     my $jscript = &Apache::loncommon::check_uncheck_jscript();      my $jscript = &Apache::loncommon::check_uncheck_jscript();
     $jscript .= qq|      $jscript .= qq|
 function nextPage(formname,nextstate) {  function nextPage(formname,nextstate) {
     formname.state.value= nextstate;      formname.state.value= nextstate;
       $validate_script
     formname.submit();      formname.submit();
 }  }
 function backPage(formname,prevstate) {  function backPage(formname,prevstate) {
Line 688  function changeSort(caller) { Line 885  function changeSort(caller) {
     document.$state.sortby.value = caller;      document.$state.sortby.value = caller;
     document.$state.submit();      document.$state.submit();
 }   } 
                                                                                         
 |;  |;
     $jscript .= &Apache::lonhtmlcommon::set_form_elements(      $jscript .= &Apache::lonhtmlcommon::set_form_elements(
                            \%{$elements{$action}{$state}},\%stored);                             \%{$elements{$action}{$state}},\%stored);
Line 696  function changeSort(caller) { Line 893  function changeSort(caller) {
     my %states = ();      my %states = ();
     my %branchstates = ();      my %branchstates = ();
     @{$states{'create'}} = ('pick_name','pick_members','pick_privs','result');      @{$states{'create'}} = ('pick_name','pick_members','pick_privs','result');
     @{$states{'modify'}} = ('pick_group','pick_task');      @{$states{'modify'}} = ('pick_task');
       @{$states{'delete'}} = ('verify','result');
       @{$states{'reenable'}} = ('verify','result');
     @{$branchstates{'noprivs'}} = ('result');      @{$branchstates{'noprivs'}} = ('result');
     @{$branchstates{'settings'}} = ('change_settings','chgresult');      @{$branchstates{'settings'}} = ('change_settings','chgresult');
     @{$branchstates{'members'}} = ('change_members','change_privs','memresult');      @{$branchstates{'members'}} = ('change_members','change_privs','memresult');
     @{$branchstates{'adds'}} = ('add_members','pick_members','pick_privs',      @{$branchstates{'adds'}} = ('add_members','pick_members','pick_privs',
                                 'addresult');                                  'addresult');
       
     if (defined($env{'form.branch'})) {      if (defined($env{'form.branch'})) {
         push (@{$states{$action}},@{$branchstates{$env{'form.branch'}}});          push (@{$states{$action}},@{$branchstates{$env{'form.branch'}}});
     }      }
   
     if (($action eq 'create') || ($action eq 'modify')) {      if (($action eq 'create') || ($action eq 'modify') || ($action eq 'delete') || ($action eq 'reenable')) {
         my $done = 0;          my $done = 0;
         my $i=0;          my $i=0;
         while ($i<@{$states{$action}} && !$done) {          while ($i<@{$states{$action}} && !$done) {
Line 720  function changeSort(caller) { Line 919  function changeSort(caller) {
     }      }
   
     my $loaditems =  &onload_action($action,$state);      my $loaditems =  &onload_action($action,$state);
     $r->print(&header('Course Groups Manager',      $r->print(&header("Groups Manager",
       $jscript,$action,$state,$page,$function,$loaditems));        $jscript,$action,$state,$page,$loaditems));
   
     if ($env{'form.refpage'} eq 'enrl') {      if ($env{'form.refpage'} eq 'cusr') {
         &Apache::lonhtmlcommon::add_breadcrumb          &Apache::lonhtmlcommon::add_breadcrumb
         ({href=>"/adm/dropadd",          ({href=>"/adm/createuser",
           text=>"Enrollment Manager",            text=>"User Management",
           faq=>9,bug=>'Instructor Interface',});            faq=>9,bug=>'Instructor Interface',});
     } else {          if ($action eq 'modify' || $action eq 'delete') {
               &Apache::lonhtmlcommon::add_breadcrumb
               ({href=>"/adm/coursegroups?refpage=cusr&amp;action=$action",
                 text=>"Groups",
                 faq=>9,bug=>'Instructor Interface',});
           }
       } else { 
         &Apache::lonhtmlcommon::add_breadcrumb          &Apache::lonhtmlcommon::add_breadcrumb
        ({href=>"/adm/coursegroups",            ({href=>"/adm/coursegroups",
           text=>"Course Groups",              text=>"Groups",
           faq=>9,bug=>'Instructor Interface',});              faq=>9,bug=>'Instructor Interface',});
           if ($env{'form.refpage'} eq 'grouplist') {
               &Apache::lonhtmlcommon::add_breadcrumb
                ({href=>"/adm/$cdom/$cnum/$env{'form.groupname'}/smppg?ref=grouplist",
                  text=>"Group: $description",});
           }
     }      }
   
     my %trail = ();      my %trail = ();
     %{$trail{'create'}} = &Apache::lonlocal::texthash (      %{$trail{'create'}} = &Apache::lonlocal::texthash (
                             pick_name => 'Group Settings',                              pick_name => $ucgpterm.' Settings',
                             pick_members => 'Select Members',                              pick_members => 'Select Members',
                             pick_privs => 'Choose Privileges',                              pick_privs => 'Choose Privileges',
                             result => 'Creation Complete',                              result => 'Creation Complete',
                           );                            );
     %{$trail{'modify'}} = &Apache::lonlocal::texthash(      %{$trail{'modify'}} = &Apache::lonlocal::texthash(
                             pick_group => 'Groups',  
                             pick_task => 'Choose Task',                              pick_task => 'Choose Task',
                             change_settings => 'Group Settings',                              change_settings => "$ucgpterm Settings",
                             change_members => 'Modify/Delete Members',                              change_members => 'Modify/Delete Members',
                             change_privs => 'Change Privileges',                              change_privs => 'Change Privileges',
                             change_mapping => 'Membership Mapping',                              change_mapping => 'Membership Mapping',
Line 756  function changeSort(caller) { Line 965  function changeSort(caller) {
                             memresult => 'Modifications Complete',                              memresult => 'Modifications Complete',
                             addresult => 'Additions Complete',                              addresult => 'Additions Complete',
                           );                            );
       %{$trail{'delete'}} = &Apache::lonlocal::texthash(
                               verify => 'Verify deletion',
                               result => 'Deletion Complete'
                             );
       %{$trail{'reenable'}} = &Apache::lonlocal::texthash(
                               verify => 'Verify Re-enable',
                               result => 'Re-enabled'
                             );
     my %navbuttons = &Apache::lonlocal::texthash(      my %navbuttons = &Apache::lonlocal::texthash(
                              gtns => 'Go to next step',                               gtns => 'Next',#'Go to next step',
                              gtps => 'Go to previous step',                               gtps => 'Back',#'Go to previous step',
                              crgr => 'Create group',                               crgr => 'Create '.$gpterm,
                              mose => 'Modify settings',                               mose => 'Save',#'Modify settings',
                              gtpp => 'Go to previous page',                               gtpp => 'Back',#'Go to previous page',
                              adme => 'Add members',                               adme => 'Add members',
     );      );
     if ((($action eq 'create') || ($action eq 'modify')) &&      if ((($action eq 'create') || ($action eq 'modify') || ($action eq 'delete') || ($action eq 'reenable')) &&
               ($manage_permission)) {                ($manage_permission)) {
         for (my $i=0; $i<@{$states{$action}}; $i++) {          for (my $i=0; $i<@{$states{$action}}; $i++) {
             if ($state eq $states{$action}[$i]) {              if ($state eq $states{$action}[$i]) {
                 &Apache::lonhtmlcommon::add_breadcrumb(                  &Apache::lonhtmlcommon::add_breadcrumb(
                    {text=>"$trail{$action}{$state}"});                     {text=>"$trail{$action}{$state}"});
                 $r->print(&Apache::lonhtmlcommon::breadcrumbs                  $r->print(&Apache::lonhtmlcommon::breadcrumbs
                      (undef,'Course Groups Manager'));    ("Groups Manager","Creating_Groups"));
                 &display_control($r,$cdom,$cnum,$tabcol,$action,$state,$page,                  &display_control($r,$cdom,$cnum,$action,$state,$page,
                        \%sectioncount,$groupname,$description,$functions,                         \%sectioncount,$groupname,$description,$functions,
                        \@tools,\%toolprivs,\%fixedprivs,$startdate,$enddate,                         \@tools,$toolprivs,$fixedprivs,$startdate,$enddate,
                        \%users,\%userdata,$idx,\%memchg,\%usertools,                         \%users,\%userdata,$idx,\%memchg,\%usertools,
                        $function,$view_permission,$manage_permission,                         $view_permission,$manage_permission,
                        \%stored,$granularity,$specificity,\@types,\@roles,                         \%stored,$granularity,$quota,$specificity,\@types,\@roles,
                        \@sections,\%states,\%navbuttons,$rowColor1,$rowColor2);                         \@sections,\%states,\%navbuttons,$gpterm,$ucgpterm,
    $crstype);
                 last;                  last;
             } else {              } else {
                 if (($state eq 'result') && ($i > 0)) {                  if (($action eq 'create') || ($action eq 'modify')) {
                     &Apache::lonhtmlcommon::add_breadcrumb(                      if (($state eq 'result') && ($i > 0)) {
                           &Apache::lonhtmlcommon::add_breadcrumb(
     {href=>"javascript:backPage(document.$state,'$states{$action}[0]')",      {href=>"javascript:backPage(document.$state,'$states{$action}[0]')",
       text=>"$trail{$action}{$states{$action}[$i]}"});        text=>"$trail{$action}{$states{$action}[$i]}"});
                 } else {                       } else { 
                     &Apache::lonhtmlcommon::add_breadcrumb(                          &Apache::lonhtmlcommon::add_breadcrumb(
      {href=>"javascript:backPage(document.$state,'$states{$action}[$i]')",       {href=>"javascript:backPage(document.$state,'$states{$action}[$i]')",
       text=>"$trail{$action}{$states{$action}[$i]}"});        text=>"$trail{$action}{$states{$action}[$i]}"});
                       }
                 }                  }
             }              }             
         }          }
     } elsif (($action eq 'view') && ($view_permission)) {      } elsif (($action eq 'view') && ($view_permission)) {
                         &Apache::lonhtmlcommon::add_breadcrumb(                          &Apache::lonhtmlcommon::add_breadcrumb(
                    {text=>"View groups"});                     {text=>"View $gpterm".'s'});
         $r->print(&Apache::lonhtmlcommon::breadcrumbs          $r->print(&Apache::lonhtmlcommon::breadcrumbs
                      (undef,'Course Groups Manager'));    ('Groups Manager'));
         &display_groups($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,          &display_groups($r,$cdom,$cnum,$functions,$idx,$view_permission,
                         $view_permission,$manage_permission,$action,   $manage_permission,$action,$state,$gpterm,$ucgpterm,
                         $rowColor1,$rowColor2);   $crstype);
   
     }      }
     $r->print(&footer());      $r->print(&footer());
     return;      return;
 }  }
   
 sub retrieve_settings {  sub retrieve_settings {
     my ($cdom,$cnum,$groupname) = @_;      my ($cdom,$cnum,$groupname,$action) = @_;
     my %groupinfo;  
     my %stored;  
     my %curr_groups;      my %curr_groups;
     my $numgroups = &Apache::loncommon::coursegroups(\%curr_groups,$cdom,      my $namespace;
                                                              $cnum,$groupname);      if ($action eq 'reenable') {
     if ($numgroups > 0) {          $namespace = 'deleted_groups';
         %groupinfo = &Apache::loncommon::get_group_settings(      } else {
                                                      $curr_groups{$groupname});          $namespace = 'coursegroups';
         $stored{'description'} = &Apache::lonnet::unescape(      }
                                                     $groupinfo{'description'});      %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum,$groupname,
         $stored{'startdate'} = $groupinfo{'startdate'};                                                     $namespace);
         $stored{'enddate'} = $groupinfo{'enddate'};  
         if ($stored{'enddate'} == 0) {      return if (!%curr_groups);
             $stored{'no_end_date'} = 1;  
         }      my %groupinfo = 
         $stored{'granularity'} = $groupinfo{'granularity'};   &Apache::longroup::get_group_settings($curr_groups{$groupname});
         $stored{'specificity'} = $groupinfo{'specificity'};  
         $stored{'creation'} = $groupinfo{'creation'};      my %stored;
         $stored{'creator'} = $groupinfo{'creator'};  
       $stored{'description'} = 
         foreach my $tool (sort(keys(%{$groupinfo{'functions'}}))) {   &unescape($groupinfo{'description'});
             if ($groupinfo{functions}{$tool} eq 'on') {      $stored{'startdate'} = $groupinfo{'startdate'};
                 push(@{$stored{tool}},$tool);      $stored{'enddate'} = $groupinfo{'enddate'};
             }      if ($stored{'enddate'} == 0) {
         }   $stored{'no_end_date'} = 1;
         foreach my $role (@{$groupinfo{'roles'}}) {      }
             push(@{$stored{roles}},$role);      $stored{'granularity'} = $groupinfo{'granularity'};
         }      $stored{'specificity'} = $groupinfo{'specificity'};
         foreach my $type (@{$groupinfo{'types'}}) {      $stored{'creation'} = $groupinfo{'creation'};
             push(@{$stored{types}},$type);      $stored{'creator'} = $groupinfo{'creator'};
         }      $stored{'quota'} = $groupinfo{'quota'};
         foreach my $section (@{$groupinfo{'sectionpick'}}) {  
             push(@{$stored{sectionpick}},$section);      foreach my $tool (sort(keys(%{$groupinfo{'functions'}}))) {
         }   if ($groupinfo{functions}{$tool} eq 'on') {
         foreach my $defpriv (@{$groupinfo{'defpriv'}}) {      push(@{$stored{tool}},$tool);
             push(@{$stored{defpriv}},$defpriv);   }
         }      }
         $stored{'autoadd'} = $groupinfo{'autoadd'};      foreach my $role (@{$groupinfo{'roles'}}) {
         $stored{'autodrop'} = $groupinfo{'autodrop'};   push(@{$stored{roles}},$role);
         if (exists($groupinfo{'autosec'})) {      }
             foreach my $role (sort(keys(%{$groupinfo{'autosec'}}))) {      foreach my $type (@{$groupinfo{'types'}}) {
                 foreach my $section (@{$groupinfo{'autosec'}{$role}}) {   push(@{$stored{types}},$type);
                     push (@{$stored{'sec_'.$role}},$section);      }
                 }      foreach my $section (@{$groupinfo{'sectionpick'}}) {
                 if (@{$groupinfo{'autosec'}{$role}} > 0) {   push(@{$stored{sectionpick}},$section);
                     push(@{$stored{'autorole'}},$role);      }
                 }      foreach my $defpriv (@{$groupinfo{'defpriv'}}) {
    push(@{$stored{defpriv}},$defpriv);
       }
       $stored{'autoadd'} = $groupinfo{'autoadd'};
       $stored{'autodrop'} = $groupinfo{'autodrop'};
       if (exists($groupinfo{'autosec'})) {
    foreach my $role (sort(keys(%{$groupinfo{'autosec'}}))) {
               if (ref($groupinfo{'autosec'}{$role}) eq 'ARRAY') {
           foreach my $section (@{$groupinfo{'autosec'}{$role}}) {
   
               push (@{$stored{'sec_'.$role}},$section);
           }
           if (@{$groupinfo{'autosec'}{$role}} > 0) {
       push(@{$stored{'autorole'}},$role);
           }
             }              }
         }   }
     }      }
     return %stored;      return %stored;
 }  }
   
 sub display_control {  sub display_control {
     my ($r,$cdom,$cnum,$tabcol,$action,$state,$page,$sectioncount,$groupname,      my ($r,$cdom,$cnum,$action,$state,$page,$sectioncount,$groupname,
         $description,$functions,$tools,$toolprivs,$fixedprivs,$startdate,          $description,$functions,$tools,$toolprivs,$fixedprivs,$startdate,
         $enddate,$users,$userdata,$idx,$memchg,$usertools,$function,          $enddate,$users,$userdata,$idx,$memchg,$usertools,
         $view_permission,$manage_permission,$stored,$granularity,$specificity,          $view_permission,$manage_permission,$stored,$granularity,$quota,
         $types,$roles,$sections,$states,$navbuttons,$rowColor1,$rowColor2)=@_;          $specificity,$types,$roles,$sections,$states,$navbuttons,
    $gpterm,$ucgpterm,$crstype) = @_;
     if ($action eq 'create') {      if ($action eq 'create') {
         if ($state eq 'pick_name') {          if ($state eq 'pick_name') {
             &general_settings_form($r,$cdom,$cnum,$action,$tabcol,$state,$page,              &general_settings_form($r,$cdom,$cnum,$action,$state,$page,
                                    $functions,$tools,$toolprivs,$fixedprivs,                                     $functions,$tools,$toolprivs,$fixedprivs,
                                    $sectioncount,$stored,$states,$navbuttons,                                     $sectioncount,$stored,$states,$navbuttons,
                                    $rowColor1,$rowColor2);                                     $gpterm,$ucgpterm,$crstype);
         } elsif ($state eq 'pick_members') {          } elsif ($state eq 'pick_members') {
             &choose_members_form($r,$cdom,$cnum,$tabcol,$action,$state,$page,              &choose_members_form($r,$cdom,$cnum,$action,$state,$page,
                                  $groupname,$description,$granularity,                                   $groupname,$description,$granularity,$quota,
                                  $startdate,$enddate,$tools,$fixedprivs,                                   $startdate,$enddate,$tools,$fixedprivs,
                                  $toolprivs,$functions,$users,$userdata,$idx,                                   $toolprivs,$functions,$users,$userdata,$idx,
                                  $stored,$states,$navbuttons,$rowColor1,                                   $stored,$states,$navbuttons,$gpterm,$ucgpterm,
                                  $rowColor2);   $crstype);
         } elsif ($state eq 'pick_privs') {          } elsif ($state eq 'pick_privs') {
             &choose_privs_form($r,$cdom,$cnum,$tabcol,$action,$state,$page,              &choose_privs_form($r,$cdom,$cnum,$action,$state,$page,
                                $startdate,$enddate,$tools,$functions,                                 $startdate,$enddate,$tools,$functions,
                                $toolprivs,$fixedprivs,$userdata,$usertools,                                 $toolprivs,$fixedprivs,$userdata,$usertools,
                                $idx,$states,$stored,$sectioncount,$navbuttons,                                 $idx,$states,$stored,$sectioncount,$navbuttons,
                                $rowColor1,$rowColor2);                                 $gpterm,$ucgpterm,$crstype);
         } elsif ($state eq 'result') {          } elsif ($state eq 'result') {
             &process_request($r,$cdom,$cnum,$tabcol,$action,$state,$page,              &process_request($r,$cdom,$cnum,$action,$state,$page,
                              $groupname,$description,$specificity,$userdata,                               $groupname,$description,$specificity,$userdata,
                              $startdate,$enddate,$tools,$functions,                               $startdate,$enddate,$tools,$functions,
                              $toolprivs,$usertools,$idx,$types,$roles,                               $toolprivs,$usertools,$idx,$types,$roles,
                              $sections,$states,$navbuttons,$memchg,                               $sections,$states,$navbuttons,$memchg,
                              $sectioncount,$stored,$rowColor1,$rowColor2);                               $sectioncount,$stored,$gpterm,$ucgpterm,$crstype);
         }          }
     } elsif ($action eq 'modify') {      } elsif ($action eq 'modify') {
         my $groupname = $env{'form.groupname'};          my $groupname = $env{'form.groupname'};
         if ($state eq 'pick_group') {          if ($state eq 'pick_task') {
             &display_groups($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,              &modify_menu($r,$groupname,$page,$gpterm);
                             $view_permission,$manage_permission,$action,  
                             $rowColor1,$rowColor2);  
         } elsif ($state eq 'pick_task') {  
             &modify_menu($r,$groupname,$page);  
         } elsif ($state eq 'change_settings') {          } elsif ($state eq 'change_settings') {
             &general_settings_form($r,$cdom,$cnum,$action,$tabcol,$state,$page,              &general_settings_form($r,$cdom,$cnum,$action,$state,$page,
                                    $functions,$tools,$toolprivs,$fixedprivs,                                     $functions,$tools,$toolprivs,$fixedprivs,
                                    $sectioncount,$stored,$states,$navbuttons,                                     $sectioncount,$stored,$states,$navbuttons,
                                    $rowColor1,$rowColor2);                                     $gpterm,$ucgpterm,$crstype);
         } elsif ($state eq 'change_members') {          } elsif ($state eq 'change_members') {
             &change_members_form($r,$cdom,$cnum,$tabcol,$action,$state,$page,              &change_members_form($r,$cdom,$cnum,$action,$state,$page,
                                  $groupname,$description,$startdate,$enddate,                                   $groupname,$description,$startdate,$enddate,
                                  $tools,$fixedprivs,$functions,$users,                                   $tools,$fixedprivs,$functions,$users,
                                  $userdata,$granularity,$specificity,$idx,                                   $userdata,$granularity,$quota,$specificity,
                                  $states,$navbuttons,$rowColor1,$rowColor2);                                   $idx,$states,$navbuttons,$gpterm,$ucgpterm);
         } elsif ($state eq 'add_members') {          } elsif ($state eq 'add_members') {
             &add_members_form($r,$tabcol,$action,$state,$page,$startdate,              &add_members_form($r,$cdom,$cnum,$action,$state,$page,$startdate,
                               $enddate,$groupname,$description,$granularity,                                $enddate,$groupname,$description,$granularity,
                               $sectioncount,$tools,$functions,$stored,$states,                                $quota,$sectioncount,$tools,$functions,$stored,
                               $navbuttons,$rowColor1,$rowColor2);                                $states,$navbuttons,$gpterm,$ucgpterm,$crstype);
         } elsif ($state eq 'pick_members') {          } elsif ($state eq 'pick_members') {
             &choose_members_form($r,$cdom,$cnum,$tabcol,$action,$state,$page,              &choose_members_form($r,$cdom,$cnum,$action,$state,$page,
                                  $groupname,$description,$granularity,                                   $groupname,$description,$granularity,$quota,
                                  $startdate,$enddate,$tools,$fixedprivs,                                   $startdate,$enddate,$tools,$fixedprivs,
                                  $toolprivs,$functions,$users,$userdata,$idx,                                   $toolprivs,$functions,$users,$userdata,$idx,
                                  $stored,$states,$navbuttons,$rowColor1,                                   $stored,$states,$navbuttons,$gpterm,$ucgpterm,
                                  $rowColor2);   $crstype);
         } elsif ($state eq 'pick_privs') {          } elsif ($state eq 'pick_privs') {
             &choose_privs_form($r,$cdom,$cnum,$tabcol,$action,$state,$page,              &choose_privs_form($r,$cdom,$cnum,$action,$state,$page,
                                $startdate,$enddate,$tools,$functions,                                 $startdate,$enddate,$tools,$functions,
                                $toolprivs,$fixedprivs,$userdata,$usertools,                                 $toolprivs,$fixedprivs,$userdata,$usertools,
                                $idx,$states,$stored,$sectioncount,$navbuttons,                                 $idx,$states,$stored,$sectioncount,$navbuttons,
                                $rowColor1,$rowColor2);                                 $gpterm,$ucgpterm,$crstype);
         } elsif ($state eq 'change_privs') {          } elsif ($state eq 'change_privs') {
             &change_privs_form($r,$cdom,$cnum,$tabcol,$action,$state,$page,              &change_privs_form($r,$cdom,$cnum,$action,$state,$page,
                                $startdate,$enddate,$tools,$functions,                                 $startdate,$enddate,$tools,$functions,
                                $toolprivs,$fixedprivs,$userdata,$usertools,                                 $toolprivs,$fixedprivs,$userdata,$usertools,
                                $memchg,$idx,$states,$stored,$sectioncount,                                 $memchg,$idx,$states,$stored,$sectioncount,
                                $navbuttons,$rowColor1,$rowColor2);                                 $navbuttons,$gpterm,$ucgpterm);
         } elsif ($state eq 'chgresult' || $state eq 'memresult' ||           } elsif ($state eq 'chgresult' || $state eq 'memresult' || 
                  $state eq 'addresult') {                   $state eq 'addresult') {
             &process_request($r,$cdom,$cnum,$tabcol,$action,$state,$page,              &process_request($r,$cdom,$cnum,$action,$state,$page,
                              $groupname,$description,$specificity,$userdata,                               $groupname,$description,$specificity,$userdata,
                              $startdate,$enddate,$tools,$functions,                               $startdate,$enddate,$tools,$functions,
                              $toolprivs,$usertools,$idx,$types,$roles,                               $toolprivs,$usertools,$idx,$types,$roles,
                              $sections,$states,$navbuttons,$memchg,                               $sections,$states,$navbuttons,$memchg,
                              $sectioncount,$stored,$rowColor1,$rowColor2);                               $sectioncount,$stored,$gpterm,$ucgpterm,$crstype);
           }
       } elsif ($action eq 'delete') {
           my %stored = &retrieve_settings($cdom,$cnum,$groupname,$action);
           if ($state eq 'verify') {
               &verify_delete($r,$groupname,$state,$action,$page,$states,
                              \%stored,$crstype);
           } elsif ($state eq 'result') {
               &delete_group($r,$cdom,$cnum,$groupname,$crstype);
           }
       } elsif ($action eq 'reenable') {
           my %stored = &retrieve_settings($cdom,$cnum,$groupname,$action);
           if ($state eq 'verify') {
               &verify_reenable($r,$groupname,$state,$action,$page,$states,
                              \%stored,$crstype);
           } elsif ($state eq 'result') {
               &reenable_group($r,$cdom,$cnum,$groupname,$crstype);
           }
       }
   }
   
   sub verify_delete {
       my ($r,$groupname,$formname,$action,$page,$states,$stored,$crstype) = @_;
       $r->print(&Apache::lonhtmlcommon::echo_form_input([]));
       $r->print(&mt('You have requested deletion of the group [_1].'
                    ,'<i>'.$stored->{'description'}.'</i>').
                 '<br /><br />'.&mt('When a group is deleted the following occurs:').'<ul>'.
                 '<li>'.&mt('All group membership is terminated.').'</li>'.
                 '<li>'.&mt('The group ceases to be available either for viewing or for modification of group settings and membership.').'</li>');
       if ($crstype eq 'Community') {
           $r->print( '<li>'.&mt("The group folder is removed from the folder containing it - normally this is the 'Community Groups' folder which contains folders for all groups in the community.").'</li>'.
                      '</ul>'.&mt("Although a deleted group is no longer accessible, the group name used for the group will be reserved, and will not be available for assignment to a new group in the same community in the future."));
       } else { 
           $r->print( '<li>'.&mt("The group folder is removed from the folder containing it - normally this is the 'Course Groups' folder which contains folders for all groups in the course.").'</li>'.
                      '</ul>'.&mt("Although a deleted group is no longer accessible, the group name used for the group will be reserved, and will not be available for assignment to a new group in the same course in the future."));
       }
       my $prevtext = &mt('Go back');
       my $nexttext = &mt('Delete group');
       my $prev;
       if ($env{'form.refpage'} eq 'cusr')  {
           $prev = 'view';
       }
       &display_navbuttons($r,$formname,$prev,$prevtext,
                           $$states{$action}[$page+1],$nexttext);
       return;
   }
   
   sub delete_group {
       my ($r,$cdom,$cnum,$groupname,$crstype) = @_;
       my %membership = &Apache::lonnet::get_group_membership($cdom,$cnum,
                                                              $groupname);
       my $now = time;
       my $num_users = 0;
       my $num_fail = 0;
       my $num_ok = 0;
       my @deleted;
       my @undeleted;
       my %usersettings;
       my $context = 'deletegroup';
       foreach my $key (sort(keys(%membership))) {
           if ($key =~ /^\Q$groupname\E:([^:]+:[^:]+)$/) {
               my $user = $1;
               my($end,$start,$userprivs) = split(/:/,$membership{$key},3);
               if ($start != -1) {
                   $num_users ++;
                   $usersettings{$groupname.':'.$user} = $now.':-1:'.$userprivs;
                   if (&Apache::lonnet::modify_group_roles($cdom,$cnum,
                                                           $groupname,$user,
                                                           $now,'-1',$userprivs,
                                                           '',$context)
                       eq 'ok') {
                       $num_ok ++;
                       push(@deleted,$user);
                   } else {
                       push(@undeleted,$user);
                       $num_fail ++;
                   }
               }
           }
       }
       if ($num_ok > 0) {
           my $roster_result = 
               &Apache::lonnet::modify_coursegroup_membership($cdom,$cnum,
                                                              \%usersettings);
       }
       if ($num_fail > 0) {
           $r->print('<div class="LC_error">'
                    .&mt('Group deletion failed because deletion of [_1] out of [_2] members failed.'
                        ,$num_fail,$num_users)
                    .'</div>');
       } else {
           my ($result,$message) = 
                &Apache::lonnet::toggle_coursegroup_status($cdom,$cnum,
                                                           $groupname,'delete');
           if ($result eq 'ok') {
               my $outcome = &modify_folders($cdom,$cnum,$groupname,$crstype);
               if ($outcome eq '') {
                   my $message = &Apache::lonhtmlcommon::confirm_success(&mt('Group successfully deleted.'));
                   $message = &Apache::loncommon::confirmwrapper($message);
                   $r->print($message);
               } else {
                   $r->print('<div class="LC_error">');
                   if ($crstype eq 'Community') {
                       $r->print(&mt("Although the group was deleted, an error occurred when removing the group's folder from the 'Community Groups' folder: [_1]",$outcome));
                   } else {
                       $r->print(&mt("Although the group was deleted, an error occurred when removing the group's folder from the 'Course Groups' folder: [_1]",$outcome));
                   }
                   $r->print('</div>');
               }
           } else {
               my $msg = &Apache::lonhtmlcommon::confirm_success(&mt('Group deletion failed.'),1);
               $msg = &Apache::loncommon::confirmwrapper($msg);
               $r->print($msg);
           }
       }
       return;
   }
   
   sub reenable_folder {
       my ($cdom,$cnum,$groupname,$description,$crstype) = @_;
       my $outcome;
       my $crspath = '/uploaded/'.$cdom.'/'.$cnum.'/';
       my $allgrpsmap = $crspath.'group_allfolders.sequence';
       my $foldertitle;
       if ($crstype eq 'Community') {
           $foldertitle = &mt("Community Folder -[_1]",$description);
       } else {
           $foldertitle = &mt("Course Folder -[_1]",$description);
       }
       my $mapurl = $crspath.'group_folder_'.
                      $groupname.'.sequence';
       my ($errtext,$fatal)=&LONCAPA::map::mapread($allgrpsmap);
       if ($fatal) {
           $outcome='<div class="LC_error">'
                   .&mt('An error occurred when reading contents of parent folder to group:')
                   ."<br />($allgrpsmap): $errtext"
                   .'</div>';
       } else {
           my $idx=&LONCAPA::map::getresidx($mapurl);
           $LONCAPA::map::resources[$idx] = $foldertitle.':'.$mapurl.
                                            ':false:normal:res';
           $LONCAPA::map::order[1+$#LONCAPA::map::order]=$idx;
           my ($outtext,$errtext) = &LONCAPA::map::storemap($allgrpsmap,1,1);
           if ($errtext) {
               $outcome='<div class="LC_error">'
                       .&mt('An error occurred when saving updated parent folder to group:'
                           ,"<br />$allgrpsmap - $errtext")
                       .'</div>';
           } else {
               my ($furl,$ferr) =
                        &Apache::lonuserstate::readmap($cdom.'/'.$cnum);
           }
       }
       return $outcome;
   }
   
   sub modify_folders {
       my ($cdom,$cnum,$groupname,$crstype) = @_;
       my ($outcome,$groupmap,$groupmapres,$map,$id,$src);
       my $navmap = Apache::lonnavmaps::navmap->new();
       if (!defined($navmap)) {
           $outcome = '<div class="LC_error">';
           if ($crstype eq 'Community') {
               $outcome .= &mt("Error reading community contents.").' '.
                      &mt("You need to re-initialize the community.");
           } else {
               $outcome .= &mt("Error reading course contents.").' '.
                      &mt("You need to re-initialize the course.");
           }
           $outcome .= '</div>';
           return $outcome;
       }
       $groupmap = '/uploaded/'.$cdom.'/'.$cnum.'/'.'group_folder_'.
                      $groupname.'.sequence';
       $groupmapres = $navmap->getResourceByUrl($groupmap);
       if ($groupmapres) {
           ($map,$id,$src)=&Apache::lonnet::decode_symb($groupmapres->symb());
       }
       undef($navmap);
       if ($map) {
           $map = '/'.$map;
           my ($errtext,$fatal) = &LONCAPA::map::mapread($map);
           if ($fatal) {
               $outcome='<div class="LC_error">'
                       .&mt('An error occurred when reading contents of parent folder to group:')
                       ."<br />($map): $errtext"
                       .'</div>';
           } else {
               my $idx = 0;
               my $grpidx;
               foreach my $item (@LONCAPA::map::order) {
                   my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$item]);
                   $url=&LONCAPA::map::qtescape($url);
                   if ($url eq $groupmap) {
                       $grpidx = $idx;
                       last;
                   } else {
                       $idx++;
                   }
               }
   
               if ($grpidx ne '') {
                   &LONCAPA::map::makezombie($LONCAPA::map::order[$grpidx]);
                   for (my $i=$grpidx;$i<$#LONCAPA::map::order;$i++) {
                       $LONCAPA::map::order[$i] = $LONCAPA::map::order[$i+1];
                   }
                   $#LONCAPA::map::order--;
                   my ($outtext,$errtext) = &LONCAPA::map::storemap($map,1,1);
                   if ($errtext) {
                       $outcome='<div class="LC_error">'
                               .&mt('An error occurred when saving updated parent folder to group:')
                               ."<br />$map - $errtext"
                               .'</div>';
                   } else {
                       my ($furl,$ferr) =
                           &Apache::lonuserstate::readmap($cdom.'/'.$cnum);
                   }  
               }
         }          }
     }      }
       return $outcome;
   }
   
   sub verify_reenable {
       my ($r,$groupname,$formname,$action,$page,$states,$stored,$crstype) = @_;
       $r->print(&Apache::lonhtmlcommon::echo_form_input([]));
       $r->print(&mt('You have requested enabling the previously deleted group [_1].'
                    ,'<i>'.$stored->{'description'}.'</i>').
                 '<br /><br />'.&mt('When a deleted group is re-enabled the following occurs:').'<ul>'.
                 '<li>'.&mt('Group settings and membership at the time the group was deleted are reinstated.').'</li><li>');
       if ($crstype eq 'Community') {
           $r->print(&mt("A group folder is added to the 'Community Groups' folder which contains folders for all groups in the community."));
       } else {
           $r->print(&mt("A group folder is added to the 'Course Groups' folder which contains folders for all groups in the course."));
       }
       $r->print('</li></ul>');
       my $prevtext = &mt('Go back');
       my $nexttext = &mt('Reenable group');
       my $prev;
       if ($env{'form.refpage'} eq 'cusr')  {
           $prev = 'view';
       }
       &display_navbuttons($r,$formname,$prev,$prevtext,
                           $$states{$action}[$page+1],$nexttext);
       return;
   }
   
   sub reenable_group {
       my ($r,$cdom,$cnum,$groupname,$crstype) = @_;
       my %groups = 
           &Apache::longroup::coursegroups($cdom,$cnum,$groupname,
                                           'deleted_groups');
       if (keys(%groups) == 0) {
           $r->print(&mt('The group [_1] was not re-enabled, because it is not a deleted group.[_2]Perhaps it has already been re-enabled?','<i>'.$groupname.'</i>'),'<br />');
           return;
       }
       my %groupinfo = 
           &Apache::longroup::get_group_settings($groups{$groupname});
       my $defstart = $groupinfo{'startdate'};
       my $defend = $groupinfo{'enddate'};
       my $showstart = &Apache::lonlocal::locallocaltime($defstart);
       my $showend;
       if ($defend == 0) {
           $showend = &mt('No end date set');
       } else {
           $showend = &Apache::lonlocal::locallocaltime($defend);
       }
       my $description = &unescape($groupinfo{'description'});
       my $num_users = 0;
       my $num_ok = 0;
       my $num_fail = 0;
       my $context = 'reenablegroup';
       my (%usersettings,@enabled,@unenabled);
       my ($result,$message) =
             &Apache::lonnet::toggle_coursegroup_status($cdom,$cnum,$groupname,
                                                        'reenable');
       if ($result eq 'ok') {
           my %membership = &Apache::lonnet::get_group_membership($cdom,$cnum,
                                                              $groupname);
           foreach my $key (sort(keys(%membership))) {
               if ($key =~ /^\Q$groupname\E:([^:]+:[^:]+)$/) {
                   my $user = $1;
                   my($end,$start,$userprivs) = split(/:/,$membership{$key},3);
                   if (($start == -1) && ($end == $groupinfo{'modified'})) {
                       $num_users ++;
                       $usersettings{$groupname.':'.$user} = $defend.':'.
                                                             $defstart.':'.
                                                             $userprivs;
                       if (&Apache::lonnet::modify_group_roles($cdom,$cnum,
                                                               $groupname,$user,
                                                               $defend,$defstart,
                                                               $userprivs,'',
   $context) eq 'ok') {
                           $num_ok ++;
                           push(@enabled,$user);
                       } else {
                           push(@unenabled,$user);
                           $num_fail ++;
                       }
                   }
               }
           }
           if ($num_users > 0) {
               if ($num_ok > 0) {
                   my $roster_result =
           &Apache::lonnet::modify_coursegroup_membership($cdom,$cnum,
                                                          \%usersettings);
                   if ($roster_result eq 'ok') {
                       $r->print('<div class="LC_success">'
                                .&mt('Membership reinstated for [quant,_1,user], each with start and end dates for group access set to defaults: [_2] and [_3]',$num_ok,$showstart,$showend)
                                .'</div>');
                   }
               } else {
                   $r->print('<div class="LC_error">'
                            .&mt('A problem occurred when trying to reinstate [_1] of the [_2] members of the pre-existing group.',$num_fail,$num_users)
                            .'</div>');
               }
           } else {
               $r->print('<div class="LC_info">'
                        .&mt('There were no group members to reinstate, as none were removed when the group was deleted.')
                        .'</div>');
           }
           my $outcome = &reenable_folder($cdom,$cnum,$groupname,$description,$crstype);
           if ($outcome eq '') {
               my $message = &Apache::lonhtmlcommon::confirm_success(&mt('Group successfully re-enabled.'));
               $message = &Apache::loncommon::confirmwrapper($message);
               $r->print($message);
           } else {
               $r->print('<div class="LC_error">');
               if ($crstype eq 'Community') {
                   $r->print(&mt("Although the group was re-enabled, an error occurred when adding the group's folder to the 'Community Groups' folder: [_1]",$outcome));
               } else {
                   $r->print(&mt("Although the group was re-enabled, an error occurred when adding the group's folder to the 'Course Groups' folder: [_1]",$outcome));
               }
               $r->print('</div>');
           }
       } else {
           my $message = &Apache::lonhtmlcommon::confirm_success(&mt('Re-enabling group failed.'),1);
           $message = &Apache::loncommon::confirmwrapper($message);
           $r->print($message);
       }
       return;
 }  }
   
 sub header {  sub header {
     my ($bodytitle,$jscript,$action,$state,$page,$function,$loaditems) = @_;      my ($bodytitle,$jscript,$action,$state,$page,$loaditems) = @_;
     my $start_page=      my $start_page=
  &Apache::loncommon::start_page($bodytitle,$jscript,   &Apache::loncommon::start_page($bodytitle,
        {'function' => $function,         '<script type="text/javascript">'.
  'add_entries' => $loaditems,});         $jscript.'</script>',
          {'add_entries' => $loaditems,});
     my $output = <<"END";      my $output = <<"END";
 $bodytag  $start_page
 <form method="POST" name="$state">  <form method="post" name="$state" action="">
   
 END  END
     if ($action eq 'create' || $action eq 'modify') {      if ($action eq 'create' || $action eq 'modify') {
Line 973  END Line 1541  END
   
 sub onload_action {  sub onload_action {
     my ($action,$state) = @_;      my ($action,$state) = @_;
     my $loaditems;      my %loaditems;
     if ((defined($env{'form.origin'})) && ($action eq 'create') &&      if ((defined($env{'form.origin'})) && ($action eq 'create') &&
                 ($state eq 'pick_name' || $state eq 'pick_members' ||                   ($state eq 'pick_name' || $state eq 'pick_members' || 
                  $state eq 'pick_privs')) {                   $state eq 'pick_privs')) {
         unless ($env{'form.origin'} eq '') {          unless ($env{'form.origin'} eq '') {
             $loaditems =       $loaditems{'onload'} = 
              'onload="javascript:setFormElements(document.'.$state.')"';   'javascript:setFormElements(document.'.$state.')';
         }          }
     }      }
     if (($action eq 'modify') &&      if (($action eq 'modify') &&
                 ($state eq 'change_settings' || $state eq 'change_members' ||                  ($state eq 'change_settings' || $state eq 'change_members' ||
                  $state eq 'change_privs' || $state eq 'add_members' ||                   $state eq 'change_privs' || $state eq 'add_members')) {
                  $state eq 'pick_members')) {   $loaditems{'onload'} = 
             $loaditems =      'javascript:setFormElements(document.'.$state.')';
              'onload="javascript:setFormElements(document.'.$state.')"';  
     }      }
     return $loaditems;      return \%loaditems;
 }  }
   
 sub footer {  sub footer {
Line 1016  sub build_members_list { Line 1583  sub build_members_list {
 }  }
   
 sub group_files {  sub group_files {
       my ($group,$portpath,$numfiles,$numdirs) = @_;
       my $dirptr=16384;
       my ($dirlistref,$listerror) = 
           &Apache::portfolio::get_dir_list($portpath,undef,$group);
       if (ref($dirlistref) eq 'ARRAY') {
           foreach my $line (@{$dirlistref}) {
               my ($filename,$dom,undef,$testdir,undef,undef,undef,undef,$size,undef,$mtime,undef,undef,undef,$obs,undef)=split(/\&/,$line,16);
               if (($filename !~ /^\.\.?$/) && ($filename !~ /\.meta$/ ) && ($filename !~ /(.*)\.(\d+)\.([^\.]*)$/) && ($filename ne 'no_such_dir')) { 
                   if ($dirptr&$testdir) {
                       $portpath .= '/'.$filename;
                       $$numdirs ++;
                       &group_files($group,$portpath,$numfiles,$numdirs)
                   } else {
                       $$numfiles ++;
                   }
               }
           }
       }
     return;      return;
 }  }
   
Line 1023  sub group_members { Line 1608  sub group_members {
     my ($cdom,$cnum,$group,$group_info) = @_;      my ($cdom,$cnum,$group,$group_info) = @_;
     my %memberhash = &Apache::lonnet::get_group_membership($cdom,$cnum,$group);      my %memberhash = &Apache::lonnet::get_group_membership($cdom,$cnum,$group);
     my $now = time;      my $now = time;
     my ($tmp)=keys(%memberhash);      my %lt = &Apache::lonlocal::texthash (
     if ($tmp=~/^error:/) {                                            active => 'active',
         $$group_info{'totalmembers'} = 'Unknown - an error occurred';                                            previous => 'previous',
         return $tmp;                                            future => 'future',
     }      );
     my $now = time;      my %membercounts = (  
                            active => 0,
                            previous => 0,
                            future => 0,
                          );
     my $totalmembers = 0;      my $totalmembers = 0;
     my $active = 0;      foreach my $member (keys(%memberhash)) {
     my $previous = 0;  
     my $future = 0;  
     foreach my $member (keys %memberhash) {  
         $totalmembers ++;          $totalmembers ++;
         my ($end,$start) = split(/:/,$memberhash{$member});          my ($end,$start) = split(/:/,$memberhash{$member});
         unless ($start == -1) {          unless ($start == -1) {
             if (($end!=0) && ($end<$now)) {              if (($end!=0) && ($end<$now)) {
                 $previous ++;                  $membercounts{previous} ++;
             } elsif (($start!=0) && ($start>$now)) {              } elsif (($start!=0) && ($start>$now)) {
                 $future ++;                  $membercounts{future} ++;
             } else {              } else {
                $active ++;                  $membercounts{active} ++;
             }              }
         }          }
     }      }
     if ($totalmembers == 0) {      if ($totalmembers == 0) {
         $$group_info{$group}{'totalmembers'} = 'None';          $$group_info{$group}{'totalmembers'} = 'None';
     } else {      } else {
         $$group_info{$group}{'totalmembers'} = $active.' - active<br />'.$previous.' -previous<br />'.$future.' -future';          foreach my $type ('active','previous','future') {
               $$group_info{$group}{'totalmembers'} .= 
                  &open_list_window($group,$type,$membercounts{$type},$lt{$type});
           }
     }      }
     return 'ok';      return 'ok';
 }  }
   
   sub open_list_window {
       my ($group,$status,$count,$text) = @_;
       my $entry;
       if ($count > 0) {
           $entry = '<span class="LC_nobreak"><a href="javascript:openGroupRoster('.
                    "'$group','$status'".')">'.$text.'</a>&nbsp;-&nbsp;'.$count.
                    '</span><br />';
       } else {
           $entry = '<span class="LC_nobreak">'.$text.'&nbsp;-&nbsp;'.$count.'</span><br />';
       }
       return $entry;
   }
   
   
 sub general_settings_form {  sub general_settings_form {
     my ($r,$cdom,$cnum,$action,$tabcol,$formname,$page,$functions,$tools,      my ($r,$cdom,$cnum,$action,$formname,$page,$functions,$tools,
         $toolprivs,$fixedprivs,$sectioncount,$stored,$states,$navbuttons,          $toolprivs,$fixedprivs,$sectioncount,$stored,$states,$navbuttons,
         $rowColor1,$rowColor2) = @_;          $gpterm,$ucgpterm,$crstype) = @_;
     my ($nexttext,$prevtext);      my ($nexttext,$prevtext);
     $r->print(' <br />      &groupsettings_options($r,$functions,$action,$formname,$stored,1,
  <table width="100%" cellpadding="0" cellspacing="0" border="0">                             $gpterm,$ucgpterm,$crstype);
 ');      &access_date_settings($r,$action,$formname,$stored,2,$gpterm,$ucgpterm);
     &groupsettings_options($r,$tabcol,$functions,$action,$formname,$stored,1);  
     $r->print('   
   <tr>  
    <td colspan="4">&nbsp;</td>  
   </tr>');  
     &access_date_settings($r,$tabcol,$action,$formname,$stored,2);  
     $r->print('  
   <tr>  
    <td colspan="4">&nbsp;</td>  
   </tr>');  
     if ($action eq 'create') {      if ($action eq 'create') {
         &membership_options($r,$action,$formname,$tabcol,$sectioncount,3);          &membership_options($r,$cdom,$cnum,$action,$formname,$sectioncount,3,
                               $gpterm,$ucgpterm,$crstype);
         $nexttext = $$navbuttons{'gtns'};          $nexttext = $$navbuttons{'gtns'};
     } else {      } else {
         my @available = ();          my @available = ();
         my @unavailable = ();          my @unavailable = ();
         &check_tools($functions,$tools,\@available,\@unavailable);          &check_tools($functions,$tools,\@available,\@unavailable);
         @{$tools} = sort(keys(%{$functions}));          @{$tools} = sort(keys(%{$functions}));
         &privilege_specificity($r,$tabcol,$rowColor1,$rowColor2,$action,          &privilege_specificity($r,$action,3,$tools,$stored,$toolprivs,
                                3,$tools,$stored,$toolprivs,$fixedprivs,         $fixedprivs,\@available,$formname,
                                \@available,$formname);         $gpterm,$ucgpterm,$functions,$crstype);
         $r->print('          &mapping_options($r,$action,$formname,$page,$sectioncount,
   <tr>                           $states,$stored,$navbuttons,4,5,
    <td colspan="4">&nbsp;</td>   $gpterm,$ucgpterm,$crstype,$cdom,$cnum);
   </tr>');  
         &mapping_options($r,$action,$formname,$page,$tabcol,$sectioncount,  
                          $states,$stored,$navbuttons,4,5,$rowColor1,  
                          $rowColor2);  
         $nexttext = $$navbuttons{'mose'};          $nexttext = $$navbuttons{'mose'};
     }      }
     $prevtext = $$navbuttons{'gtpp'};      $prevtext = $$navbuttons{'gtpp'};
     &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext,      &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext,
                         $$states{$action}[$page+1],$nexttext);                          $$states{$action}[$page+1],$nexttext);
     $r->print('  
  </table>');  
     return;      return;
 }  }
   
 sub groupsettings_options {  sub groupsettings_options {
     my ($r,$tabcol,$functions,$action,$formname,$stored,$image) = @_;      my ($r,$functions,$action,$formname,$stored,$image,$gpterm,
           $ucgpterm,$crstype) = @_;
     my %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
         'gdat' => 'Group open and close dates',          'gdat' => "Group access start and end dates",
         'sten' => 'Set a start date/time and end date/time for the group',          'gnde' => "Group name, title and available collaborative tools",
         'gfun' => 'Group functionality',          'desc' => 'Group Title',
         'gnde' => 'Group name, description and available functionality',          'func' => 'Collaborative Tools',
         'desc' => 'Description',  
         'func' => 'Functionality',  
         'gnam' => 'Group Name',          'gnam' => 'Group Name',
         'doyo' => 'Do you want to assign different functionality '.          'lett' => 'Letters, numbers and underscore only',
                   'to different group members?',          'doyo' => 'Different subsets of the chosen collaborative tools '.
                     'for different group members?',
           'gran' => 'Granularity',
           'dquo' => 'Disk quota',
       );
       my ($crsquota,$freespace,$maxposs) = &get_quota_constraints($action,$stored);
       $r->print(&Apache::lonhtmlcommon::topic_bar($image,$lt{'gnde'}));
   
       # Group Name
       $r->print(&Apache::lonhtmlcommon::start_pick_box()
                .&Apache::lonhtmlcommon::row_title($lt{'gnam'})
     );      );
     &topic_bar($r,$tabcol,$image,$lt{'gnde'});  
     $r->print('  
    <tr>  
     <td>&nbsp;</td>  
     <td colspan="3">  
      <table border="0" cellpadding="2" cellspacing="2">  
       <tr>  
        <td><b>'.$lt{'gnam'}.':</b></td>  
        <td colspan="5">  
 ');  
     if ($action eq 'create') {      if ($action eq 'create') {
         $r->print('<input type="text" name="groupname" size="25" />');          $r->print('<input type="text" name="groupname" size="25" />'
                    .' <span class="LC_nobreak">('
                    .$lt{'lett'}.')</span>'
           );
     } else {      } else {
         $r->print('<input type="hidden" name="groupname" value="'.          $r->print('<input type="hidden" name="groupname" value="'.
                          $env{'form.groupname'}.'" />'.$env{'form.groupname'});                           $env{'form.groupname'}.'" />'.$env{'form.groupname'});
     }      }
     $r->print(<<"END");      $r->print(&Apache::lonhtmlcommon::row_closure());
        </td>  
       <tr>      # Group Title
       <tr>      $r->print(&Apache::lonhtmlcommon::row_title($lt{'desc'})
        <td><b>$lt{'desc'}:</b></td>               .'<input type="text" name="description" size="40" value="" />'
        <td colspan="5"><input type="text" name="description" size="40"               .&Apache::lonhtmlcommon::row_closure()
                                                     value="" />      );
        </td>  
       <tr>      # Collaborative Tools
       <tr>  
        <td><b>$lt{'func'}:</b></td>  
 END  
     my $numitems = keys(%{$functions});      my $numitems = keys(%{$functions});
     my $halfnum = int($numitems/2);      my $halfnum = int($numitems/2);
     my $remnum = $numitems%2;      my $remnum = $numitems%2;
     if ($remnum) {      if ($remnum) {
         $halfnum ++;          $halfnum ++;
     }      }
     my @allfunctions = sort(keys (%{$functions}));      my @allfunctions = sort(keys(%{$functions}));
     for (my $i=0; $i<$halfnum; $i++) {  
         $r->print('<td><label><input type="checkbox" name="tool" value="'.      $r->print(&Apache::lonhtmlcommon::row_title($lt{'func'})
                   $allfunctions[$i].'" />&nbsp;'.               .'<div>'
                    $$functions{$allfunctions[$i]}.'</label></td>               .'<input type="button" value="'.&mt('check all').'"'
                    <td>&nbsp;</td><td>&nbsp;</td>');               .' onclick="javascript:checkAll(document.'.$formname.'.tool)" />'
     }               .'&nbsp;<input type="button" value="'.&mt('uncheck all').'"'
     $r->print('<td><input type="button" value="check all" '.               .' onclick="javascript:uncheckAll(document.'.$formname.'.tool)" />'
               'onclick="javascript:checkAll(document.'.$formname.'.tool)" />'.               .'</div>'
               '</td></tr><tr><td>&nbsp;</td>');               .'<table cellpadding="5px"><tr>' # FIXME Get rid of inflexible table (-> float)
     for (my $j=$halfnum; $j<@allfunctions; $j++) {      );
         $r->print('<td><label><input type="checkbox" name="tool" value="'.      for (my $i=0; $i<@allfunctions; $i++) {
                   $allfunctions[$j].'" />&nbsp;'.          $r->print('<td><label><span class="LC_nobreak">'
                   $$functions{$allfunctions[$j]}.'</label></td>                   .'<input type="checkbox" name="tool" value="'
                   <td>&nbsp;</td><td>&nbsp;</td>');                   .$allfunctions[$i].'" /> '
     }                   .&mt($$functions{$allfunctions[$i]})
     if ($remnum) {                   .'</span></label></td>'
         $r->print('<td>&nbsp;</td>');          );
           if ($i == $halfnum - 1) {
               $r->print('</tr><tr>');
           }
     }      }
     $r->print('      $r->print('</tr></table>'
        <td>               .&Apache::lonhtmlcommon::row_closure()
         <input type="button" value="uncheck all"      );
           onclick="javascript:uncheckAll(document.'.$formname.'.tool)" />  
        </td>      # Granularity
       </tr>      $r->print(&Apache::lonhtmlcommon::row_title($lt{'gran'})
       <tr>               .$lt{'doyo'}.'<br />'
        <td><b>Granularity:</b></td>               .'<label>'
        <td colspan="9">'.$lt{'doyo'}.'&nbsp;<label><input type="radio" name="granularity" value="Yes" />'.&mt('Yes').'</label>&nbsp;<label><input type="radio" name="granularity" value="No" checked="checked" />'.&mt('No').'</label>');               .'<input type="radio" name="granularity" value="Yes" />'.&mt('Yes')
                .'</label>&nbsp;<label>'
                .'<input type="radio" name="granularity" value="No" checked="checked" />'.&mt('No')
                .'</label>'
       );
     if ($action eq 'modify') {      if ($action eq 'modify') {
         $r->print('&nbsp;&nbsp;('.&mt('Currently set to "[_1]"',          $r->print(' <span class="LC_nobreak">('
                                       $$stored{'granularity'}).')');                   .&mt('Currently set to [_1].'
                        ,'"'.&mt($$stored{'granularity'}).'"')
                    .')</span>'
           );
     }      }
     $r->print('      $r->print(&Apache::lonhtmlcommon::row_closure());
        </td>  
       </tr>      # Disk Quota
      </table>      $r->print(&Apache::lonhtmlcommon::row_title($lt{'dquo'}));
     </td>      if ($action eq 'create') {
    </tr>          $r->print('<span class="LC_info">'
 ');                   .&mt('If you enable the group portfolio for the '.$gpterm
                        .', allocate a disk quota.')
                    .'</span>'
           );
       } else {
           $r->print(&mt('Quota allocated to group portfolio:'));
       } 
       $r->print(' '.&mt('[_1] MB','<input type="text" name="quota" size="4" />'));
       if ($action eq 'create') {
           $r->print('<br />'
                    .&mt('A total of [_1] MB can be divided amongst all '.$gpterm.'s in the '
                        .lc($crstype).', and [_2] MB are currently unallocated.'
                        ,$crsquota,sprintf("%.2f",$freespace))
                    );
       } else {
           $r->print('&nbsp;&nbsp;('.&mt('The quota is currently [_1] MB',
                                         $$stored{'quota'}).').');
   
           $r->print('<br />'
                    .&mt('The quota can be increased to [_1] MB, '
                    .'by adding all unallocated space for '.$gpterm.'s in the '.lc($crstype).'.'
                     ,sprintf("%.2f",$maxposs)));
       }
       $r->print(&Apache::lonhtmlcommon::row_closure(1));
   
       $r->print(&Apache::lonhtmlcommon::end_pick_box());
   
     return;      return;
 }  }
   
   sub get_quota_constraints {
       my ($action,$stored) = @_;
       my ($crsquota,$freespace,$maxposs); 
       $crsquota = $env{'course.'.$env{'request.course.id'}.'.internal.coursequota'};
       if ($crsquota eq '') {
           $crsquota = 20;
       }
       $freespace = $crsquota - &Apache::longroup::sum_quotas();
       if ($action eq 'create') {
           $maxposs = $freespace;
       } else {
           $maxposs = $$stored{'quota'} + $freespace;
       }
       return ($crsquota,$freespace,$maxposs);
   }
   
 sub membership_options {  sub membership_options {
     my ($r,$action,$state,$tabcol,$sectioncount,$image) = @_;      my ($r,$cdom,$cnum,$action,$state,$sectioncount,$image,$gpterm,$ucgpterm,$crstype)=@_;
     my %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
                 'pipa' => 'Pick parameters to generate membership list',                  'pipa' => 'Build a list of users for selection of group members',
                 'gmem' => 'Group membership options',                  'gmem' => 'Group membership selection list criteria:',
                 'picr' => 'Pick the criteria to use to build a list of '.                  'picr' => 'Pick the criteria to use to build a list of course users from which you will select members of the new group.',
                           'course users from which you will select ',                  'pica' => 'Pick the criteria to use to build a list of course users from which you will select additional members of the group.',
                 'meof' => 'members of the new group.',                  'ifno' => 'If you do not wish to add members when you first create the group, there is no need to pick any criteria.', 
                 'admg' => 'additional members of the group.',  
                 'ifno' => 'If you do not wish to add members when you first '.  
                           'create the group, do not make any selections',    
                 'acty' => 'Access types',                  'acty' => 'Access types',
                 'coro' => 'Course roles',                  'coro' => 'Course roles',
                 'cose' => 'Course sections',                  'cose' => 'Course sections',
              );               );
       if ($crstype eq 'Community') {
           $lt{'picr'} = &mt('Pick the criteria to use to build a list of community participants from which you will select ');
           $lt{'asub'} = &mt('A subsequent step will also allow you to specify automatic adding/dropping of group members triggered by specified user role and section [_1]changes[_2] in the course.','<i>','</i>');
           $lt{'coro'} = &mt('Community roles');
           $lt{'cose'} = &mt('Community sections');
       } else {
           $lt{'asub'} = &mt('A subsequent step will also allow you to specify automatic adding/dropping of group members triggered by specified user role and section [_1]changes[_2] in the course.','<i>','</i>');
       }
     my %status_types = (      my %status_types = (
                    active => &mt('Currently has access'),                     active => &mt('Currently has access'),
                    previous => &mt('Previously had access'),                     previous => &mt('Previously had access'),
                    future => &mt('Will have future access'),                     future => &mt('Will have future access'),
                    );                     );
                                                                                    
     my @roles = ('st','cc','in','ta','ep','cr');      my @roles = ('st');
       if ($crstype eq 'Community') {
           push(@roles,'co');
       } else {
           push(@roles,'cc');
       }
       push (@roles,('in','ta','ep','ad','cr'));
   
     my @sections = keys(%{$sectioncount});      my @sections = keys(%{$sectioncount});
   
     &topic_bar($r,$tabcol,$image,$lt{'pipa'});      $r->print(&Apache::lonhtmlcommon::topic_bar($image,$lt{'pipa'}).'
     $r->print('       <b>'.$lt{'gmem'}.'</b><br />');
    <tr>  
     <td>&nbsp;</td>  
     <td colspan="3">  
      <b>'.$lt{'gmem'}.'</b><br/>'.$lt{'picr'});  
     if ($action eq 'create') {      if ($action eq 'create') {
         $r->print($lt{'meof'}.'<br />'.$lt{'ifno'});          $r->print($lt{'picr'}.'<br />'.$lt{'ifno'}.'<br />'.$lt{'asub'});
     } else {      } else {
         $r->print($lt{'admg'});          $r->print($lt{'pica'});
     }      }
     $r->print('      $r->print('
      <br />       <br />
      <br />       <br />
      <table border="0">       <table class="LC_status_selector">
       <tr>        <tr>
        <td><b>'.$lt{'acty'}.'</b></td>         <th>'.$lt{'acty'}.'</th>
        <td>&nbsp;</td>         <th>'.$lt{'coro'}.'</th>
        <td><b>'.$lt{'coro'}.'</b></td>');         <th>'.$lt{'cose'}.'</th>
     if (@sections >0) {        </tr><tr><td>');
         $r->print('  
        <td>&nbsp;</td>  
        <td><b>'.$lt{'cose'}.'</b></td>  
        <td>&nbsp;</td>');  
     }  
     $r->print('</tr><tr>');  
     $r->print(&Apache::lonhtmlcommon::status_select_row(\%status_types));      $r->print(&Apache::lonhtmlcommon::status_select_row(\%status_types));
     $r->print('<td>&nbsp;</td>');      $r->print('</td><td>');
     $r->print(&Apache::lonhtmlcommon::role_select_row(\@roles));      $r->print(&Apache::lonhtmlcommon::role_select_row(\@roles,undef,undef,1,$cdom,$cnum));
     if (@sections > 0) {      if (@sections > 0) {
         @sections = sort {$a cmp $b} @sections;          @sections = sort {$a cmp $b} @sections;
         unshift(@sections,'_all'); # Put 'all' at the front of the list          unshift(@sections,'none'); # Put 'no sections' next
         unshift(@sections,'_nosec'); # Put 'no sections' next          unshift(@sections,'all'); # Put 'all' at the front of the list
         $r->print('<td>&nbsp;</td>      } else {
                    <td colspan="3" align="center" valign="top">'.          @sections = ('all','none');
         &sections_selection(\@sections,'sectionpick').'</td>');  
     }      }
     $r->print('      $r->print('</td><td>'.
                 &sections_selection(\@sections,'sectionpick').'</td>
       </tr>        </tr>
      </table>       </table>');
     </td>  
    </tr>');  
     return;      return;
 }  }
   
Line 1268  sub sections_selection { Line 1905  sub sections_selection {
         $numvisible = @{$sections};          $numvisible = @{$sections};
     }      }
     foreach my $sec (@{$sections}) {      foreach my $sec (@{$sections}) {
         if ($sec eq '_all') {          if ($sec eq 'all') {
             $section_sel .= '  <option value="'.$sec.'" />all sections'."\n";              $section_sel .= '  <option value="'.$sec.'">'.&mt('all sections').'</option>'."\n";
         } elsif ($sec eq '_nosec') {          } elsif ($sec eq 'none') {
             $section_sel .= '  <option value="'.$sec.'" />no section'."\n";               $section_sel .= '  <option value="'.$sec.'">'.&mt('no section').'</option>'."\n"; 
         } else {          } else {
             $section_sel .= '  <option value="'.$sec.'" />'.$sec."\n";              $section_sel .= '  <option value="'.$sec.'">'.$sec."</option>\n";
         }          }
     }      }
     my $output = '      my $output = '
         <select name="'.$elementname.'" multiple="true" size="'.$numvisible.'">          <select name="'.$elementname.'" multiple="multiple" size="'.$numvisible.'">
           '.$section_sel.'            '.$section_sel.'
         </select>';          </select>';
     return $output;      return $output;
 }  }
   
 sub access_date_settings {  sub access_date_settings {
     my ($r,$tabcol,$action,$formname,$stored,$image) = @_;      my ($r,$action,$formname,$stored,$image,$gpterm,$ucgpterm) = @_;
     my %lt = &Apache::lonlocal::texthash(      my $sten = &mt("Default start and end dates for $gpterm access");
                 'sten' => 'Default start and end dates for group access',  
              );  
     my $starttime = time;      my $starttime = time;
     my $endtime = time+(6*30*24*60*60); # 6 months from now, approx      my $endtime = time+(6*30*24*60*60); # 6 months from now, approx
     if ($action eq 'modify') {      if ($action eq 'modify') {
Line 1296  sub access_date_settings { Line 1931  sub access_date_settings {
             $endtime = $$stored{'enddate'};              $endtime = $$stored{'enddate'};
         }          }
     }      }
     my ($start_table,$end_table) = &date_setting_table      my ($table) = &date_setting_table($starttime,$endtime,$formname);
                                     ($starttime,$endtime,$formname);      $r->print(&Apache::lonhtmlcommon::topic_bar($image,$sten).'
     &topic_bar($r,$tabcol,$image,$lt{'sten'});      '.$table.'
     $r->print('      ');
    <tr>  
     <td>&nbsp;</td>  
     <td colspan="3">'.$start_table.'</td>  
    <tr>  
    <tr>  
     <td colspan="4">&nbsp;</td>  
    </tr>  
    <tr>  
     <td>&nbsp;</td>  
     <td colspan="3">'.$end_table.'</td>  
    <tr>');  
     return;      return;
 }  }
   
 sub choose_members_form {  sub choose_members_form {
     my ($r,$cdom,$cnum,$tabcol,$action,$formname,$page,$groupname,$description,      my ($r,$cdom,$cnum,$action,$formname,$page,$groupname,$description,
         $granularity,$startdate,$enddate,$tools,$fixedprivs,$toolprivs,          $granularity,$quota,$startdate,$enddate,$tools,$fixedprivs,$toolprivs,
         $functions,$users,$userdata,$idx,$stored,$states,$navbuttons,          $functions,$users,$userdata,$idx,$stored,$states,$navbuttons,
         $rowColor1,$rowColor2) = @_;          $gpterm,$ucgpterm,$crstype) = @_;
     my @regexps = ('user_','userpriv_','sec_');      my @regexps = ('user_','userpriv_','sec_');
     my %origmembers;      my %origmembers;
     $r->print(&Apache::lonhtmlcommon::echo_form_input(      $r->print(&Apache::lonhtmlcommon::echo_form_input(
          ['origin','action','state','page','member','specificity','branch',           ['origin','action','state','page','member','specificity','branch',
           'defpriv','autorole','autoadd','autodrop','sortby','togglefunc'],            'defpriv','autorole','autoadd','autodrop','sortby','togglefunc'],
          \@regexps));           \@regexps));
     my $earlyout = &validate_groupname($groupname,$action,$cdom,$cnum);      my $earlyout = &validate_groupname($groupname,$action,$cdom,$cnum,$gpterm,
     $r->print('                                         $ucgpterm,$crstype);
 <table width="100%" cellpadding="0" cellspacing="0" border="0">  
  <tr>  
   <td>&nbsp;</td>  
   <td colspan="3">  
 ');  
     if ($earlyout) {      if ($earlyout) {
         $r->print($earlyout.'</td></tr>');   $r->print($earlyout);
         &display_navbuttons($r,$formname,$$states{$action}[$page-1],          &display_navbuttons($r,$formname,$$states{$action}[$page-1],
                            $$navbuttons{'gtps'});                             $$navbuttons{'gtps'});
         $r->print('</table>');  
         return;          return;
     }       } 
     my ($specimg,$memimg);      my ($specimg,$memimg);
Line 1344  sub choose_members_form { Line 1962  sub choose_members_form {
     my @unavailable = ();      my @unavailable = ();
     &check_tools($functions,$tools,\@available,\@unavailable);      &check_tools($functions,$tools,\@available,\@unavailable);
     if ($action eq 'create') {      if ($action eq 'create') {
         &print_current_settings($r,$action,$tabcol,$rowColor1,$rowColor2,          &print_current_settings($r,$action,$functions,$startdate,$enddate,
                                 $functions,$startdate,$enddate,$groupname,   $groupname,$description,$granularity,$quota,
                                 $description,$granularity,\@available,   \@available,\@unavailable,$gpterm,$ucgpterm);
                                 \@unavailable);  
         $specimg = 4;          $specimg = 4;
         $memimg = 5;          $memimg = 5;
     } else {      } else {
Line 1367  sub choose_members_form { Line 1984  sub choose_members_form {
             }              }
         }          }
     }      }
     &privilege_specificity($r,$tabcol,$rowColor1,$rowColor2,$action,      &privilege_specificity($r,$action,$specimg,$tools,$stored,$toolprivs,
                           $specimg,$tools,$stored,$toolprivs,                            $fixedprivs,\@available,$formname,$gpterm,$ucgpterm,
                           $fixedprivs,\@available,$formname);                            $functions,$crstype);
     my $newusers = &pick_new_members($r,$action,$formname,$tabcol,$rowColor1,      my $newusers = &pick_new_members($r,$action,$formname,\@available,$idx,
                                     $rowColor2,\@available,$idx,$stored,       $stored,$memimg,$users,$userdata,
                                     $memimg,$users,$userdata,$granularity,       $granularity,\%origmembers,$gpterm,
                                     \%origmembers);       $ucgpterm);
     if ($newusers || $action eq 'create') {      if ($newusers || $action eq 'create') {
         &display_navbuttons($r,$formname,$$states{$action}[$page-1],          &display_navbuttons($r,$formname,$$states{$action}[$page-1],
                             $$navbuttons{'gtps'},$$states{$action}[$page+1],                              $$navbuttons{'gtps'},$$states{$action}[$page+1],
Line 1382  sub choose_members_form { Line 1999  sub choose_members_form {
         &display_navbuttons($r,$formname,$$states{$action}[$page-1],          &display_navbuttons($r,$formname,$$states{$action}[$page-1],
                             $$navbuttons{'gtps'});                              $$navbuttons{'gtps'});
     }      }
     $r->print('</table>');  
     return;      return;
 }  }
   
 sub display_navbuttons {  sub display_navbuttons {
     my ($r,$formname,$prev,$prevtext,$next,$nexttext) = @_;      my ($r,$formname,$prev,$prevtext,$next,$nexttext) = @_;
     $r->print('      $r->print('<div class="LC_navbuttons">');
     <tr>  
      <td colspan="4">&nbsp;</td>  
     </tr>  
     <tr>  
      <td>&nbsp;</td>  
      <td colspan="3">');  
     if ($prev) {      if ($prev) {
         $r->print('          $r->print('
       <input type="button" name="previous" value = "'.$prevtext.'"        <input type="button" name="previous" value = "'.$prevtext.'"
     onclick="javascript:backPage(document.'.$formname.','."'".$prev."'".')"/>      onclick="javascript:backPage(document.'.$formname.','."'".$prev."'".')"/>
    &nbsp;&nbsp;&nbsp;');     &nbsp;&nbsp;&nbsp;');
       } elsif ($prevtext) {
           $r->print('
         <input type="button" name="previous" value = "'.$prevtext.'"
       onclick="javascript:history.back()"/>
      &nbsp;&nbsp;&nbsp;');
     }      }
     if ($next) {      if ($next) {
         $r->print('          $r->print('
       <input type="button" name="next" value="'.$nexttext.'"        <input type="button" name="next" value="'.$nexttext.'"
  onclick="javascript:nextPage(document.'.$formname.','."'".$next."'".')" />');   onclick="javascript:nextPage(document.'.$formname.','."'".$next."'".')" />');
     }      }
     $r->print('      $r->print('</div>');
      </td>  
     </tr>  
 ');  
 }  }
   
 sub check_tools {  sub check_tools {
Line 1425  sub check_tools { Line 2037  sub check_tools {
 }  }
   
 sub print_current_settings {  sub print_current_settings {
     my ($r,$action,$tabcol,$rowColor1,$rowColor2,$functions,$startdate,$enddate,      my ($r,$action,$functions,$startdate,$enddate,$groupname,$description,
            $groupname,$description,$granularity,$available,$unavailable) =@_;   $granularity,$quota,$available,$unavailable,$gpterm,$ucgpterm) = @_;
   
     my %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
         grna => 'Group Name',          grna => 'Group Name',
         desc => 'Description',          desc => 'Group Title',
         grfn => 'Group Functions',          grfn => "Collaborative Tools",
         gran => 'Granularity',          gran => 'Granularity',
           quot => 'File quota',
         dfac => 'Default access dates',          dfac => 'Default access dates',
         ygrs => 'Your group selections',          ygrs => "Your group selections - ",
         tfwa => 'The following settings will apply to the group:',          tfwa => "The following settings will apply to the group:",
         difn => 'Different functionality<br />for different users:',          stda => 'Start date:',
         stda => 'Start date',  
         enda => 'End date:',          enda => 'End date:',
     );      );
       $lt{'difn'} = &mt('Different collaborative tools[_1]for different members:','<br />');
     my $showstart = &Apache::lonlocal::locallocaltime($startdate);      my $showstart = &Apache::lonlocal::locallocaltime($startdate);
     my $showend;      my $showend;
     if ($enddate == 0) {      if ($enddate == 0) {
Line 1447  sub print_current_settings { Line 2060  sub print_current_settings {
     } else {      } else {
         $showend = &Apache::lonlocal::locallocaltime($enddate);          $showend = &Apache::lonlocal::locallocaltime($enddate);
     }      }
     $r->print('<table border="0" cellpadding="0" cellspacing="20">');  
     if ($action eq 'create') {      if ($action eq 'create') {
         $r->print('          $r->print('
 <tr>  <div><span style="font-size: larger">'.$lt{'ygrs'}.'</span>
  <td><font face="arial,helvetica,sans-serif"><b>'.$lt{'ygrs'}.'</b></font>  
 <br />'.$lt{'tfwa'}.'  <br />'.$lt{'tfwa'}.'
  </td>  </div>');
 </tr>');  
     }      }
     $r->print('<tr><td>');      $r->print(&Apache::loncommon::start_data_table('LC_course_group_status').
     $r->print(&Apache::lonhtmlcommon::start_pick_box());        &Apache::loncommon::start_data_table_header_row());
     $r->print('      $r->print('
 <tr>    <th>'.$lt{'grna'}.'</th>
  <td>    <th>'.$lt{'desc'}.'</th>
 <table cellspacing="1" cellpadding="4">    <th>'.$lt{'grfn'}.'</th>
  <tr bgcolor="'.$tabcol.'" align="center">    <th>'.$lt{'gran'}.'</th>
   <td><b>'.$lt{'grna'}.'</b></td>    <th>'.$lt{'quot'}.'</th>
   <td><b>'.$lt{'desc'}.'</b></td>    <th>'.$lt{'dfac'}.'</th>
   <td><b>'.$lt{'grfn'}.'</b></td>  ');
   <td><b>'.$lt{'gran'}.'</b></td>      $r->print(&Apache::loncommon::end_data_table_header_row().
   <td><b>'.$lt{'dfac'}.'</b></td>        &Apache::loncommon::start_data_table_row('LC_data_table_dense'));
  </tr>      $r->print('
  <tr bgcolor="'.$rowColor2.'">    <td valign="top">'.$groupname.'</td>
   <td valign="top"><small>'.$groupname.'</small></td>    <td valign="top">'.$description.'</td>
   <td valign="top"><small>'.$description.'</small></td>  
   <td>    <td>
 ');  ');
   
     if (@{$available} > 0) {      if (@{$available} > 0) {
         $r->print('<small><b>Available:</b></small>          $r->print('<b>'.&mt('Available for assignment to members:').'</b>');
                     <table cellpadding="" cellspacing="1"><tr>');          $r->print('<ul>');
         my $rowcell = int(@{$available}/2) + @{$available}%2;  
         for (my $i=0; $i<@{$available}; $i++) {          for (my $i=0; $i<@{$available}; $i++) {
             if (@{$available} > 3) {              $r->print('<li>'.&mt($$functions{$$available[$i]}).'</li>');
                 if ($i==$rowcell) {  
                     $r->print('</tr><tr>');  
                 }  
             }  
             $r->print('<td><small>'.$$functions{$$available[$i]}.  
                                           '</small></td><td>&nbsp;</td>');  
         }          }
         if ((@{$available} > 3) && (@{$available}%2)) {          $r->print('</ul>');
             $r->print('<td>&nbsp;</td><td>&nbsp;</td>');  
         }  
         $r->print('</tr></table><br />');  
     }      }
   
     if (@{$unavailable} > 0) {      if (@{$unavailable} > 0) {
         $r->print('<small><b>Unavailable:</b></small>          $r->print('<b>'.&mt('Unavailable for assignment:').'</b>');
                     <table cellpadding="0" cellspacing="1"  border="0"><tr>');          $r->print('<ul>');
         my $rowcell = int(@{$unavailable}/2) + @{$unavailable}%2;          for (my $i=0; $i<@{$unavailable}; $i++) {
         for (my $j=0; $j<@{$unavailable}; $j++) {              $r->print('<li>'.&mt($$functions{$$unavailable[$i]}).'</li>');
             if (@{$unavailable} > 3) {  
                 if ($j==$rowcell) {  
                     $r->print('</tr><tr>');  
                 }  
             }  
             $r->print('<td><small>'.$$functions{$$unavailable[$j]}.  
                                               '</small></td><td>&nbsp;</td>');  
         }  
         if ((@{$unavailable} > 3) && (@{$unavailable}%2)) {  
             $r->print('<td>&nbsp;</td><td>&nbsp;</td>');  
         }          }
         $r->print('</tr></table>');          $r->print('</ul>');
     }      }
   
       my $quota_text=&mt('[_1] MB',$quota);
       my $granu_text=&mt($granularity);
     $r->print(<<"END");      $r->print(<<"END");
   </td>    </td>
   <td valign="top"><small><b>$lt{'difn'}    <td valign="top"><b>$lt{'difn'}</b> $granu_text</td>
   </b> $granularity</small>     <td valign="top">$quota_text</td> 
   <td valign="top"><small><b>$lt{'stda'}</b> $showstart<br />    <td valign="top"><b>$lt{'stda'}</b> $showstart<br />
       <b>$lt{'enda'}</b> $showend</small>        <b>$lt{'enda'}</b> $showend
   </td>    </td>
  </tr>  
 </table>  
 </td>  
 </tr>  
 END  END
     $r->print(&Apache::lonhtmlcommon::end_pick_box());      $r->print(&Apache::loncommon::end_data_table_row().
     $r->print('</td></tr></table><br />');        &Apache::loncommon::end_data_table());
     return;      return;
 }  }
   
 sub pick_new_members {  sub pick_new_members {
     my ($r,$action,$formname,$tabcol,$rowColor1,$rowColor2,$available,$idx,      my ($r,$action,$formname,$available,$idx,$stored,$img,$users,$userdata,
         $stored,$img,$users,$userdata,$granularity,$origmembers) = @_;   $granularity,$origmembers,$gpterm,$ucgpterm) = @_;
     my %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
           'gpme' => 'Group membership',            'gpme' => "Group membership",
           'addm' => 'Add members',            'addm' => 'Add members',
           'setf' => 'Set functionality',            'setf' => 'Assign collaborative tools', 
           'func' => 'Functionality',            'func' => 'Tools',
           'nome' => 'No members to add at this time.',            'nome' => 'No members to add at this time, as there are no users '.
           'nnew' => 'There are no users to add as new members, as all users'.                       'matching the specified type(s), role(s) and section(s).',
                     ' matching the specified type(s), role(s), and/or '.            'nnew' => "There are no users to add as new members, as all users".
                     'section(s) are already affiliated with this group.',                      " matching the specified type(s), role(s), and ".
           'yoma' =>  'You may need to use the '."'".'modify existing, past or '.                      "section(s) are already affiliated with this group.",
                      'future members'."'".' page if you need to re-enable '.            'yoma' =>  "You may need to use the 'modify existing, past or ".
                      'or activate access for previous or future members.',                       "future members' page if you need to re-enable ".
                        "or activate access for previous or future members.",
     );      );
     my %members;      my %members;
     my $totalusers = 0;      my $totalusers = 0;
Line 1565  sub pick_new_members { Line 2156  sub pick_new_members {
             $r->print(&check_uncheck_tools($r,$available));              $r->print(&check_uncheck_tools($r,$available));
         }          }
     }      }
     &topic_bar($r,$tabcol,$img,$lt{'gpme'});      $r->print(&Apache::lonhtmlcommon::topic_bar($img,$lt{'gpme'}));
     if (keys(%members) > 0) {      if (keys(%members) > 0) {
         $r->print('          $r->print('
  <tr>  
   <td>&nbsp;</td>  
   <td colspan="3">  
     <table>      <table>
      <tr>');       <tr>');
         &check_uncheck_buttons($r,$formname,'member',$lt{'addm'});          &check_uncheck_buttons($r,$formname,'member',$lt{'addm'});
         if (@{$available} > 0 && $granularity eq 'Yes') {          if (@{$available} > 0 && $granularity eq 'Yes') {
             $r->print('<td><nobr>              $r->print('<td>
      <fieldset><legend><b>'.$lt{'setf'}.'</b></legend>       <fieldset><legend>'.$lt{'setf'}.'</legend>
       <input type="button" value="check all"        <span class="LC_nobreak">
         <input type="button" value="'.&mt('check all').'"
         onclick="javascript:checkAllTools(document.'.$formname.')" />          onclick="javascript:checkAllTools(document.'.$formname.')" />
         &nbsp;&nbsp;          &nbsp;&nbsp;
       <input type="button" value="uncheck all"        <input type="button" value="'.&mt('uncheck all').'"
         onclick="javascript:uncheckAllTools(document.'.$formname.')" />          onclick="javascript:uncheckAllTools(document.'.$formname.')" />
      </fieldset></nobr></td>');        </span>
        </fieldset></td>');
         }          }
         $r->print('</tr></table>          $r->print('</tr></table>
   </td>  
  </tr>  
  <tr>  
   <td colspan="4">&nbsp;</td>  
  </tr>  
  <tr>  
   <td>&nbsp;</td>  
   <td colspan="3">  
         ');          ');
         $r->print(&Apache::lonhtmlcommon::start_pick_box());          $r->print(&Apache::loncommon::start_data_table().
     &Apache::loncommon::start_data_table_header_row());
         $r->print('          $r->print('
    <table border="0" cellpadding="4" cellspacing="1">       <th>'.&mt('Add?').'</b></td>
     <tr bgcolor="'.$tabcol.'" align="center">       <th><a href="javascript:changeSort('."'fullname'".')">'.&mt('Name').'</a></td>
      <td><b>'.&mt('Add?').'</b></td>       <th><a href="javascript:changeSort('."'username'".')">'.&mt('Username').'</a></td>
      <td><b><a href="javascript:changeSort('."'fullname'".')">'.&mt('Name').'</a></b></td>       <th><a href="javascript:changeSort('."'domain'".')">'.&mt('Domain').'</a></td>
      <td><b><a href="javascript:changeSort('."'username'".')">'.&mt('Username').'</a></b>       <th><a href="javascript:changeSort('."'id'".')">'.&mt('ID').'</a></td>
      </td>       <th><a href="javascript:changeSort('."'section'".')">'.&mt('Section').'</a></td>
      <td><b><a href="javascript:changeSort('."'domain'".')">'.&mt('Domain').'</a></b></td>  
      <td><b><a href="javascript:changeSort('."'id'".')">ID</a></b></td>  
 ');  ');
         if (@{$available} > 0) {          if (@{$available} > 0) {
             $r->print('<td><b>'.$lt{'func'}.'</b></td>');              $r->print('<th>'.$lt{'func'}.'</th>');
         }          }
         $r->print('</tr>');          $r->print(&Apache::loncommon::end_data_table_header_row());
         if (@{$available} > 0) {          if (@{$available} > 0) {
             if ($granularity eq 'Yes') {              if ($granularity eq 'Yes') {
                 $r->print('<tr bgcolor="#cccccc">                  $r->print(&Apache::loncommon::start_data_table_row('LC_data_table_dense LC_data_table_highlight').'
  <td colspan="5">&nbsp;</td>   <td colspan="6">&nbsp;</td>
  <td align="center"><small><nobr><b>'.&mt('All:').'</b>&nbsp;');   <td align="center"><span class="LC_nobreak"><b>'.&mt('All:').'</b>&nbsp;');
                 foreach my $tool (@{$available}) {                  foreach my $tool (@{$available}) {
                     $r->print('<label><input type="checkbox" name="togglefunc" '.                      $r->print('<label><input type="checkbox" name="togglefunc" '.
    'onclick="javascript:toggleTools(document.'.$formname.'.user_'.$tool.',this);"'.     'onclick="javascript:toggleTools(document.'.$formname.'.user_'.$tool.',this);"'.
    ' value="'.$tool.'">'.'<b>'.$tool.'</b></label>&nbsp;&nbsp;&nbsp;');     ' value="'.$tool.'">'.'<b>'.$tool.'</b></label>&nbsp;&nbsp;&nbsp;');
                 }                  }
                 $r->print('</nobr></small></td></tr>');                  $r->print('</span></td></tr>');
             }              }
         }          }
         my %Sortby = ();          my %Sortby = ();
Line 1632  sub pick_new_members { Line 2213  sub pick_new_members {
                 push(@{$Sortby{$members{$user}[$$idx{udom}]}},$user);                  push(@{$Sortby{$members{$user}[$$idx{udom}]}},$user);
             } elsif ($env{'form.sortby'} eq 'id') {              } elsif ($env{'form.sortby'} eq 'id') {
                 push(@{$Sortby{$members{$user}[$$idx{id}]}},$user);                  push(@{$Sortby{$members{$user}[$$idx{id}]}},$user);
               } elsif ($env{'form.sortby'} eq 'section') {
                   push(@{$Sortby{$members{$user}[$$idx{section}]}},$user);
             } else {              } else {
                 push(@{$Sortby{$members{$user}[$$idx{fullname}]}},$user);                  push(@{$Sortby{$members{$user}[$$idx{fullname}]}},$user);
             }              }
         }          }
         my $rowNum = 0;  
         my $rowColor;  
         foreach my $key (sort(keys(%Sortby))) {          foreach my $key (sort(keys(%Sortby))) {
             foreach my $user (@{$Sortby{$key}}) {              foreach my $user (@{$Sortby{$key}}) {
                 if ($rowNum %2 == 1) {  
                     $rowColor = $rowColor1;  
                 } else {  
                     $rowColor = $rowColor2;  
                 }  
                 my $id = $members{$user}[$$idx{id}];                  my $id = $members{$user}[$$idx{id}];
                 my $fullname = $members{$user}[$$idx{fullname}];                  my $fullname = $members{$user}[$$idx{fullname}];
                 my $udom = $members{$user}[$$idx{udom}];                  my $udom = $members{$user}[$$idx{udom}];
                 my $uname = $members{$user}[$$idx{uname}];                  my $uname = $members{$user}[$$idx{uname}];
                 $r->print('<tr bgcolor="'.$rowColor.'"><td align="right">                  my $section = $members{$user}[$$idx{section}];
    <input type="checkbox" name="member" value="'.$user.'" /></td><td><small>'.                  $r->print(&Apache::loncommon::start_data_table_row('LC_data_table_dense').
     $fullname.'</small></td><td><small>'.$uname.'</small></td><td><small>'.    '<td align="right"><input type="checkbox" name="member" value="'.$user.'" /></td>'.
     $udom.'</small></td><td><small>'.$id.'</small></td>');    '<td>'.$fullname.'</td>'.
     '<td>'.$uname.'</td>'.
     '<td>'.$udom.'</td>'.
     '<td>'.$id.'</td>'.
     '<td>'.$section.'</td>');
                 if (@{$available} > 0) {                  if (@{$available} > 0) {
                     $r->print('<td align="center"><nobr><small>'.                      $r->print('<td align="center"><span class="LC_nobreak">'.
                               '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;');                                '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;');
                     foreach my $tool (@{$available}) {                      foreach my $tool (@{$available}) {
                         if ($granularity eq 'Yes') {                          if ($granularity eq 'Yes') {
Line 1665  sub pick_new_members { Line 2245  sub pick_new_members {
                           $tool.'" value="'.$user.'" />'.$tool.'&nbsp;&nbsp;&nbsp;');                            $tool.'" value="'.$user.'" />'.$tool.'&nbsp;&nbsp;&nbsp;');
                         }                          }
                     }                      }
                     $r->print('</small></nobr></td>');                      $r->print('</span></td>');
                 }                  }
                 $r->print('</tr>'."\n");                  $r->print(&Apache::loncommon::end_data_table_row()."\n");
                 $rowNum ++;  
             }              }
         }          }
         $r->print(&Apache::lonhtmlcommon::end_pick_box());          $r->print(&Apache::loncommon::end_data_table());
         $r->print('  
      </td>  
     </tr>');  
     } else {      } else {
         $r->print('  
     <tr>  
      <td>&nbsp;</td>  
      <td colspan="3">  
 ');  
         if ($totalusers > 0) {          if ($totalusers > 0) {
             $r->print($lt{'nnew'}.'<br /><br />'.$lt{'yoma'});              $r->print($lt{'nnew'}.'<br /><br />'.$lt{'yoma'});
         } else {           } else { 
             $r->print($lt{'nome'});              $r->print($lt{'nome'});
         }          }
         $r->print('  
      </td>  
     </tr>');  
     }      }
     return $newusers;      return $newusers;
 }  }
   
 sub privilege_specificity {  sub privilege_specificity {
     my ($r,$tabcol,$rowColor1,$rowColor2,$action,$img,$tools,$stored,      my ($r,$action,$img,$tools,$stored,$toolprivs,$fixedprivs,$available,
         $toolprivs,$fixedprivs,$available,$formname) = @_;   $formname,$gpterm,$ucgpterm,$functions,$crstype) = @_;
     my %lt = &Apache::lonlocal::texthash (      my %lt = &Apache::lonlocal::texthash (
       'uprv' => 'User privileges',        'uprv' => 'User privileges for collaborative tools',
       'frty' => 'For each type of functionality you have chosen to include, '.        'frty' => 'For each collaborative tool you have chosen to include, '.
                 'there is a set of standard privileges which apply to all '.                  'there is a set of core privileges which all group members '.
                 'of those for whom the functionality is enabled.',                  'assigned use of the tool will receive.',
       'thar' => 'There are also additional privileges which can be set for '.        'thar' => 'For some tools there are also additional optional '.
                 'some, or all, members. Please choose one of the following:',                   'privileges which can be set.',
       'fort' => 'For the types of functionality you have chosen to include '.        'plch' => 'Choose one of the following:',
                 'there are no additional privileges which can be set for some '.        'fort' => 'For the collaborative tools you have chosen to include '.
                 'or all members.',                  'only core privileges are available, '.
       'eaty' => 'Each of the types of functionality includes standard '.                  'so there are no optional privileges to assign.',
                 'privileges which apply to members with access to that '.        'eaty' => 'Each collaborative tool includes core '.
                 'functionality, and may also include additional privileges '.                  'privileges assigned to all members with access to the '.
                   'tool. Some tools may also feature additional privileges '.
                 'which can be set for specific members.',                  'which can be set for specific members.',
       'cutg' => 'Currently the group is configured ',        'cutg' => 'Currently the group is configured ',
       'sdif' => 'so different group members can receive different privileges.',        'sdif' => 'so different members can receive different optional privileges for a particular tool.',
       'sall' => 'so all group members will receive the same privileges.',        'sall' => 'so all members will receive the same optional privileges for a particular tool.',
       'algm' => 'All group members will receive the same privileges.',        'algm' => 'All group members will receive the same privileges for any tool assigned to them, including the default set of optional privileges.',
       'smgp' => 'Some group members will receive different privileges from '.        'smgp' => 'Different group members may receive different privileges from '.
                 'others.',                  'others for the tools they have been assigned.',
       'thwi' => 'These will be the privileges all group members receive, '.         'thwi' => 'These will be the privileges all group members receive for a particular assigned tool, '. 
                 'if you selected the first option above.',                  'if you selected the first option above.',
       'thes' => 'These will be the privileges given to members assigned '.           'thes' => "These will be the privileges given to members assigned ".   
                 'in the future, including via automatic group assignment '.                  "in the future via automatic group assignment ".
                 'for specific sections/roles ',                  "for users who receive specific sections/roles in the course ",
       'asyo' => 'As you have chosen not to include any functionality in the '.        'asyo' => "As you have chosen not to include any collaborative tools ".
                 'group, no default user privileges settings need to be set.',                  "in the group, no default optional privileges need to be set.",
       'plin' => 'Please indicate which <b>optional</b> privileges members '.                  'will receive by default for a specific tool.',
                 'will receive by default.',  
       'oppr' => 'Optional privileges',        'oppr' => 'Optional privileges',
       'defp' => 'The default privileges new members will receive are:',         'defp' => 'The default privileges new members will receive are:', 
     );      );
       $lt{'plin'} = &mt('Indicate which [_1]optional[_2] privileges members '.
                         'will receive by default for a specific tool.','<b>','</b>');
       if ($crstype eq 'Community') {
           $lt{'thes'} = &mt('These will be the privileges given to members assigned in the future via automatic group assignment for users who receive specific sections/roles in the community '); 
       }
     my $totaloptionalprivs = 0;      my $totaloptionalprivs = 0;
     foreach my $tool (@{$tools}) {      foreach my $tool (@{$tools}) {
         foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {          foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {
Line 1736  sub privilege_specificity { Line 2309  sub privilege_specificity {
             }              }
         }          }
     }      }
     &topic_bar($r,$tabcol,$img,$lt{'uprv'});      $r->print(&Apache::lonhtmlcommon::topic_bar($img,$lt{'uprv'}));
     $r->print('  
  <tr>  
   <td>&nbsp;</td>  
   <td colspan="3">  
   ');  
     if ((($action eq 'create') && (@{$available} > 0)) ||       if ((($action eq 'create') && (@{$available} > 0)) || 
         (($action eq 'modify') && ($formname eq 'change_settings'))) {            (($action eq 'modify') && ($formname eq 'change_settings'))) {
         my %specific = (          my %specific = (
                       'No'  => 'checked="checked"',                        'No'  => 'checked="checked"',
                       'Yes' => '',                        'Yes' => '',
Line 1751  sub privilege_specificity { Line 2319  sub privilege_specificity {
         if ($action eq 'create') {          if ($action eq 'create') {
             $r->print($lt{'frty'}.'<br />');              $r->print($lt{'frty'}.'<br />');
             if ($totaloptionalprivs) {              if ($totaloptionalprivs) {
                 $r->print($lt{'thar'});                  $r->print($lt{'thar'}.'<br /><br />'.$lt{'plch'});
             } else {              } else {
                 $r->print($lt{'fort'});                  $r->print($lt{'fort'});
             }              }
Line 1767  sub privilege_specificity { Line 2335  sub privilege_specificity {
         }          }
         if ($totaloptionalprivs) {          if ($totaloptionalprivs) {
             $r->print('              $r->print('
 <br /><br /><label><nobr><input type="radio" name="specificity" value="No" '.$specific{'No'}.' />&nbsp;'.$lt{'algm'}.'</nobr></label><br/>  <br />
 <label><nobr><input type="radio" name="specificity" value="Yes" '.$specific{'Yes'}.' />&nbsp;'.$lt{'smgp'}.'</nobr></label>  <label><span class="LC_nobreak"><input type="radio" name="specificity" value="No" '.$specific{'No'}.' />&nbsp;'.$lt{'algm'}.'</span></label><br />
   </td>  <label><span class="LC_nobreak"><input type="radio" name="specificity" value="Yes" '.$specific{'Yes'}.' />&nbsp;'.$lt{'smgp'}.'</span></label><br /><br />');
  </tr>  
  <tr>  
   <td colspan="4">&nbsp;</td>  
  </tr>');  
         } else {          } else {
             $r->print('<input type="hidden" name="specificity" value="No" />');              $r->print('<input type="hidden" name="specificity" value="No" />');
         }          }
         if ($totaloptionalprivs) {          if ($totaloptionalprivs) {
             $r->print('              $r->print($lt{'plin'});
  <tr>  
   <td>&nbsp;</td>  
   <td colspan="3">'.$lt{'plin'});  
             if ($action eq 'create') {              if ($action eq 'create') {
                 $r->print(' '.$lt{'thwi'});                  $r->print('<br />'.$lt{'thwi'});
             }              }
             $r->print('<br />'.$lt{'thes'});              $r->print('<br />'.$lt{'thes'});
             if ($action eq 'create') {              if ($action eq 'create') {
Line 1792  sub privilege_specificity { Line 2353  sub privilege_specificity {
                 $r->print('('.&mt('if enabled below').').');                  $r->print('('.&mt('if enabled below').').');
             }              }
             $r->print('<br /><br />              $r->print('<br /><br />
   </td>    <table><tr>');
  </tr>  
  <tr>  
   <td>&nbsp;</td>  
   <td colspan="2"><table><tr>');  
         &check_uncheck_buttons($r,$formname,'defpriv',$lt{'oppr'});          &check_uncheck_buttons($r,$formname,'defpriv',$lt{'oppr'});
         $r->print('          $r->print('
     </tr>      </tr>
    </table>     </table>
   </td>  
   <td width="100%">&nbsp;</td>  
  </tr><tr>  
   <td>&nbsp;</td>  
   <td colspan="3">  
    <br />     <br />
 ');  ');
         } else {          } else {
             $r->print('<tr><td>&nbsp;</td><td colspan="3">'.$lt{'algm'}.'<br /><br />');              $r->print($lt{'algm'}.'<br /><br />');
         }          }
         &default_privileges($r,$action,$tabcol,$rowColor1,$rowColor2,          &default_privileges($r,$action,$tools,$toolprivs,$fixedprivs,
                             $tools,$toolprivs,$fixedprivs,$available);      $available,$functions);
     } else {      } else {
         if ($action eq 'create') {          if ($action eq 'create') {
             $r->print($lt{'asyo'});              $r->print($lt{'asyo'});
               $r->print('<input type="hidden" name="specificity" value="No" />');
         } elsif ($action eq 'modify' && $formname eq 'pick_members') {          } elsif ($action eq 'modify' && $formname eq 'pick_members') {
             my @defprivs;              my @defprivs;
             if (ref($$stored{'defpriv'}) eq 'ARRAY') {              if (ref($$stored{'defpriv'}) eq 'ARRAY') {
Line 1828  sub privilege_specificity { Line 2381  sub privilege_specificity {
                 $r->print($lt{'sall'});                  $r->print($lt{'sall'});
             }              }
             $r->print(' '.$lt{'defp'}.'<br /><br />');              $r->print(' '.$lt{'defp'}.'<br /><br />');
             &display_defprivs($r,$tabcol,$rowColor1,$rowColor2,$tools,              &display_defprivs($r,$tools,$toolprivs,\@defprivs);
                               $toolprivs,\@defprivs);  
         }          }
     }      }
     $r->print('  
   </td>  
  </tr>  
 ');  
     return;      return;
 }  }
   
 sub default_privileges {  sub default_privileges {
     my ($r,$action,$tabcol,$rowColor1,$rowColor2,$tools,$toolprivs,      my ($r,$action,$tools,$toolprivs,$fixedprivs,$available,$functions) = @_;
         $fixedprivs,$available) = @_;  
     my %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
                                 'addp' => 'Additional privileges',                                  'addp' => 'Additional privileges',
                                 'fixp' => 'Fixed privileges',                                  'fixp' => 'Fixed privileges',
                                 'oppr' => 'Optional privileges',                                  'oppr' => 'Optional privileges',
                                 'func' => 'Function',                                  'func' => 'Collaborative Tool',
     );      );
     $r->print(&Apache::lonhtmlcommon::start_pick_box());      $r->print(&Apache::lonhtmlcommon::start_pick_box('LC_group_priv_box').
     $r->print('<tr>        &Apache::lonhtmlcommon::row_title($lt{'func'},undef,
                 <td bgcolor="'.$tabcol.'" valign="top">        'LC_groups_functionality'));
                  <table cellspacing="0" cellpadding="1">      my @tableHeader;
                   <tr>      if ((ref($functions) eq 'HASH') && (ref($tools) eq 'ARRAY')) {
                    <td valign="top"><b>'.$lt{'func'}.'</b></td>          @tableHeader = map { $functions->{$_}; } @{$tools};
                   </tr>      }
                   <tr>   $r->print(join('</td><td class="LC_groups_functionality">', @tableHeader));
                    <td valign="top"><b>'.$lt{'fixp'}.'</b></td>      $r->print(&Apache::lonhtmlcommon::row_closure(1));
                   </tr>      my $fixed = '';
                   <tr>      my $dynamic = '';
                    <td valign="top"><b>'.$lt{'oppr'}.'</b></td>  
                   </tr>  
                  </table>  
                 </td>  
     ');  
     foreach my $tool (@{$tools}) {      foreach my $tool (@{$tools}) {
         $r->print('<td align="center" valign="top">  
                     <table cellspacing="0" cellpadding="1">  
                      <tr bgcolor="#cccccc">  
                       <td colspan="2" align="center"><b>'.$tool.'</b></td>  
                      </tr>  
         ');  
         my $privcount = 0;          my $privcount = 0;
         my $fixed = '';   if ($dynamic ne '') {
         my $dynamic = '';      $dynamic .= '</td><td class="LC_groups_optional">';
    }
    $dynamic .= '<table class="LC_group_priv"><tr>';
         foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {          foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {
             if (exists($$fixedprivs{$tool}{$priv})) {              if (exists($$fixedprivs{$tool}{$priv})) {
                 $fixed .= '<input type="hidden" name="defpriv" value="'.$priv.'" />'.$$toolprivs{$tool}{$priv}.'&nbsp;';   if ($fixed ne '') {
       $fixed .= '</td><td class="LC_groups_fixed">';
    }
                   $fixed .= '<input type="hidden" name="defpriv" value="'.$priv.'" />'
                            .'<span class="LC_nobreak">'.&mt($$toolprivs{$tool}{$priv}).'&nbsp;';
                 if ($action eq 'modify') {                  if ($action eq 'modify') {
                     if (grep/^$tool$/,@{$available}) {                      if (grep(/^$tool$/,@{$available})) {
                         $fixed .= '<small>'.&mt('(on)').'<small>&nbsp;';                          $fixed .= '<small>'.&mt('(on)').'<small>&nbsp;';
                     } else {                      } else {
                         $fixed .= '<small>'.&mt('(off)').'<small>&nbsp;';                          $fixed .= '<small>'.&mt('(off)').'<small>&nbsp;';
                     }                      }
                 }                  }
                   $fixed .= '</span>';
             } else {              } else {
                 $privcount ++;                  $privcount++;
                 if ($privcount == 3) {                  if ($privcount == 3) {
                     $dynamic .= '</tr>                      $dynamic .= '</tr>
                                  <tr bgcolor="'.$rowColor1.'">'."\n";                                   <tr>'."\n";
                 }                  }
                 $dynamic .= '<td><label><input type="checkbox" name="defpriv" value="'.$priv.'" />'.$$toolprivs{$tool}{$priv}.'</label></td>'."\n";                  $dynamic .= '<td><span class="LC_nobreak"><label><input type="checkbox" name="defpriv" value="'.$priv.'" />'.&mt($$toolprivs{$tool}{$priv}).'</label></span></td>'."\n";
             }              }
         }          }
         if ($dynamic eq '') {          if ($privcount == 0) {
             $dynamic = '<td>None</td>'."\n";              $dynamic .= '<td>'.&mt('None').'</td>'."\n";
         }          }
         if ($privcount < 3) {          if ($privcount < 3) {
             $dynamic .= '</tr>              $dynamic .= '<td>&nbsp;</td>'."\n";
                          <tr bgcolor="'.$rowColor1.'">  
                           <td colspan="2">&nbsp;</td>'."\n";  
         } elsif ($privcount%2) {          } elsif ($privcount%2) {
             $dynamic = '<td>&nbsp;</td>'."\n";              $dynamic = '<td>&nbsp;</td>'."\n";
         }          }
         $r->print('<tr bgcolor="'.$rowColor2.'">   $dynamic .= '</tr></table>';
                     <td colspan="2" align="center"><nobr>'.$fixed.'</nobr></td>  
                    </tr>  
                    <tr bgcolor="'.$rowColor1.'">'."\n".$dynamic.'</tr>'."\n".'</table>'."\n".'</td>  
         ');  
     }      }
     $r->print('</tr>'."\n");      $r->print(&Apache::lonhtmlcommon::row_title($lt{'fixp'},undef,
     $r->print(&Apache::lonhtmlcommon::end_pick_box());   'LC_groups_fixed').
         $fixed.
         &Apache::lonhtmlcommon::row_closure(1));
       $r->print(&Apache::lonhtmlcommon::row_title($lt{'oppr'},undef,
    'LC_groups_optional').
         $dynamic.
         &Apache::lonhtmlcommon::end_pick_box());
     $r->print('<br />');      $r->print('<br />');
     return;      return;
   
 }  }
   
 sub display_defprivs {  sub display_defprivs {
     my ($r,$tabcol,$rowColor1,$rowColor2,$tools,$toolprivs,$defprivs) = @_;      my ($r,$tools,$toolprivs,$defprivs) = @_;
       my $function = &Apache::loncommon::get_users_function();
       my $tabcol = &Apache::loncommon::designparm($function.'.tabbg');
       my $rowColor1 = "#dddddd";
       my $rowColor2 = "#eeeeee";
     my %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
                                 'priv' => 'Privileges',                                  'priv' => 'Privileges',
                                 'func' => 'Function',                                  'func' => 'Collaborative Tool',
     );      );
     $r->print(&Apache::lonhtmlcommon::start_pick_box());      $r->print(&Apache::lonhtmlcommon::start_pick_box());
     $r->print('<tr>');      $r->print('<tr>');
Line 1929  sub display_defprivs { Line 2477  sub display_defprivs {
         @{$currprivs{$tool}} = ();          @{$currprivs{$tool}} = ();
         foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {          foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {
             if (ref($defprivs) eq 'ARRAY') {              if (ref($defprivs) eq 'ARRAY') {
                 if (grep/^\Q$priv\E$/,@{$defprivs}) {                  if (grep(/^\Q$priv\E$/,@{$defprivs})) {
                     push(@{$currprivs{$tool}},$priv);                      push(@{$currprivs{$tool}},$priv);
                 }                  }
             }              }
Line 1985  sub display_defprivs { Line 2533  sub display_defprivs {
   
   
 sub change_members_form {  sub change_members_form {
     my ($r,$cdom,$cnum,$tabcol,$action,$formname,$page,$groupname,$description,      my ($r,$cdom,$cnum,$action,$formname,$page,$groupname,$description,
         $startdate,$enddate,$tools,$fixedprivs,$functions,$users,$userdata,          $startdate,$enddate,$tools,$fixedprivs,$functions,$users,$userdata,
         $granularity,$specificity,$idx,$states,$navbuttons,$rowColor1,          $granularity,$quota,$specificity,$idx,$states,$navbuttons,$gpterm,
         $rowColor2) = @_;   $ucgpterm) = @_;
     my %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
                                          grse => 'Group settings',                                           grse => "$ucgpterm settings",
                                          mogm => 'Modify group membership',                                           mogm => "Modify $gpterm membership",
                                         );                                          );
     my @regexps = ('user_','userpriv_');      my @regexps = ('user_','userpriv_');
     $r->print(&Apache::lonhtmlcommon::echo_form_input(      $r->print(&Apache::lonhtmlcommon::echo_form_input(
Line 2006  sub change_members_form { Line 2554  sub change_members_form {
     my $prevtext = $$navbuttons{'gtpp'};      my $prevtext = $$navbuttons{'gtpp'};
     $r->print('      $r->print('
 <br />  <br />
 <table width="100%" cellpadding="0" cellspacing="0" border="0">  
 ');  
     &topic_bar($r,$tabcol,1,$lt{'grse'});  
     $r->print('  
  <tr>  
   <td>&nbsp;</td>  
   <td colspan="3">  
 ');  
     &print_current_settings($r,$action,$tabcol,$rowColor1,$rowColor2,  
                             $functions,$startdate,$enddate,$groupname,  
                           $description,$granularity,\@available,\@unavailable);  
 $r->print('  
 </td></tr><tr><td colspan="4">&nbsp;</td></tr>');  
     &topic_bar($r,$tabcol,2,$lt{'mogm'});  
     $r->print('  
  <tr>  
   <td>&nbsp;</td>  
   <td colspan="3">  
 ');  ');
     &current_membership($r,$cdom,$cnum,$formname,$tabcol,$rowColor1,      $r->print(&Apache::lonhtmlcommon::topic_bar(1,$lt{'grse'}));
                         $rowColor2,$groupname,\@available,\@unavailable,      &print_current_settings($r,$action,$functions,$startdate,$enddate,
                         $fixedprivs,$granularity,$specificity);      $groupname,$description,$granularity,$quota,
     $r->print('</td>');      \@available,\@unavailable,$gpterm,$ucgpterm);
     &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext,      $r->print(&Apache::lonhtmlcommon::topic_bar(2,$lt{'mogm'}));
                         $$states{$action}[$page+1],$nexttext);      my $numcurrent = &current_membership($r,$cdom,$cnum,$formname,$groupname,
     $r->print('</table>');                                           \@available,\@unavailable,$fixedprivs,
                    $granularity,$specificity);
       if ($numcurrent > 0) {
           &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext,
                               $$states{$action}[$page+1],$nexttext);
       } else {
           &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext);
       }
     return;      return;
 }  }
   
 sub current_membership {  sub current_membership {
     my ($r,$cdom,$cnum,$formname,$tabcol,$rowColor1,$rowColor2,$groupname,      my ($r,$cdom,$cnum,$formname,$groupname,$available,$unavailable,
         $available,$unavailable,$fixedprivs,$granularity,$specificity) = @_;   $fixedprivs,$granularity,$specificity) = @_;
     my %membership = &Apache::lonnet::get_group_membership($cdom,$cnum,      my %membership = &Apache::lonnet::get_group_membership($cdom,$cnum,
                                                                    $groupname);                                                                     $groupname);
     my %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
                                           'actn' => 'Action?',                                            'actn' => 'Action?',
                                           'name' => 'Name',                                            'name' => 'Name',
                                           'usnm' => 'Username',                                            'usnm' => 'Username',
                                             'stid' => 'ID',
                                           'doma' => 'Domain',                                            'doma' => 'Domain',
                                           'stda' => 'Start Date',                                            'stda' => 'Start Date',
                                           'enda' => 'End Date',                                            'enda' => 'End Date',
Line 2051  sub current_membership { Line 2589  sub current_membership {
                                           'reen' => 'Re-enable',                                            'reen' => 'Re-enable',
                                           'acti' => 'Activate',                                            'acti' => 'Activate',
                                           'dele' => 'Delete',                                            'dele' => 'Delete',
                                           'curf' => 'Current Functionality',                                            'curf' => 'Current Tool Set',
                                           'chpr' => 'Change Privileges'                                             'chpr' => 'Change Privileges' 
                                         );                                          );
     if (keys(%membership) > 0) {      my ($current,$num_items,$hastools,$addtools) =
         my %current = ();          &Apache::longroup::group_memberlist($cdom,$cnum,$groupname,$fixedprivs,
         my %allnames = ();                                              $available);
         my $hastools = 0;      my $numcurrent = scalar(keys(%{$current}));
         my $addtools = 0;      if ($numcurrent > 0) {
         my $num_reenable = 0;          $r->print('
         my $num_activate = 0;  
         my $num_expire - 0;  
         foreach my $key (sort(keys(%membership))) {  
             if ($key =~ /^\Q$groupname\E:([^:]+):([^:]+)$/) {  
                 my $uname = $1;  
                 my $udom = $2;  
                 my $user = $uname.':'.$udom;  
                 my($end,$start,@userprivs) = split(/:/,$membership{$key});  
                 unless ($start == -1) {  
                     $allnames{$udom}{$uname} = 1;  
                     %{$current{$user}} = ();  
                     $current{$user}{uname} = $uname;  
                     $current{$user}{udom} = $udom;  
                     $current{$user}{start} =   
                                      &Apache::lonlocal::locallocaltime($start);  
                     if ($end == 0) {  
                         $current{$user}{end} =  'No end date';  
                     } else {  
                         $current{$user}{end} =   
                                      &Apache::lonlocal::locallocaltime($end);  
                     }  
                     my $now = time;  
                     if (($end > 0) && ($end < $now)) {  
                         $current{$user}{changestate} = 'reenable';  
                         $num_reenable++;  
                     } elsif (($start > $now)) {  
                         $current{$user}{changestate} = 'activate';  
                         $num_activate ++;  
                     } else {  
                         $current{$user}{changestate} = 'expire';  
                         $num_expire ++;  
                     }  
                     @{$current{$user}{currtools}} = ();  
                     @{$current{$user}{newtools}} = ();  
                     if (@userprivs > 0) {  
                         foreach my $tool (sort(keys(%{$fixedprivs}))) {  
                             foreach my $priv (keys(%{$$fixedprivs{$tool}})) {  
                                 if (grep/^$priv$/,@userprivs) {  
                                     push(@{$current{$user}{currtools}},$tool);  
                                     last;  
                                 }  
                             }  
                         }  
                         $hastools = 1;  
                     }  
                     if (@{$available} > 0) {  
                         if (@{$current{$user}{currtools}} > 0) {  
                             if ("@{$available}" ne "@{$current{$user}{currtools}}") {  
                                 foreach my $tool (@{$available}) {  
                                     unless (grep/^$tool$/,@{$current{$user}{currtools}}) {  
                                         push(@{$current{$user}{newtools}},$tool);  
                                     }  
                                 }  
                             }  
                         } else {  
                             @{$current{$user}{newtools}} = @{$available};  
                         }  
                         if (@{$current{$user}{newtools}} > 0) {  
                             $addtools = 1;  
                         }  
                     }  
                 }  
             }  
         }  
         if (keys(%current) > 0) {  
             my %idhash;  
             foreach my $udom (keys(%allnames)) {  
                 %{$idhash{$udom}} = &Apache::lonnet::idrget($udom,  
                                                 keys(%{$allnames{$udom}}));  
                 foreach my $uname (keys(%{$idhash{$udom}})) {  
                     $current{$uname.':'.$udom}{'id'} = $idhash{$udom}{$uname};  
                 }  
                 foreach my $uname (keys(%{$allnames{$udom}})) {  
                     $current{$uname.':'.$udom}{'fullname'} =  
                                 &Apache::loncommon::plainname($uname,$udom,  
                                                                   'lastname');  
                 }  
             }  
             $r->print('  
  <tr>  
   <td>&nbsp;</td>  
   <td colspan="2">  
    <table>     <table>
     <tr>');      <tr>');
             if ($num_expire) {          if ($num_items->{'active'}) {
                 &check_uncheck_buttons($r,$formname,'expire',$lt{'expi'});              &check_uncheck_buttons($r,$formname,'expire',$lt{'expi'});
             }          }
             if ($num_reenable) {          if ($num_items->{'previous'}) {
                 &check_uncheck_buttons($r,$formname,'reenable',$lt{'reen'});              &check_uncheck_buttons($r,$formname,'reenable',$lt{'reen'});
             }          }
             if ($num_activate) {          if ($num_items->{'future'}) {
                 &check_uncheck_buttons($r,$formname,'activate',$lt{'acti'});              &check_uncheck_buttons($r,$formname,'activate',$lt{'acti'});
           }
           &check_uncheck_buttons($r,$formname,'deletion',$lt{'dele'});
           if (@{$available} > 0) {
               if ($specificity eq 'Yes') {
                   &check_uncheck_buttons($r,$formname,'changepriv',$lt{'chpr'});
             }              }
             &check_uncheck_buttons($r,$formname,'deletion',$lt{'dele'});              if ($granularity eq 'Yes') {
             if (@{$available} > 0) {                  $r->print(&check_uncheck_tools($r,$available));
                 if ($specificity eq 'Yes') {                  $r->print('
                     &check_uncheck_buttons($r,$formname,'changepriv',$lt{'chpr'});  
                 }  
                 if ($granularity eq 'Yes') {  
                     $r->print(&check_uncheck_tools($r,$available));  
                     $r->print('  
      <td>       <td>
       <nobr>        <span class="LC_nobreak">
        <fieldset><legend><b>'.$lt{'curf'}.'</b></legend>         <fieldset><legend>'.$lt{'curf'}.'</legend>
        <input type="button" value="check all"         <input type="button" value="'.&mt('check all').'"
        onclick="javascript:checkAllTools(document.'.$formname.')" />         onclick="javascript:checkAllTools(document.'.$formname.')" />
        &nbsp;&nbsp;         &nbsp;&nbsp;
        <input type="button" value="uncheck all"         <input type="button" value="'.&mt('uncheck all').'"
         onclick="javascript:uncheckAllTools(document.'.$formname.')" />          onclick="javascript:uncheckAllTools(document.'.$formname.')" />
       </fieldset>        </fieldset>
      </nobr>       </span>
     </td>      </td>
 ');  ');
                 }  
             }              }
             $r->print(<<"END");          }
           $r->print(<<"END");
    </tr>     </tr>
   </table>    </table>
   </td>    <br />
   <td width="100%">&nbsp;</td>  
  </tr>  
  <tr>  
   <td colspan="4">&nbsp;</td>  
  </tr>  
  <tr>  
   <td>&nbsp;</td>  
   <td colspan="3">  
 END  END
             $r->print(&Apache::lonhtmlcommon::start_pick_box());          $r->print(&Apache::loncommon::start_data_table().
             $r->print(<<"END");    &Apache::loncommon::start_data_table_header_row());
    <table border="0" cellpadding="4" cellspacing="1">          $r->print(<<"END");
     <tr bgcolor="$tabcol" align="center">       <th>$lt{'actn'}</th>
      <td><b>$lt{'actn'}</b></td>       <th><a href="javascript:changeSort('fullname')">$lt{'name'}</a></th>
      <td><b><a href="javascript:changeSort('fullname')">$lt{'name'}</a></b></td>       <th><a href="javascript:changeSort('username')">$lt{'usnm'}</a></th>
      <td><b><a href="javascript:changeSort('username')">$lt{'usnm'}</a></b>       <th><a href="javascript:changeSort('domain')">$lt{'doma'}</a></th>
      </td>       <th><a href="javascript:changeSort('id')">$lt{'ID'}</a></th>
      <td><b><a href="javascript:changeSort('domain')">$lt{'doma'}</a></b></td>       <th><a href="javascript:changeSort('start')">$lt{'stda'}</a></th>
      <td><b><a href="javascript:changeSort('id')">ID</a></b></td>       <th><a href="javascript:changeSort('end')">$lt{'enda'}</a></th>
      <td><b><a href="javascript:changeSort('start')">$lt{'stda'}</a></b></td>  
      <td><b><a href="javascript:changeSort('end')">$lt{'enda'}</a></b></td>  
 END  END
             my $colspan = 0;          my $colspan = 0;
             if ($hastools) {          if ($hastools) {
                 $r->print('<td><b>'.$lt{'curf'}.'</b></td>');              $r->print('<th>'.$lt{'curf'}.'</th>');
                 $colspan ++;                $colspan++;  
             }          }
             if ($addtools) {          if ($addtools) {
                 $r->print('<td><b>Additional Functionality</b></td>');              $r->print('<th>'.&mt('Additional Tools').'</th>');
                 $colspan ++;              $colspan++;
             }          }
             $r->print('</tr>');          $r->print(&Apache::loncommon::end_data_table_header_row());
             if ($colspan) {          if ($colspan) {
                 if ($granularity eq 'Yes') {              if ($granularity eq 'Yes') {
                     $r->print('<tr bgcolor="#cccccc">                  $r->print(&Apache::loncommon::start_data_table_row('LC_data_table_dense LC_data_table_highlight').'
  <td colspan="7">&nbsp;</td>   <td colspan="7">&nbsp;</td>
  <td colspan="'.$colspan.'" align="center"><small><nobr><b>'.&mt('All:').   <td colspan="'.$colspan.'" align="center"><span class="LC_nobreak"><b>'.&mt('All:').
   '</b>&nbsp;');    '</b>&nbsp;');
                     foreach my $tool (@{$available}) {                  foreach my $tool (@{$available}) {
                         $r->print('<label><input type="checkbox" name="togglefunc"'.                      $r->print('<label><input type="checkbox" name="togglefunc"'.
    ' onclick="javascript:toggleTools(document.'.$formname.'.user_'.$tool.',this);"'.     ' onclick="javascript:toggleTools(document.'.$formname.'.user_'.$tool.',this);"'.
    ' value="'.$tool.'">'.'<b>'.$tool.'</b></label>&nbsp;&nbsp;&nbsp;');     ' value="'.$tool.'" />'.'<b>'.$tool.'</b></label>&nbsp;&nbsp;&nbsp;');
                     }  
                     $r->print('</nobr></small></td></tr>');  
                 }                  }
                   $r->print('</span></td></tr>');
             }              }
             my %Sortby = ();          }
             foreach my $user (sort(keys(%current))) {          my %Sortby = ();
                 if ($env{'form.sortby'} eq 'fullname') {          foreach my $user (sort(keys(%{$current}))) {
                     push(@{$Sortby{$current{$user}{fullname}}},$user);              if ($env{'form.sortby'} eq 'fullname') {
                 } elsif ($env{'form.sortby'} eq 'username') {                  push(@{$Sortby{$$current{$user}{fullname}}},$user);
                     push(@{$Sortby{$current{$user}{uname}}},$user);              } elsif ($env{'form.sortby'} eq 'username') {
                 } elsif ($env{'form.sortby'} eq 'domain') {                  push(@{$Sortby{$$current{$user}{uname}}},$user);
                     push(@{$Sortby{$current{$user}{udom}}},$user);              } elsif ($env{'form.sortby'} eq 'domain') {
                 } elsif ($env{'form.sortby'} eq 'id') {                  push(@{$Sortby{$$current{$user}{udom}}},$user);
                     push(@{$Sortby{$current{$user}{id}}},$user);              } elsif ($env{'form.sortby'} eq 'id') {
                 } else {                  push(@{$Sortby{$$current{$user}{id}}},$user);
                     push(@{$Sortby{$current{$user}{fullname}}},$user);              } else {
                 }                  push(@{$Sortby{$$current{$user}{fullname}}},$user);
             }              }
             my $rowNum = 0;          }
             my $rowColor;          foreach my $key (sort(keys(%Sortby))) {
             foreach my $key (sort(keys(%Sortby))) {              foreach my $user (@{$Sortby{$key}}) {
                 foreach my $user (@{$Sortby{$key}}) {                  my $id = $$current{$user}{id};
                     if ($rowNum %2 == 1) {                  my $fullname = $$current{$user}{fullname};
                         $rowColor = $rowColor1;                  my $udom = $$current{$user}{udom};
                     } else {                  my $uname = $$current{$user}{uname};
                         $rowColor = $rowColor2;                  my $start = $$current{$user}{start};
                     }                  my $end = $$current{$user}{end};
                     my $id = $current{$user}{id};                  $r->print(&Apache::loncommon::start_data_table_row('LC_data_table_dense').'
                     my $fullname = $current{$user}{fullname};                              <td>');
                     my $udom = $current{$user}{udom};                  if ($$current{$user}{changestate} eq 'reenable') {
                     my $uname = $current{$user}{uname};                      $r->print('<span class="LC_nobreak"><label>'. 
                     my $start = $current{$user}{start};  
                     my $end = $current{$user}{end};  
                     $r->print('<tr bgcolor="'.$rowColor.'">  
                                 <td><small>');  
                     if ($current{$user}{changestate} eq 'reenable') {  
                         $r->print('<nobr><label>'.   
    '<input type="checkbox" name="reenable" value="'.$user.'" />'.     '<input type="checkbox" name="reenable" value="'.$user.'" />'.
    $lt{'reen'}.'</label></nobr><br />');     $lt{'reen'}.'</label></span><br />');
                     } elsif ($current{$user}{changestate} eq 'expire') {                  } elsif ($$current{$user}{changestate} eq 'expire') {
                         $r->print('<nobr><label>'.                      $r->print('<span class="LC_nobreak"><label>'.
    '<input type="checkbox" name="expire" value="'.$user.'" />'.     '<input type="checkbox" name="expire" value="'.$user.'" />'.
    $lt{'expi'}.'</label></nobr><br />');     $lt{'expi'}.'</label></span><br />');
                     } elsif ($current{$user}{changestate} eq 'activate') {                  } elsif ($$current{$user}{changestate} eq 'activate') {
                         $r->print('<nobr><label>'.                      $r->print('<span class="LC_nobreak"><label>'.
    '<input type="checkbox" name="activate" value="'.$user.'" />'.     '<input type="checkbox" name="activate" value="'.$user.'" />'.
    $lt{'acti'}.'</label></nobr><br />');     $lt{'acti'}.'</label></span><br />');
                     }                  }
                     $r->print('<nobr><label>'.                  $r->print('<span class="LC_nobreak"><label>'.
    '<input type="checkbox" name="deletion" value="'.$user.'" />'.     '<input type="checkbox" name="deletion" value="'.$user.'" />'.
    $lt{'dele'}.'</label></nobr>');     $lt{'dele'}.'</label></span>');
                     if ($specificity eq 'Yes') {                  if ($specificity eq 'Yes') {
                         $r->print('<br /><nobr><label>'.                      $r->print('<br /><span class="LC_nobreak"><label>'.
    '<input type="checkbox" name="changepriv" value="'.$user.'" />'.$lt{'chpr'}.     '<input type="checkbox" name="changepriv" value="'.$user.'" />'.$lt{'chpr'}.
    '</label></nobr>');     '</label></span>');
                     }                  }
                     $r->print('                  $r->print('
    </td>     </td>'.
    <td><small>'.     '<td>'.$fullname.'</td>'.
     $fullname.'</small></td><td><small>'.$uname.'</small></td><td><small>'.     '<td>'.$uname.'</td>'.
     $udom.'</small></td><td><small>'.$id.'</small></td><td><small>'.$start.     '<td>'. $udom.'</td>'.
     '</small></td><td><small>'.$end.'</small></td>');     '<td>'.$id.'</td>'.
                     if ($hastools) {     '<td>'.$start.'</td>'.
                         $r->print('<td align="left"><small><nobr>'.     '<td>'.$end.'</td>');
                   if ($hastools) {
                       $r->print('<td align="left"><span class="LC_nobreak">'.
                                   '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;');                                    '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;');
                         foreach my $tool (@{$current{$user}{currtools}}) {                      foreach my $tool (@{$$current{$user}{currtools}}) {
                             if ($granularity eq 'Yes') {                          if ($granularity eq 'Yes') {
                                 $r->print('<label><input type="checkbox" '.                               $r->print('<label><input type="checkbox" '. 
                                        'checked="checked" '.                                          'checked="checked" '. 
                                        'name="user_'.$tool.'" value="'.                                         'name="user_'.$tool.'" value="'.
                                        $user.'" />'.$tool.'</label>');                                         $user.'" />'.$tool.'</label>');
                              } else {                           } else {
                                $r->print('<input type="hidden" '.                               $r->print('<input type="hidden" '.
                                        'checked="checked" '.                                         'checked="checked" '.
                                        'name="user_'.$tool.'" value="'.                                         'name="user_'.$tool.'" value="'.
                                        $user.'" />'.$tool);                                         $user.'" />'.$tool);
                              }                           }
                              $r->print('&nbsp;&nbsp;&nbsp;');                           $r->print('&nbsp;&nbsp;&nbsp;');
                         }  
                         $r->print('</nobr></small></td>');  
                     }                      }
                     if ($addtools) {                      $r->print('</span></td>');
                         $r->print('<td align="left"><small>');                  }
                         if ($granularity eq 'Yes') {                  if ($addtools) {
                             foreach my $tool (@{$current{$user}{newtools}}) {                      $r->print('<td align="left">');
                                 $r->print('<nobr><label><input type="checkbox"                        if ($granularity eq 'Yes') {
                           foreach my $tool (@{$$current{$user}{newtools}}) {
                               $r->print('<span class="LC_nobreak"><label><input type="checkbox"
                                           name="user_'.$tool.'" value="'.                                            name="user_'.$tool.'" value="'.
                                           $user.'" />'.$tool.                                            $user.'" />'.$tool.
                                           '</label></nobr>&nbsp;&nbsp;&nbsp;');                                            '</label></span>&nbsp;&nbsp;&nbsp;');
                             }                          }
                         } else {                      } else {
                             foreach my $tool (@{$current{$user}{newtools}}) {                          foreach my $tool (@{$$current{$user}{newtools}}) {
                                 $r->print('<nobr><input type="hidden"                               $r->print('<span class="LC_nobreak"><input type="hidden" 
                                           name="user_'. $tool.'" value="'.                                            name="user_'. $tool.'" value="'.
                                           $user.'" />'.$tool.                                            $user.'" />'.$tool.
                                           '</nobr>&nbsp;&nbsp;&nbsp;');                                            '</span>&nbsp;&nbsp;&nbsp;');
                             }  
                         }                          }
                         $r->print('</small></td>');  
                     }                      }
                     $r->print('</tr>'."\n");                      $r->print('</td>');
                     $rowNum ++;  
                 }                  }
                   $r->print(&Apache::loncommon::end_data_table_row()."\n");
             }              }
             $r->print(&Apache::lonhtmlcommon::end_pick_box());  
             $r->print('  
   </td>  
  </tr>');  
         }          }
           $r->print(&Apache::loncommon::end_data_table());
       } else {
           $r->print(
               '<p class="LC_info">'
              .&mt('There are no active, future or previous group members to modify.')
              .'</p>');
     }      }
     return;      return $numcurrent;
 }  }
   
 sub check_uncheck_buttons {  sub check_uncheck_buttons {
     my ($r,$formname,$field,$title,$colspan) = @_;      my ($r,$formname,$field,$title,$colspan) = @_;
     $r->print('      $r->print('
      <td '.$colspan.'>       <td '.$colspan.'>
       <nobr>  
        <fieldset>         <fieldset>
        <legend><b>'.$title.'</b></legend>         <legend>'.$title.'</legend>
        <input type="button" value="check all"        <span class="LC_nobreak">
          <input type="button" value="'.&mt('check all').'"
        onclick="javascript:checkAll(document.'.$formname.'.'.$field.')" />         onclick="javascript:checkAll(document.'.$formname.'.'.$field.')" />
        &nbsp;&nbsp;         &nbsp;&nbsp;
        <input type="button" value="uncheck all"         <input type="button" value="'.&mt('uncheck all').'"
        onclick="javascript:uncheckAll(document.'.$formname.'.'.$field.')" />         onclick="javascript:uncheckAll(document.'.$formname.'.'.$field.')" />
         </span>
        </fieldset>         </fieldset>
       </nobr>  
      </td>       </td>
 ');  ');
 }  }
   
   
 sub change_privs_form {  sub change_privs_form {
     my ($r,$cdom,$cnum,$tabcol,$action,$formname,$page,$startdate,$enddate,      my ($r,$cdom,$cnum,$action,$formname,$page,$startdate,$enddate,
        $tools,$functions,$toolprivs,$fixedprivs,$userdata,$usertools,   $tools,$functions,$toolprivs,$fixedprivs,$userdata,$usertools,
        $memchg,$idx,$states,$stored,$sectioncount,$navbuttons,$rowColor1,   $memchg,$idx,$states,$stored,$sectioncount,$navbuttons,$gpterm,
        $rowColor2) = @_;   $ucgpterm) = @_;
     my @regexps = ('userpriv_');      my @regexps = ('userpriv_');
     my $nexttext;      my $nexttext;
     my %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
                'tode' => 'To be deleted',                 'tode' => 'To be deleted',
                'toex' => 'To be expired',                 'toex' => 'To be expired',
                'nome' => 'No members to be deleted or expired from the group.',                 'nome' => "No members to be deleted or expired from the $gpterm.",
     );      );
     $r->print(&Apache::lonhtmlcommon::echo_form_input(      $r->print(&Apache::lonhtmlcommon::echo_form_input(
          ['origin','action','state','page','sortby'],\@regexps));           ['origin','action','state','page','sortby'],\@regexps));
Line 2372  sub change_privs_form { Line 2813  sub change_privs_form {
     } else {      } else {
         $nexttext = $$navbuttons{'mose'};          $nexttext = $$navbuttons{'mose'};
     }      }
     $r->print('<br /><table width="100%" cellpadding="0" cellspacing="0" border="0">');      $r->print(&Apache::lonhtmlcommon::topic_bar(3,&mt('Members to delete or expire')));
     &topic_bar($r,$tabcol,3,&mt('Members to delete or expire'));  
     my $exp_or_del = 0;      my $exp_or_del = 0;
     if (ref($$memchg{'deletion'}) eq 'ARRAY') {      if (ref($$memchg{'deletion'}) eq 'ARRAY') {
         if (@{$$memchg{'deletion'}} > 0) {          if (@{$$memchg{'deletion'}} > 0) {
             $r->print('<tr><td>&nbsp;</td><td colspan="3"><b>'.$lt{'tode'}.':</b><br /><ul>');              $r->print('<b>'.$lt{'tode'}.':</b><br /><ul>');
             foreach my $user (@{$$memchg{'deletion'}}) {              foreach my $user (@{$$memchg{'deletion'}}) {
                 $r->print('<li>'.$$userdata{$user}[$$idx{fullname}].                  $r->print('<li>'.$$userdata{$user}[$$idx{fullname}].
                           '&nbsp;('.$user.')</li>');                            '&nbsp;('.$user.')</li>');
             }              }
             $r->print('</ul></td><tr><td colspan="4">&nbsp;</td></tr>');              $r->print('</ul>');
             $exp_or_del += @{$$memchg{'deletion'}};              $exp_or_del += @{$$memchg{'deletion'}};
         }          }
     }      }
     if (ref($$memchg{'expire'}) eq 'ARRAY') {      if (ref($$memchg{'expire'}) eq 'ARRAY') {
         if (@{$$memchg{'expire'}} > 0) {          if (@{$$memchg{'expire'}} > 0) {
             $r->print('<tr><td>&nbsp;</td><td colspan="3"><b>'.$lt{'toex'}.':</b><br /><ul>');              $r->print('<b>'.$lt{'toex'}.':</b><br /><ul>');
             foreach my $user (@{$$memchg{'expire'}}) {              foreach my $user (@{$$memchg{'expire'}}) {
                 $r->print('<li>'.$$userdata{$user}[$$idx{fullname}].                  $r->print('<li>'.$$userdata{$user}[$$idx{fullname}].
                           '&nbsp;('.$user.')</li>');                            '&nbsp;('.$user.')</li>');
             }              }
             $r->print('</ul></td><tr><td colspan="4">&nbsp;</td></tr>');              $r->print('</ul>');
             $exp_or_del += @{$$memchg{'expire'}};              $exp_or_del += @{$$memchg{'expire'}};
         }          }
     }      }
     if (!$exp_or_del) {      if (!$exp_or_del) {
         $r->print('<tr><td>&nbsp;</td><td colspan="3">'.$lt{'nome'}.          $r->print('<p class="LC_info">'.$lt{'nome'}.'</p>');
                   '</td></tr><tr><td colspan="4">&nbsp;</td></tr>');  
     }      }
           
     &topic_bar($r,$tabcol,4,&mt('Group member privileges'));      $r->print(&Apache::lonhtmlcommon::topic_bar(4,&mt('Setting optional privileges for specific group members')));
   
     my $numchgs = &member_privileges_form($r,$tabcol,$action,$formname,$tools,      my $numchgs = &member_privileges_form($r,$action,$formname,$tools,
                                           $toolprivs,$fixedprivs,$userdata,                                            $toolprivs,$fixedprivs,$userdata,
                                           $usertools,$idx,$memchg,$states,                                            $usertools,$idx,$memchg,$states,
                                           $stored,$rowColor1,$rowColor2);                                            $stored,$gpterm);
     $r->print('</td></tr><tr><td colspan="4">&nbsp;</td></tr>');  
     my $prevtext = $$navbuttons{'gtps'};      my $prevtext = $$navbuttons{'gtps'};
     if ($numchgs || $exp_or_del) {      if ($numchgs || $exp_or_del) {
         &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext,          &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext,
Line 2416  sub change_privs_form { Line 2854  sub change_privs_form {
     } else {      } else {
         &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext);          &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext);
     }      }
     $r->print('</table>');  
     return;      return;
 }  }
   
 sub add_members_form {  sub add_members_form {
     my ($r,$tabcol,$action,$formname,$page,$startdate,$enddate,$groupname,      my ($r,$cdom,$cnum,$action,$formname,$page,$startdate,$enddate,$groupname,
         $description,$granularity,$sectioncount,$tools,$functions,$stored,          $description,$granularity,$quota,$sectioncount,$tools,$functions,
         $states,$navbuttons,$rowColor1,$rowColor2) = @_;           $stored,$states,$navbuttons,$gpterm,$ucgpterm,$crstype)=@_;
     $r->print(' <br />      $r->print(' <br />');
 <table width="100%" cellpadding="0" cellspacing="0" border="0">  
  <tr>  
   <td>&nbsp;</td>  
   <td colspan="3">  
 ');  
     my @available = ();      my @available = ();
     my @unavailable = ();      my @unavailable = ();
     &check_tools($functions,$tools,\@available,\@unavailable);      &check_tools($functions,$tools,\@available,\@unavailable);
     &print_current_settings($r,$action,$tabcol,$rowColor1,$rowColor2,      &print_current_settings($r,$action,$functions,$startdate,$enddate,
                             $functions,$startdate,$enddate,$groupname,      $groupname,$description,$granularity,$quota,
                             $description,$granularity,\@available,\@unavailable);      \@available,\@unavailable,$gpterm,$ucgpterm);
     $r->print('      &membership_options($r,$cdom,$cnum,$action,$formname,$sectioncount,1,$gpterm,
    </td>                          $ucgpterm,$crstype);
   </tr>  
   <tr>  
    <td colspan="4">&nbsp;</td>  
   </tr>');  
   
     &membership_options($r,$action,$formname,$tabcol,$sectioncount,1);  
     my $nexttext = $$navbuttons{'gtns'};      my $nexttext = $$navbuttons{'gtns'};
     my $prevtext = $$navbuttons{'gtpp'};      my $prevtext = $$navbuttons{'gtpp'};
     &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext,      &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext,
                         $$states{$action}[$page+1],$nexttext);                          $$states{$action}[$page+1],$nexttext);
     $r->print('  
  </table>');  
     return;      return;
 }  }
   
 sub choose_privs_form {  sub choose_privs_form {
     my ($r,$cdom,$cnum,$tabcol,$action,$formname,$page,$startdate,$enddate,      my ($r,$cdom,$cnum,$action,$formname,$page,$startdate,$enddate,
        $tools,$functions,$toolprivs,$fixedprivs,$userdata,$usertools,$idx,   $tools,$functions,$toolprivs,$fixedprivs,$userdata,$usertools,$idx,
        $states,$stored,$sectioncount,$navbuttons,$rowColor1,$rowColor2) = @_;   $states,$stored,$sectioncount,$navbuttons,$gpterm,$ucgpterm,
    $crstype) = @_;
   
     my @regexps = ('userpriv_');      my @regexps = ('userpriv_');
     my $nexttext;      my $nexttext;
Line 2473  sub choose_privs_form { Line 2898  sub choose_privs_form {
         $nexttext = $$navbuttons{'adme'};          $nexttext = $$navbuttons{'adme'};
     }      }
   
     $r->print('<br /><table width="100%" cellpadding="0" cellspacing="0" border="0">');      $r->print(&Apache::lonhtmlcommon::topic_bar(6,&mt('Setting optional privileges for specific group members')));
     &topic_bar($r,$tabcol,6,&mt('Group member privileges'));  
   
     &member_privileges_form($r,$tabcol,$action,$formname,$tools,$toolprivs,      &member_privileges_form($r,$action,$formname,$tools,$toolprivs,
                             $fixedprivs,$userdata,$usertools,$idx,undef,                              $fixedprivs,$userdata,$usertools,$idx,undef,
                             $states,$stored,$rowColor1,$rowColor2);                              $states,$stored,$gpterm);
   
     $r->print('</td></tr><tr><td colspan="4">&nbsp;</td></tr>');  
     if ($action eq 'create') {      if ($action eq 'create') {
         if (keys(%{$sectioncount}) > 0) {          my $img1 = 7;
             my $img1 = 7;          my $img2 = 8;
             my $img2 = 8;          &mapping_options($r,$action,$formname,$page,$sectioncount,
             &mapping_options($r,$action,$formname,$page,$tabcol,$sectioncount,                           $states,$stored,$navbuttons,$img1,$img2,
                              $states,$stored,$navbuttons,$img1,$img2,                           $gpterm,$ucgpterm,$crstype,$cdom,$cnum);
                              $rowColor1,$rowColor2);  
         }  
     }      }
     my $prevtext = $$navbuttons{'gtps'};      my $prevtext = $$navbuttons{'gtps'};
     &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext,      &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext,
                         $$states{$action}[$page+1],$nexttext);                          $$states{$action}[$page+1],$nexttext);
     $r->print('</table>');  
     return;      return;
 }  }
   
Line 2556  function uncheckAllTools(formname) { Line 2976  function uncheckAllTools(formname) {
 }  }
   
 sub member_privileges_form {  sub member_privileges_form {
     my ($r,$tabcol,$action,$formname,$tools,$toolprivs,$fixedprivs,$userdata,      my ($r,$action,$formname,$tools,$toolprivs,$fixedprivs,$userdata,
         $usertools,$idx,$memchg,$states,$stored,$rowColor1,$rowColor2) = @_;          $usertools,$idx,$memchg,$states,$stored,$gpterm) = @_;
     my %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
             'addp' => 'Additional privileges',              'addp' => 'Additional privileges',
             'fixp' => 'Fixed privileges',              'fixp' => 'Core privileges',
             'oppr' => 'Optional privileges',              'oppr' => 'Optional privileges',
             'func' => 'Function',              'func' => 'Tool',
             'forf' => 'For the functionality you have chosen to include '.              'forf' => 'For the collaborative tools included for group '.
                       'there are no optional privileges to set besides '.                        'members being added or modified, '. 
                       'the standard privileges.',                        'there are no optional privileges to set '.
             'algr' => 'All group members will receive the same privileges.',                        'for specific members.',
               'algr' => 'All new group members will receive the same privileges.',
               'ifex' => 'If previously expired members are being re-enabled, or '.
                         'if access for future members is being activated now, '.
                         'previously set privileges will be preserved.',
             'asno' => 'As no group members are being added, '.              'asno' => 'As no group members are being added, '.
                       'there are no specific user privileges to set.',                        'there are no specific user privileges to set.',
             'asng' => 'As no group tools will be made available to users, '.              'asng' => 'As no group tools will be made available to users, '.
Line 2574  sub member_privileges_form { Line 2998  sub member_privileges_form {
             'nogm' => 'No group member privileges to display or set, '.              'nogm' => 'No group member privileges to display or set, '.
                       'as you have not indicated that you will be activating,'.                        'as you have not indicated that you will be activating,'.
                       ' re-enabling, changing privileges, or adding/removing '.                        ' re-enabling, changing privileges, or adding/removing '.
                       'functionality for any current members ',                        'tools for any current members.',
             'full' => 'Fullname',              'full' => 'Fullname',
             'user' => 'Username',              'user' => 'Username',
             'doma' => 'Domain',              'doma' => 'Domain',
Line 2587  sub member_privileges_form { Line 3011  sub member_privileges_form {
         }          }
         $specificity = $env{'form.specificity'};          $specificity = $env{'form.specificity'};
     } else {      } else {
         @defprivs = @{$$stored{'defpriv'}};          if (defined($$stored{'defpriv'})) {
               @defprivs = @{$$stored{'defpriv'}};
           }
         $specificity = $$stored{'specificity'};          $specificity = $$stored{'specificity'};
     }      }
     my @showtools;      my @showtools;
Line 2616  sub member_privileges_form { Line 3042  sub member_privileges_form {
         }          }
         $numchgs = @currmembers;          $numchgs = @currmembers;
         if (!$numchgs) {          if (!$numchgs) {
             $r->print('<tr><td>&nbsp;</td><td colspan="3">'.$lt{'nogm'});               $r->print($lt{'nogm'}); 
             return $numchgs;              return $numchgs;
         }          }
     }      }
Line 2632  sub member_privileges_form { Line 3058  sub member_privileges_form {
                 my %total;                  my %total;
                 if (keys(%{$usertools}) > 1) {                  if (keys(%{$usertools}) > 1) {
                     $r->print('                      $r->print('
  <tr>     <table border="0" cellspacing="2" cellpadding="2">
   <td>&nbsp;</td>  
   <td colspan="3">  
    <table border="0" cellspacing="2" cellpadding="2" border="0">  
     <tr>      <tr>
 ');  ');
                     foreach my $tool (@{$tools}) {                      foreach my $tool (@{$tools}) {
                         if (@{$showboxes{$tool}} > 0) {                          if (@{$showboxes{$tool}} > 0) {
                             $r->print('<td valign="top">');                              $r->print('<td valign="top">');
                             $r->print('<table class="thinborder"><tr bgcolor="'.                              $r->print('<fieldset><legend>'.&mt($tool).'</legend>');
                                       $tabcol.'"><th colspan="'.$colspan.'">'.                              $r->print('<table><tr>');
                                       $tool.'</th></tr><tr>');  
                             my $privcount = 0;                              my $privcount = 0;
                             foreach my $priv (@{$showboxes{$tool}}) {                              foreach my $priv (@{$showboxes{$tool}}) {
                                 $privcount ++;                                  $privcount ++;
Line 2657  sub member_privileges_form { Line 3079  sub member_privileges_form {
                                 } else {                                  } else {
                                     $r->print('<td>');                                      $r->print('<td>');
                                 }                                  }
                                 $r->print(qq|                                  $r->print(
        <fieldset><legend><b>$$toolprivs{$tool}{$priv}</b></legend>   '<fieldset><legend>'.&mt($$toolprivs{$tool}{$priv}).'</legend>'
        <nobr>  .'<span class="LC_nobreak">'
        <input type="button" value="check all"  .' <input type="button" value="'.&mt('check all').'"'
          onclick="javascript:checkAll(document.$formname.userpriv_$priv)" />  .' onclick="javascript:checkAll(document.'.$formname.'.userpriv_'.$priv.')" />'
        &nbsp;  .'&nbsp;'
        <input type="button" value="uncheck all"  .'<input type="button" value="'.&mt('uncheck all').'"'
         onclick="javascript:uncheckAll(document.$formname.userpriv_$priv)" />  .' onclick="javascript:uncheckAll(document.'.$formname.'.userpriv_'.$priv.')" />'
       </nobr></fieldset><br />|);  .'</span></fieldset><br />'
                                   );
                                 $r->print('</td>');                                  $r->print('</td>');
                                 if ($privcount < @{$showboxes{$tool}}) {                                  if ($privcount < @{$showboxes{$tool}}) {
                                     if (@{$showboxes{$tool}} > 2) {                                      if (@{$showboxes{$tool}} > 2) {
Line 2677  sub member_privileges_form { Line 3100  sub member_privileges_form {
                                     }                                      }
                                 }                                  }
                             }                              }
                             $r->print('</tr></table></td><td>&nbsp;</td>');                              $r->print('</tr></table></fieldset></td><td>&nbsp;</td>');
                         }                          }
                     }                      }
                     $r->print('</tr></table></td></tr>');                      $r->print('</tr></table>');
                     $r->print('<tr><td colspan="4">&nbsp;</td></tr>');  
                 }                  }
                 $r->print('<tr><td>&nbsp;</td><td colspan="3">');                  $r->print(&Apache::loncommon::start_data_table().
                 $r->print(&Apache::lonhtmlcommon::start_pick_box());    &Apache::loncommon::start_data_table_header_row());
                 $r->print(<<"END");                  $r->print(<<"END");
    <tr bgcolor="$tabcol">      <th>$lt{'full'}</th>
     <th><b>$lt{'full'}</th>      <th>$lt{'user'}</th>
     <th><b>$lt{'user'}</th>  
     <th>$lt{'doma'}</th>      <th>$lt{'doma'}</th>
     <th colspan="$numtools">$lt{'addp'}</th>      <th colspan="$numtools">$lt{'addp'}</th>
   </tr>  
 END  END
                 &member_privs_entries($r,$tabcol,$rowColor1,$rowColor2,                  $r->print(&Apache::loncommon::end_data_table_header_row());
                                       $usertools,$toolprivs,$fixedprivs,                  &member_privs_entries($r,$usertools,$toolprivs,$fixedprivs,
                                       $userdata,$idx,\@showtools,\@defprivs,                                        $userdata,$idx,\@showtools,\@defprivs,
                                       \@excluded);                                        \@excluded);
                 $r->print('</td>');                  $r->print(&Apache::loncommon::end_data_table());
                 $r->print(&Apache::lonhtmlcommon::end_pick_box());  
                 $r->print('</td></tr>  
  <tr>  
   <td colspan="4">&nbsp;</td>  
  </tr>  
 ');  
             } else {              } else {
                 $r->print('<tr><td>&nbsp;</td><td colspan="3">'.$lt{'forf'}.                  $r->print($lt{'forf'}.'<br />');
                           '<br />');                  &display_defprivs($r,$tools,$toolprivs,\@defprivs);
                 &display_defprivs($r,$tabcol,$rowColor1,$rowColor2,$tools,  
                             $toolprivs,\@defprivs);  
                                                                                         
             }              }
         } else {          } else {
             if (keys(%{$usertools}) > 0) {              if (keys(%{$usertools}) > 0) {
                 $r->print('<tr><td>&nbsp;</td><td colspan="3">'.$lt{'algr'}.                  $r->print($lt{'algr'}.'<br />'.$lt{'ifex'}.'<br /><br />');
                           '<br /><br />');                  &display_defprivs($r,$tools,$toolprivs,\@defprivs);
                 &display_defprivs($r,$tabcol,$rowColor1,$rowColor2,$tools,  
                             $toolprivs,\@defprivs);  
             } else {              } else {
                 $r->print('<tr><td>&nbsp;</td><td colspan="3">'.$lt{'asno'}.                  $r->print($lt{'asno'}.'<br />');
                           '<br />');  
             }              }
         }          }
     } else {      } else {
         $r->print('<tr><td>&nbsp;</td><td colspan="3">'.$lt{'asng'});          $r->print($lt{'asng'});
     }      }
     return $numchgs;      return $numchgs;
 }  }
   
 sub process_request {  sub process_request {
     my ($r,$cdom,$cnum,$tabcol,$action,$state,$page,$groupname,$description,      my ($r,$cdom,$cnum,$action,$state,$page,$groupname,$description,
         $specificity,$userdata,$startdate,$enddate,$tools,$functions,$toolprivs,          $specificity,$userdata,$startdate,$enddate,$tools,$functions,$toolprivs,
         $usertools,$idx,$types,$roles,$sections,$states,$navbuttons,$memchg,          $usertools,$idx,$types,$roles,$sections,$states,$navbuttons,$memchg,
         $sectioncount,$stored,$rowColor1,$rowColor2) = @_;          $sectioncount,$stored,$gpterm,$ucgpterm,$crstype) = @_;
   
     $r->print(&Apache::lonhtmlcommon::echo_form_input(      $r->print(&Apache::lonhtmlcommon::echo_form_input(
                                  ['origin','action','state','page','sortby']));                                   ['origin','action','state','page','sortby']));
   
     my $earlyout = &validate_groupname($groupname,$action,$cdom,$cnum);      my $earlyout = &validate_groupname($groupname,$action,$cdom,$cnum,$gpterm,
                                          $ucgpterm,$crstype);
     if ($earlyout) {      if ($earlyout) {
         $r->print('          $r->print('
 <table width="100%" cellpadding="0" cellspacing="0" border="0">  <table width="100%" cellpadding="0" cellspacing="0" border="0">
Line 2772  sub process_request { Line 3181  sub process_request {
             @defprivs = @temp;               @defprivs = @temp; 
         }          }
     } else {      } else {
         @defprivs = @{$$stored{'defpriv'}};          if (defined($$stored{'defpriv'})) {
               @defprivs = @{$$stored{'defpriv'}};
           }
     }      }
   
     my $outcome;      my $outcome;
Line 2781  sub process_request { Line 3192  sub process_request {
                                      $description,$startdate,$enddate,                                       $description,$startdate,$enddate,
                                      $specificity,$functions,$tools,                                       $specificity,$functions,$tools,
                                      $sectioncount,$roles,$types,$sections,                                       $sectioncount,$roles,$types,$sections,
                                      \@defprivs,$stored);                                        \@defprivs,$stored,$gpterm,$ucgpterm,
                                        $crstype); 
     }      }
     if (($action eq 'create' && $outcome eq 'ok') || (($action eq 'modify') &&       if (($action eq 'create' && $outcome eq 'ok') || (($action eq 'modify') && 
        (($state eq 'memresult') || ($state eq 'addresult')))) {         (($state eq 'memresult') || ($state eq 'addresult')))) {
         &process_membership($r,$cdom,$cnum,$action,$state,$groupname,$tools,          &process_membership($r,$cdom,$cnum,$action,$state,$groupname,$tools,
                             $enddate,$startdate,$userdata,$idx,$toolprivs,                              $enddate,$startdate,$userdata,$idx,$toolprivs,
                             $usertools,$specificity,\@defprivs,$memchg);                              $usertools,$specificity,\@defprivs,$memchg,$gpterm,
                               $ucgpterm,$crstype);
     }      }
     return;      return;
 }  }
Line 2795  sub process_request { Line 3208  sub process_request {
 sub write_group_data {  sub write_group_data {
     my ($r,$cdom,$cnum,$action,$state,$groupname,$description,$startdate,      my ($r,$cdom,$cnum,$action,$state,$groupname,$description,$startdate,
         $enddate,$specificity,$functions,$tools,$sectioncount,$roles,$types,          $enddate,$specificity,$functions,$tools,$sectioncount,$roles,$types,
         $sections,$defprivs,$stored) = @_;          $sections,$defprivs,$stored,$gpterm,$ucgpterm,$crstype) = @_;
     my $now = time;      my $now = time;
     my $creation = $now;      my $creation = $now;
     my $creator = $env{'user.name'}.':'.$env{'user.domain'};      my $creator = $env{'user.name'}.':'.$env{'user.domain'};
Line 2803  sub write_group_data { Line 3216  sub write_group_data {
         $creation = $$stored{'creation'};          $creation = $$stored{'creation'};
         $creator = $$stored{'creator'};          $creator = $$stored{'creator'};
     }      }
     my $esc_description = &Apache::lonnet::escape($description);      my $esc_description = &escape($description);
     my @single_attributes = ('description','functions','startdate','enddate',      my @single_attributes = ('description','functions','startdate','enddate',
                              'creation','modified','creator','granularity',                               'creation','modified','creator','granularity',
                              'specificity','autoadd','autodrop');                               'specificity','autoadd','autodrop','quota');
     my @mult_attributes = ('roles','types','sectionpick','defpriv');      my @mult_attributes = ('roles','types','sectionpick','defpriv');
                                                                                       
       my ($crsquota,$freespace,$maxposs) = &get_quota_constraints($action,
                                                                   $stored);
       my $quota = $env{'form.quota'};
       
       $quota =~ s/^\s*([^\s]*)\s*$/$1/;
       if ($quota eq '') {
           $quota = 0;
       }
       if ($quota !~ /^\d*\.?\d*$/) {
           $quota = 0;
           $r->print('<div class="LC_warning">'
                    .&mt('The value you entered for the quota for the group portfolio in this '.$gpterm
                    .' contained invalid characters, so it has been set to 0 MB. You can change this by'
                    .' modifying the '.$gpterm.' settings.')
                    .'</div>');
       }
       if ($quota > $maxposs) {
           $quota = $maxposs;
           $r->print('<div class="LC_warning">'
                    .&mt('The value you entered for the quota for the group portfolio in this '.$gpterm
                    .' exceeded the maximum possible value, so it has been set to [_1] MB '
                    .'(the maximum possible value).',sprintf("%.2f",$maxposs))
                    .'</div>');
       }
     my %groupinfo = (      my %groupinfo = (
                      description => $esc_description,                       description => $esc_description,
                      startdate => $startdate,                       startdate => $startdate,
Line 2820  sub write_group_data { Line 3257  sub write_group_data {
                      specificity => $specificity,                       specificity => $specificity,
                      autoadd => $env{'form.autoadd'},                       autoadd => $env{'form.autoadd'},
                      autodrop => $env{'form.autodrop'},                       autodrop => $env{'form.autodrop'},
                        quota => $quota,
                    );                     );
   
     foreach my $func (keys(%{$functions})) {      foreach my $func (keys(%{$functions})) {
         my $status;          my $status;
         if (grep(/^$func$/,@{$tools})) {          if (grep(/^$func$/,@{$tools})) {
Line 2847  sub write_group_data { Line 3286  sub write_group_data {
     }      }
     my $autosec;      my $autosec;
     my @autorole = &Apache::loncommon::get_env_multiple('form.autorole');      my @autorole = &Apache::loncommon::get_env_multiple('form.autorole');
                                                                                       
     foreach my $role (@autorole) {      foreach my $role (@autorole) {
         if (defined($env{'form.sec_'.$role})) {          if (defined($env{'form.sec_'.$role})) {
             my @autosections=&Apache::loncommon::get_env_multiple('form.sec_'.              my @autosections=&Apache::loncommon::get_env_multiple('form.sec_'.
                                                                   $role);                                                                    $role);
             if (grep/^_all$/,@autosections) {  
                 @autosections = sort {$a cmp $b} keys(%{$sectioncount});  
             }  
             $autosec .= '<role id="'.$role.'">';              $autosec .= '<role id="'.$role.'">';
             foreach my $sec (@autosections) {              foreach my $sec (@autosections) {
                 $autosec .= '<section>'.$sec.'</section>';                  $autosec .= '<section>'.$sec.'</section>';
Line 2870  sub write_group_data { Line 3306  sub write_group_data {
   
     if ($result eq 'ok') {      if ($result eq 'ok') {
         if ($action eq 'create') {          if ($action eq 'create') {
             my $put_result = &create_homepage($cdom,$cnum,$groupname,              my $result = &add_group_folder($cdom,$cnum,$now,$groupname,$action,
                                               \%groupinfo,$tools);                                             $description,$tools,\%groupinfo,
             $r->print('Group '.$groupname.' was created.<br />');                                             $gpterm,$ucgpterm,$crstype);
         } else {              if ($result eq 'ok') {
             $r->print('Group '.$groupname.' was updated.<br />');                  my $msg = &Apache::lonhtmlcommon::confirm_success(&mt($ucgpterm.' [_1] was created.','<i>'.$groupname.'</i>'));
                   $msg = &Apache::loncommon::confirmwrapper($msg);
                   $r->print($msg);
               } else {
                   my $msg = &Apache::lonhtmlcommon::confirm_success(&mt('A problem occurred when creating folders for the new '.$gpterm.' [_1]:'
                                                                        ,'<i>'.$groupname.'</i>')
                                                                        .'<br />'.$result,1);
                   $msg = &Apache::loncommon::confirmwrapper($msg);
                   $r->print($msg);
               }
           } elsif ($action eq 'modify') {
               my (@oldtools,@newtools); 
               if (ref($$stored{'tool'}) eq 'ARRAY') {
                   @oldtools = @{$$stored{'tool'}};
               }
               if (ref($tools) eq 'ARRAY') {
                   @newtools = @{$tools};
               }
               if (!grep(/^discussion$/,@oldtools) && 
                    grep(/^discussion$/,@newtools)) {
                   my $crspath = '/uploaded/'.$cdom.'/'.$cnum.'/';
                   my $boardsmap = $crspath.'group_boards_'.$groupname.'.sequence';
                   my $navmap = Apache::lonnavmaps::navmap->new();
                   my ($bbmapres,$error);
                   if (defined($navmap)) {
                       $bbmapres = $navmap->getResourceByUrl($boardsmap);
                       undef($navmap);
                       if (!$bbmapres) {
                           my $grpmap = $crspath.'group_folder_'.$groupname.'.sequence';
                           my $disctitle = &mt('Discussion Boards');
                           my $outcome = &map_updater($cdom,$cnum,'group_boards_'.
                                                      $groupname.'.sequence','bbseq',
                                                      $disctitle,$grpmap);
                           my ($furl,$ferr) = 
                               &Apache::lonuserstate::readmap($cdom.'/'.$cnum);
                           # modify parameter
                           if ($outcome eq 'ok') {
                               $navmap = Apache::lonnavmaps::navmap->new();
                               if (defined($navmap)) {
                                   my $parm_result = &parm_setter($navmap,$cdom,$boardsmap,
                                                                  $groupname);
                                   if ($parm_result) {
                                       $error = &mt('An error occurred while setting parameters '
                                                .'for Discussion Boards folder: '
                                                .'[_1]',$parm_result);
                                   } else {
                                       $r->print('<div class="LC_success">'.
                                                 &mt('Discussion Boards Folder created.')
                                                 .'</div>');
                                   }
                                   undef($navmap);
                               } else {
                                   if ($crstype eq 'Community') {
                                       $error = &mt("An error occurred while setting parameters '.
                                                'for Discussion Boards folder: '.
                                                'Could not retrieve community information");
                                   } else {
                                       $error = &mt("An error occurred while setting parameters '.
                                                'for Discussion Boards folder: '.
                                                'Could not retrieve course information");
                                   }
                               }
                           } else {
                               $r->print($outcome);
                           }
                       }
                   } else {
                       $error = &mt("An error occurred while retrieving the contents of the group's folder.").'<br />';
                       if ($crstype eq 'Community') {
                           $error .= &mt("You need to re-initialize the community.");
   
                       } else {
                           $error .= &mt("You need to re-initialize the course.");
                       }
                   }
                   if ($error ne '') {
                       $r->print('<div class="LC_error">'.$error.'</div>');
                   }
               }
               my $message = &Apache::lonhtmlcommon::confirm_success(&mt($ucgpterm.' [_1] was updated.','<i>'.$groupname.'</i>'));
               $message = &Apache::loncommon::confirmwrapper($message);
               $r->print($message);
         }          }
     } else {      } else {
         my %actiontype = (          my %actiontype = (
                           'create' => 'creating',                            'create' => 'creating',
                           'modify' => 'modifying',                            'modify' => 'modifying',
                          );                           );
         &Apache::lonnet::logthis('Failed to store group '.$groupname.          &Apache::lonnet::logthis("Failed to store $gpterm $groupname ".
                                  'in course: '.$cnum.' in domain: '.$cdom);                                   'in '.lc($crstype).': '.$cnum.
         $r->print(&mt('An error occurred when [_1] the new group. '.                                   ' in domain: '.$cdom);
                       'Please try again.',$actiontype{$action}));          $r->print('<p class="LC_error">'
                    .&mt('An error occurred when '.$actiontype{$action}.' the '.$gpterm.'. '
                    .'Please try again.')
                    .'</p');
     }      }
     return $result;      return $result;
 }  }
   
 sub process_membership {  sub process_membership {
     my ($r,$cdom,$cnum,$action,$state,$groupname,$tools,$enddate,$startdate,      my ($r,$cdom,$cnum,$action,$state,$groupname,$tools,$enddate,$startdate,
         $userdata,$idx,$toolprivs,$usertools,$specificity,$defprivs,$memchg)=@_;          $userdata,$idx,$toolprivs,$usertools,$specificity,$defprivs,$memchg,
           $gpterm,$ucgpterm,$crstype)=@_;
     my %usersettings = ();      my %usersettings = ();
     my %added= ();      my %added= ();
     my %failed = ();      my %failed = ();
     my $num_ok = 0;      my $num_ok = 0;
     my $num_fail = 0;      my $num_fail = 0;
     my %group_privs = ();      my %group_privs = ();
       my %curr_privs = ();
       my %curr_start = ();
       my %curr_end = ();
     my %tooltype = ();      my %tooltype = ();
       my $context = 'processgroupmembership';
   
     foreach my $tool (@{$tools}) {      foreach my $tool (@{$tools}) {
         foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {          foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {
Line 2916  sub process_membership { Line 3441  sub process_membership {
                 }                  }
             } else {              } else {
                 if (@{$defprivs} > 0) {                  if (@{$defprivs} > 0) {
                     foreach my $priv (@{$defprivs}) {                      if (grep/^\Q$priv\E$/,@{$defprivs}) {
                         foreach my $user (sort(keys(%{$usertools}))) {                          foreach my $user (sort(keys(%{$usertools}))) {
                             if ($$usertools{$user}{$tool}) {                              if ($$usertools{$user}{$tool}) {
                                 $group_privs{$user} .= $priv.':';                                  $group_privs{$user} .= $priv.':';
Line 2936  sub process_membership { Line 3461  sub process_membership {
     my @expire = ();      my @expire = ();
     my @deletion = ();      my @deletion = ();
     my @reenable = ();      my @reenable = ();
       my @unchanged = ();
     if ($state eq 'memresult') {      if ($state eq 'memresult') {
         if (ref($$memchg{'activate'}) eq 'ARRAY') {          if (ref($$memchg{'activate'}) eq 'ARRAY') {
             @activate = @{$$memchg{'activate'}};              @activate = @{$$memchg{'activate'}};
Line 2949  sub process_membership { Line 3475  sub process_membership {
         if (ref($$memchg{'reenable'}) eq 'ARRAY') {          if (ref($$memchg{'reenable'}) eq 'ARRAY') {
             @reenable = @{$$memchg{'reenable'}};              @reenable = @{$$memchg{'reenable'}};
         }          }
           my %membership = &Apache::lonnet::get_group_membership($cdom,$cnum,
                                                                    $groupname);
           foreach my $key (sort(keys(%membership))) {
               if ($key =~ /^\Q$groupname\E:([^:]+:[^:]+)$/) {
                   ($curr_end{$1},$curr_start{$1},$curr_privs{$1}) = 
                                                   split(/:/,$membership{$key},3);
               }
           }
         if (@expire + @deletion > 0) {          if (@expire + @deletion > 0) {
             my %membership = &Apache::lonnet::get_group_membership($cdom,$cnum,  
                                                                    $groupname);  
             foreach my $user (@expire) {              foreach my $user (@expire) {
                 my ($currend,$currstart,@userprivs) =                   my $savestart = $curr_start{$user};
                                   split(/:/,$membership{$groupname.':'.$user});                  if ($savestart > $now) {
                 $group_privs{$user} = join(':',@userprivs);                       $savestart = $now;
                 if ($currstart > $now) {  
                     $currstart = $now;  
                 }                  }
                 $usersettings{$groupname.':'.$user} = $now.':'.$currstart.':'.                  $usersettings{$groupname.':'.$user} = $now.':'.$savestart.':'.
                                                       $group_privs{$user};                                                        $curr_privs{$user};
                 if (&Apache::lonnet::modify_group_roles($cdom,$cnum,$groupname,                  if (&Apache::lonnet::modify_group_roles($cdom,$cnum,$groupname,
                                                        $user,$now,$currstart,                                                         $user,$now,$savestart,
                                                        $group_privs{$user}) eq 'ok') {                                                         $curr_privs{$user},'',$context) eq 'ok') {
                     push(@{$added{'expired'}},$user);                      push(@{$added{'expired'}},$user);
                     $num_ok ++;                      $num_ok ++;
                 } else {                  } else {
Line 2974  sub process_membership { Line 3504  sub process_membership {
             foreach my $user (@deletion) {              foreach my $user (@deletion) {
                 $usersettings{$groupname.':'.$user} = $now.':-1:';                  $usersettings{$groupname.':'.$user} = $now.':-1:';
                 if (&Apache::lonnet::modify_group_roles($cdom,$cnum,$groupname,                  if (&Apache::lonnet::modify_group_roles($cdom,$cnum,$groupname,
                                                        $user,$now,'-1','')                                                         $user,$now,'-1','','',$context)
                                                          eq 'ok') {                                                           eq 'ok') {
                     push(@{$added{'deleted'}},$user);                      push(@{$added{'deleted'}},$user);
                     $num_ok ++;                      $num_ok ++;
Line 2987  sub process_membership { Line 3517  sub process_membership {
     }      }
   
     foreach my $user (sort(keys(%{$usertools}))) {      foreach my $user (sort(keys(%{$usertools}))) {
           if ((grep(/^$user$/,@expire)) || (grep(/^$user$/,@deletion))) {
               next;
           }
         my $type;          my $type;
         my $start = $startdate;          my $start = $startdate;
         my $end = $enddate;          my $end = $enddate;
         if ($state eq 'memresult') {          if ($state eq 'memresult') {
             $type = 'modified';  
             if (@activate > 0) {              if (@activate > 0) {
                 if (grep/^$user$/,@activate) {                  if (grep/^$user$/,@activate) {
                     $start = $now;                      $start = $now;
                       $end = $enddate;
                     $type = 'activated';                      $type = 'activated';
                 }                  }
             }              }
             if (@reenable > 0) {              if (@reenable > 0) {
                 if (grep/^$user$/,@reenable) {                  if (grep/^$user$/,@reenable) {
                     $type = 'reenabled';                      $start = $startdate;
                       $end = $enddate;
                       $type = 're-enabled';
                   }
               }
               if ($type eq '') {
                   if ($curr_privs{$user} eq $group_privs{$user}) {
                       push(@unchanged,$user);
                       next;
                   }
                   if (exists($curr_start{$user})) {
                       $start = $curr_start{$user};
                 }                  }
                   if (exists($curr_end{$user})) {
                       $end = $curr_end{$user};
                   }
                   $type = 'modified';
             }              }
         } else {          } else {
             $type = 'added';              $type = 'added';
Line 3010  sub process_membership { Line 3558  sub process_membership {
                                               $group_privs{$user};                                                $group_privs{$user};
         if (&Apache::lonnet::modify_group_roles($cdom,$cnum,$groupname,          if (&Apache::lonnet::modify_group_roles($cdom,$cnum,$groupname,
                                                 $user,$end,$start,                                                  $user,$end,$start,
                                                 $group_privs{$user}) eq 'ok') {                                                  $group_privs{$user},'',$context) eq 'ok') {
             push(@{$added{$type}},$user);              push(@{$added{$type}},$user);
             $num_ok ++;              $num_ok ++;
         } else {          } else {
Line 3021  sub process_membership { Line 3569  sub process_membership {
     my $roster_result = &Apache::lonnet::modify_coursegroup_membership($cdom,      my $roster_result = &Apache::lonnet::modify_coursegroup_membership($cdom,
                                                        $cnum,\%usersettings);                                                         $cnum,\%usersettings);
     if ($num_ok) {      if ($num_ok) {
         foreach my $type (sort(keys(%added))) {           my $msgall ='';
             $r->print(&mt('The following users were successfully [_1]',$type));          foreach my $type (sort(keys(%added))) {
             if (!($type eq 'deleted' ||  $type eq 'expired')) {                 my $message;
                 $r->print(&mt(' with the following privileges'));              my $tmsg = "The following users were successfully $type"; 
               if (!($type eq 'deleted' || $type eq 'expired')) {   
                   $tmsg .= ' with the following privileges';
             }              }
             $r->print(':<br />');              $message .= &mt($tmsg.':').'<br/>';
             foreach my $user (@{$added{$type}}) {              foreach my $user (@{$added{$type}}) {
                 my $privlist = '';                  my $privlist = '';
                 if (!($type eq 'deleted' ||  $type eq 'expired')) {                  if (!($type eq 'deleted' ||  $type eq 'expired')) {
Line 3042  sub process_membership { Line 3592  sub process_membership {
                     }                      }
                     $privlist =~ s/, $//;                      $privlist =~ s/, $//;
                 }                  }
                 $r->print($$userdata{$user}[$$idx{fullname}].'&nbsp;-&nbsp;'.$user.$privlist.'<br />');                  $message .= $$userdata{$user}[$$idx{fullname}].'&nbsp;-&nbsp;'.$user.$privlist.'<br />';
             }              }
               $message .= '<br/>';
               $message = &Apache::lonhtmlcommon::confirm_success($message);
               $msgall .= $message;
         }          }
           $msgall = &Apache::loncommon::confirmwrapper($msgall);
           $r->print($msgall);
     }      }
     if ($num_fail) {      if ($num_fail) {
         foreach my $type (sort(keys(%failed))) {          foreach my $type (sort(keys(%failed))) {
             $r->print(&mt('The following users could not be [_1], because an error occurred:<br />',$type));              $r->print('<div class="LC_error">'
                        .&mt("The following users could not be $type, because an error occurred:")
                        .'</div>');
             foreach my $user (@{$failed{$type}}) {              foreach my $user (@{$failed{$type}}) {
                 $r->print($$userdata{$user}[$$idx{fullname}].' - '.$user.'<br />');                  $r->print($$userdata{$user}[$$idx{fullname}].' - '.$user.'<br />');
             }              }
         }          }
           $r->print('<br />');
     }      }
   # Is that really needed?
   #
   #    if (@unchanged > 0) {
   #        $r->print(&mt('No change occurred for the following users:').'<br />');
   #        foreach my $user (sort(@unchanged)) {
   #            $r->print($$userdata{$user}[$$idx{fullname}].' - '.$user.'<br />');
   #        }
   #        $r->print('<br />');
   #    }
     if ($roster_result eq 'ok') {      if ($roster_result eq 'ok') {
         $r->print('<br />Group membership list updated.');          $r->print('<div class="LC_success">'
                    .&mt($ucgpterm.' membership list updated.')
                    .'</div>');
    $r->print('<p class="LC_info">');
           if ($crstype eq 'Community') {
               $r->print(&mt("Any currently logged in community users affected by the changes you made"
                        .' to group membership or privileges for the [_1] group will need to log out'
                        .' and log back in for their LON-CAPA sessions to reflect these changes.'
                        ,'<i>'.$groupname.'</i>'));
   
           } else {  
               $r->print(&mt("Any currently logged in course users affected by the changes you made"
                        .' to group membership or privileges for the [_1] group will need to log out'
                        .' and log back in for their LON-CAPA sessions to reflect these changes.'
                        ,'<i>'.$groupname.'</i>'));
           } 
           $r->print('</p>');
     } else {      } else {
         $r->print('<br />An error occurred while updating the group membership list -'.$roster_result.'<br />');          $r->print('<div class="LC_error">'
                    .&mt("An error occurred while updating the $gpterm membership list:")
                    .'<br />'.$roster_result
                    .'</div>');
     }      }
     return;      return;
 }  }
   
 sub mapping_options {  sub mapping_options {
     my ($r,$action,$formname,$page,$tabcol,$sectioncount,$states,$stored,      my ($r,$action,$formname,$page,$sectioncount,$states,$stored,
         $navbuttons,$img1,$img2,$rowColor1,$rowColor2) = @_;          $navbuttons,$img1,$img2,$gpterm,$ucgpterm,$crstype,$cdom,$cnum) = @_;
     my %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
         'auto' => 'Settings for automatic group enrollment',          'auto' => "Settings for automatic $gpterm enrollment",
         'gmma' => 'Group membership mapping to specific sections/roles',          'gmma' => "$ucgpterm membership mapping to specific sections/roles",
         'endi' => 'Enable/disable automatic group enrollment for '.          'endi' => "Enable/disable automatic $gpterm enrollment for ".
                           'users in specified roles and sections',                            "users in specified roles and sections",
         'adds'  => 'If automatic group enrollment is enabled, when a user is assigned a course-wide or section-specific role, he/she will automatically be added as a member of the group, with start and end access dates defined by the default dates set for the group, unless he/she is already a group member, with access dates that permit either current or future group access.',          'adds'  => "If automatic $gpterm enrollment is enabled, when a user is newly assigned a ".lc($crstype)."-wide or section-specific role, he/she will automatically be added as a member of the $gpterm, with start and end access dates defined by the default dates set for the $gpterm, unless he/she is already a $gpterm member, with access dates that permit either current or future $gpterm access.",
         'drops'  => "If automatic group disenrollment is enabled, when a user's role is expired, access to the group will be terminated unless the user continues to have other course-wide or section-specific active or future roles which receive automatic membership in the group.",          'drops'  => "If automatic $gpterm disenrollment is enabled, when a user's role is expired, access to the $gpterm will be terminated unless the user continues to have other ".lc($crstype)."-wide or section-specific active or future roles which receive automatic membership in the $gpterm.",
         'pirs' => 'Pick roles and sections for automatic group enrollment',          'pirs' => "Pick roles and sections for automatic $gpterm enrollment",
         'curr' => 'Currently set to',  
         'on' => 'on',          'on' => 'on',
         'off' => 'off',          'off' => 'off',
         'auad' => 'Automatically enable group membership when roles are added?',          'auad' => "Automatically enable $gpterm membership when roles are added?",
         'auex' => 'Automatically expire group membership when roles are removed?',          'auex' => "Automatically expire $gpterm membership when roles are removed?",
         'mapr' => 'Mapping of roles and sections affected by automatic group enrollment/disenrollment follows scheme chosen below.',          'mapr' => "Mapping of roles and sections affected by automatic $gpterm enrollment/disenrollment follows scheme chosen below.",
     );      );
     &automapping($r,$action,$tabcol,$stored,\%lt,$img1);      &automapping($r,$action,$stored,\%lt,$img1);
     $r->print('      &mapping_settings($r,$sectioncount,\%lt,$stored,$img2,$crstype,$cdom,$cnum,
    <tr>                        $action);
     <td colspan="4">&nbsp;</td>  
    </tr>');  
     &mapping_settings($r,$tabcol,$rowColor1,$rowColor2,$sectioncount,\%lt,  
                                                        $stored,$img2);  
     return;      return;
 }  }
   
 sub automapping {  sub automapping {
     my ($r,$action,$tabcol,$stored,$lt,$image) = @_;      my ($r,$action,$stored,$lt,$image) = @_;
     my $add = 'off';      my $add = 'off';
     my $drop = 'off';      my $drop = 'off';
     if (exists($$stored{'autoadd'})) {      if (exists($$stored{'autoadd'})) {
Line 3100  sub automapping { Line 3681  sub automapping {
     if (exists($$stored{'autodrop'})) {      if (exists($$stored{'autodrop'})) {
         $drop = $$stored{'autodrop'};          $drop = $$stored{'autodrop'};
     }      }
     &topic_bar($r,$tabcol,$image,$$lt{'endi'});      $r->print(&Apache::lonhtmlcommon::topic_bar($image,$$lt{'endi'}).'
     $r->print('      <b>'.$$lt{'gmma'}.':</b><br />'.$$lt{'adds'}.'<br />'.$$lt{'drops'}.'<br /><br />
   <tr>     <span class="LC_nobreak">'.$$lt{'auad'}.':&nbsp;
    <td>&nbsp;</td>      <label><input type="radio" name="autoadd" value="on" />'.&mt('on').'&nbsp;&nbsp;</label><label><input type="radio" name="autoadd" value="off" checked="checked" />'.&mt('off').'</label>');
    <td colspan="3">  
     <b>'.$$lt{'gmma'}.':</b><br />'.$$lt{'adds'}.'<br />'.$$lt{'drops'}.'<br />  
    </td>  
   </tr>  
   <tr>  
    <td colspan="4">&nbsp;</td>  
   </tr>  
   <tr>  
    <td>&nbsp;</td>  
    <td colspan="3">  
    <nobr>'.$$lt{'auad'}.':&nbsp;  
     <input type="radio" name="autoadd" value="on" />on&nbsp;&nbsp;<input type="radio" name="autoadd" value="off" />off');  
     if ($action eq 'modify') {      if ($action eq 'modify') {
         $r->print('&nbsp;&nbsp;&nbsp;&nbsp;('.$$lt{'curr'}.' <b>'.$$lt{$add}.'</b>)');          $r->print('&nbsp;&nbsp;&nbsp;&nbsp;('.&mt('Currently set to [_1].','<b>'.$$lt{$add}.'</b>').')');
     }      }
     $r->print('      $r->print('
     </nobr>      </span><br />
    </td>      <span class="LC_nobreak">'.$$lt{'auex'}.':&nbsp;
   </tr>      <label><input type="radio" name="autodrop" value="on" />'.&mt('on').'&nbsp;&nbsp;</label><label><input type="radio" name="autodrop" value="off" checked="checked" />'.&mt('off').'</label>');
   <tr>  
    <td>&nbsp;</td>  
    <td colspan="3">  
     <nobr>'.$$lt{'auex'}.':&nbsp;  
     <input type="radio" name="autodrop" value="on" />on&nbsp;&nbsp;<input type="radio" name="autodrop" value="off" />off');  
     if ($action eq 'modify') {      if ($action eq 'modify') {
         $r->print('&nbsp;&nbsp;&nbsp;&nbsp;('.$$lt{'curr'}.' <b>'.$$lt{$drop}.'</b>)');          $r->print('&nbsp;&nbsp;&nbsp;&nbsp;('.&mt('Currently set to [_1].','<b>'.$$lt{$drop}.'</b>').')');
     }      }
     $r->print('</nobr>      $r->print('</span><br /><br />'.$$lt{'mapr'});
    </td>  
   </tr>  
   <tr>  
    <td colspan="4">&nbsp;</td>  
   </tr>  
   <tr>  
    <td>&nbsp;</td>  
    <td colspan="3">'.$$lt{'mapr'}.'  
    </td>  
   </tr>  
 ');  
 }  }
   
 sub mapping_settings {  sub mapping_settings {
     my ($r,$tabcol,$rowColor1,$rowColor2,$sectioncount,$lt,$stored,$image) = @_;      my ($r,$sectioncount,$lt,$stored,$image,$crstype,$cdom,$cnum,$action) = @_;
     my @sections = keys(%{$sectioncount});      my @sections = keys(%{$sectioncount});
     if (@sections > 0) {      if (@sections > 0) {
         @sections = sort {$a cmp $b} @sections;          @sections = sort {$a cmp $b} @sections;
         unshift(@sections,'_nosec'); # Put 'no sections' next          unshift(@sections,'none'); # Put 'no sections' next
         unshift(@sections,'_all'); # Put 'all' at the front of the list          unshift(@sections,'all'); # Put 'all' at the front of the list
       } else {
           @sections = ('all','none');
     }      }
     &topic_bar($r,$tabcol,$image,$$lt{'pirs'});      $r->print(&Apache::lonhtmlcommon::topic_bar($image,$$lt{'pirs'}));
     $r->print('      my @roles = &standard_roles($crstype);
    <tr>      my %customroles = &Apache::lonhtmlcommon::course_custom_roles($cdom,$cnum);
     <td>&nbsp;</td>      $r->print(&Apache::loncommon::start_data_table().
     <td colspan="3">        &Apache::loncommon::start_data_table_header_row());
 ');  
     my @roles = &standard_roles();  
     my %customroles = &my_custom_roles();  
     $r->print(&Apache::lonhtmlcommon::start_pick_box());  
     $r->print('      $r->print('
                 <tr bgcolor="'.$tabcol.'">  
                  <th>'.&mt('Active?').'</th>                   <th>'.&mt('Active?').'</th>
                  <th>'.&mt('Role').'</th>');                   <th>'.&mt('Role').'</th>');
     if (@sections > 0) {      if (@sections > 0) {
         $r->print('<th>'.&mt('Sections').'</th></tr>'."\n");          $r->print('<th>'.&mt('Sections').'</th>');
     }      }
     my $rowNum = 0;      $r->print(&Apache::loncommon::end_data_table_header_row()."\n");
     my $rowColor;  
     foreach my $role (@roles) {      foreach my $role (@roles) {
         my $plrole=&Apache::lonnet::plaintext($role);          my $roletitle=&Apache::lonnet::plaintext($role,$crstype);
         my $sections_sel;          $r->print(&print_autorole_item($role,$roletitle,\@sections));
         if (@sections > 0) {  
             $sections_sel='<td>'.&sections_selection(\@sections,'sec_'.$role).  
                                                                        '</td>';  
         }  
         if ($rowNum %2 == 1) {  
             $rowColor = $rowColor1;  
         } else {  
             $rowColor = $rowColor2;  
         }  
         $r->print('<tr bgcolor="'.$rowColor.'"><td><input type="checkbox" '.  
                   'name="autorole" value="'.$role.'"></td><td>'.$plrole.  
                   '</td>'.$sections_sel.'</tr>');  
         $rowNum ++;  
     }      }
       my @customs;
     foreach my $role (sort(keys(%customroles))) {      foreach my $role (sort(keys(%customroles))) {
         my $sections_sel;          my ($roletitle) = ($role =~ m|^cr/[^/]+/[^/]+/(.+)$|);
         if (@sections > 0) {          push (@customs,$role);
             $sections_sel = '<td>'.&sections_selection(\@sections,'sec_'.$role).          $r->print(&print_autorole_item($role,$roletitle,\@sections));
                                                                         '</td>';  
         }  
         if ($rowNum %2 == 1) {  
             $rowColor = $rowColor1;  
         } else {  
             $rowColor = $rowColor2;  
         }  
         $r->print('<tr bgcolor="'.$rowColor.'"><td><input type="checkbox" '.  
                   'value="'.$role.'"></td><td>'.$role.'</td>'.  
                   $sections_sel.'</tr>');  
         $rowNum ++;  
     }      }
     $r->print(&Apache::lonhtmlcommon::end_pick_box());      if ($action eq 'modify') {
           foreach my $role (@{$$stored{'autorole'}}) {
               if ((!grep(/^\Q$role\E$/,@customs)) && 
                   (!grep(/^\Q$role\E$/,@roles))) {
                   my $roletitle;
                   if ($role =~ /^cr/) {
                       ($roletitle) = ($role =~ m|_([^_]+)$|);
                   } else {
                       $roletitle = &Apache::lonnet::plaintext($role,$crstype);
                   }
                   $r->print(&print_autorole_item($role,$roletitle,\@sections));
               }
           }
       }
       $r->print(&Apache::loncommon::end_data_table());
     return;      return;
 }  }
   
 sub standard_roles {  sub print_autorole_item {
     my @roles = ('st','ep','ta','in','cc');      my ($role,$roletitle,$sections) = @_;
     return @roles;      my $sections_sel;
 }      if (@{$sections} > 0) {
           if (($role eq 'cc') || ($role eq 'co')) {
 sub my_custom_roles {              $sections_sel = '<td align="right">'.
     my %returnhash=();                              &mt('all sections').'<input type="hidden" '.
     my %rolehash=&Apache::lonnet::dump('roles');                              'name="sec_'.$role.'" value="all" /></td>';
     foreach (keys %rolehash) {          } else {
         if ($_=~/^rolesdef\_(\w+)$/) {              $sections_sel='<td align="right">'.
             $returnhash{$1}=$1;                            &sections_selection($sections,'sec_'.$role).
                             '</td>';
         }          }
     }      }
     return %returnhash;      my $output = &Apache::loncommon::start_data_table_row().
                    '<td><input type="checkbox" '.
                    'name="autorole" value="'.$role.'" />'.
                    '</td><td>'.$roletitle.'</td>'.$sections_sel.
                    &Apache::loncommon::end_data_table_row();
       return $output;
   } 
   
   sub standard_roles {
       my ($crstype) = @_;
       my @roles = qw(in ta ep ad st);
       if ($crstype eq 'Community') {
           unshift(@roles,'co');
       } else {
           unshift(@roles,'cc');
       }
       return @roles;
 }  }
   
 sub modify_menu {  sub modify_menu {
     my ($r,$groupname,$page) = @_;      my ($r,$groupname,$page,$gpterm) = @_;
     my @menu =      my @menu =
         (          ( { categorytitle =>'Group Actions',
           { text => 'Modify default group settings',   items => [
             help => 'Course_Modify_Group',  
             state => 'change_settings',            { linktext => "Modify default $gpterm settings",
             branch => 'settings',              url => '/adm/coursegroups?action=modify&amp;refpage='.$env{'form.refpage'}.'&amp;groupname='.$groupname.'&amp;state=change_settings&amp;branch=settings',
               icon => 'grp_settings.png',
               alttext => "Modify default $gpterm settings",
               permission => '1',
               help => 'Course_Modify_Group',            
             },              },
           { text => 'Modify access, tools and/or privileges for previous, '.            { linktext => 'Modify access, tools and privileges for members',
                     'future, or current members',              url => '/adm/coursegroups?action=modify&amp;refpage='.$env{'form.refpage'}.'&amp;groupname='.$groupname.'&amp;state=change_members&amp;branch=members',
               icon => 'grp_tools.png',
               alttext => 'Modify access, tools and privileges for members',
               permission => '1',
             help => 'Course_Modify_Group_Membership',              help => 'Course_Modify_Group_Membership',
             state => 'change_members',  
             branch => 'members',  
             },              },
           { text => 'Add member(s) to the group',            { linktext => "Add member(s) to the $gpterm",
               url => '/adm/coursegroups?action=modify&amp;refpage='.$env{'form.refpage'}.'&amp;groupname='.$groupname.'&amp;state=add_members&amp;branch=adds',
               icon => 'grp_add.png',
               alttext =>  "Add member(s) to the $gpterm",
               permission => '1',
             help => 'Course_Group_Add_Members',              help => 'Course_Group_Add_Members',
             state => 'add_members',              }]}
             branch => 'adds',            );   
             },      $r->print(&Apache::lonhtmlcommon::generate_menu(@menu));
           );  
     my $menu_html = '';  
     foreach my $menu_item (@menu) {  
         $menu_html .=  
         '<p><font size="+1"><a href="/adm/coursegroups?action=modify&refpage='.$env{'form.refpage'}.'&groupname='.$groupname.'&state='.$menu_item->{'state'}.'&branch='.$menu_item->{'branch'}.'">';  
         $menu_html.= &mt($menu_item->{'text'}).'</a></font>';  
         if (exists($menu_item->{'help'})) {  
             $menu_html.=  
                 &Apache::loncommon::help_open_topic($menu_item->{'help'});  
         }  
         $menu_html.='</p>'.$/;  
     }  
     $r->print($menu_html);  
     return;      return;
 }  }
   
 sub member_privs_entries {  sub member_privs_entries {
     my ($r,$tabcol,$rowColor1,$rowColor2,$usertools,$toolprivs,      my ($r,$usertools,$toolprivs,$fixedprivs,$userdata,$idx,$showtools,
         $fixedprivs,$userdata,$idx,$showtools,$defprivs,$excluded) = @_;   $defprivs,$excluded) = @_;
     my $rowColor;  
     my $rowNum = 0;  
     foreach my $user (sort(keys(%{$usertools}))) {      foreach my $user (sort(keys(%{$usertools}))) {
         if (defined($excluded)) {          if (defined($excluded)) {
             if (ref($excluded) eq 'ARRAY') {              if (ref($excluded) eq 'ARRAY') {
Line 3274  sub member_privs_entries { Line 3825  sub member_privs_entries {
             }              }
         }          }
         my ($uname,$udom) = split(/:/,$user);          my ($uname,$udom) = split(/:/,$user);
         if ($rowNum %2 == 1) {          $r->print(&Apache::loncommon::start_data_table_row().'
             $rowColor = $rowColor1;  
         } else {  
             $rowColor = $rowColor2;  
         }  
         $r->print('<tr bgcolor="'.$rowColor.'">  
                 <td>'.$$userdata{$user}[$$idx{fullname}].'</td>                  <td>'.$$userdata{$user}[$$idx{fullname}].'</td>
                 <td>'.$uname.'</td>                  <td>'.$uname.'</td>
                 <td>'.$udom.'</td>                  <td>'.$udom.'</td>
                 <td valign="top"><table><tr><td><b>Function</b></td></tr><tr><td><b>Fixed</b></td></tr><tr><td><b>Optional</b></td></tr></table></td>');                  <td valign="top">
                     <table>
                      <tr>
                       <td><b>'.
                       &mt('Collaborative Tool').'</b></td>
                      </tr>
                      <tr>
                       <td><b>'.&mt('Fixed').'</b></td>
                      </tr>
                      <tr>
                       <td><b>'.&mt('Optional').'</b></td>
                      </tr>
                     </table>
                    </td>');
         foreach my $tool (@{$showtools}) {          foreach my $tool (@{$showtools}) {
             if (exists($$usertools{$user}{$tool})) {              if (exists($$usertools{$user}{$tool})) {
                 $r->print('<td valign="top"><table><tr bgcolor="'.$tabcol.'"><td colspan="2" align="center"><b>'.$tool.'</b></td></tr>');                  $r->print('<td valign="top"><table><tr><th colspan="2">'.$tool.'</th></tr>');
                 my $privcount = 0;                  my $privcount = 0;
                 my $fixed = '';                  my $fixed = '';
                 my $dynamic = '';                  my $dynamic = '';
Line 3298  sub member_privs_entries { Line 3857  sub member_privs_entries {
                         if ($privcount == 3) {                          if ($privcount == 3) {
                             $dynamic .= '</tr><tr>';                              $dynamic .= '</tr><tr>';
                         }                          }
                         $dynamic .='<td><nobr><label><input type="checkbox" '.                          $dynamic .='<td><span class="LC_nobreak"><label><input type="checkbox" '.
                                'name="userpriv_'.$priv.'" value="'.$user.'"';                                 'name="userpriv_'.$priv.'" value="'.$user.'"';
                         if (grep/^\Q$priv\E$/,@{$defprivs}) {                          if (grep/^\Q$priv\E$/,@{$defprivs}) {
                             $dynamic .= ' checked="checked" ';                              $dynamic .= ' checked="checked" ';
                         }                          }
                         $dynamic .= ' />'.$$toolprivs{$tool}{$priv}.                          $dynamic .= ' />'.$$toolprivs{$tool}{$priv}.
                                     '</label></nobr></td>';                                      '</label></span></td>';
                     }                      }
                 }                  }
                 $r->print('<tr><td colspan="2"><nobr>'.$fixed.'</nobr></td></tr><tr>'.$dynamic.'</tr></table></td>');                  $r->print('<tr><td colspan="2"><span class="LC_nobreak">'.$fixed.'</span></td></tr><tr>'.$dynamic.'</tr></table></td>');
             } else {              } else {
                 $r->print('<td valign="top"><table width="100%"><tr bgcolor="'.$tabcol.'"><td colspan="2" align="center"><b>'.$tool.'</b></td></tr><tr><td>&nbsp;</td></tr><tr><td>&nbsp;</td></tr></table></td>');                  $r->print('<td valign="top"><table width="100%"><tr><th colspan="2">'.$tool.'</th></tr><tr><td>&nbsp;</td></tr><tr><td>&nbsp;</td></tr></table></td>');
             }              }
         }          }
         $rowNum ++;          $r->print(&Apache::loncommon::end_data_table_row());
     }      }
 }  }
   
Line 3333  sub date_setting_table { Line 3892  sub date_setting_table {
                                                       'startdate',$starttime);                                                        'startdate',$starttime);
     my $endform = &Apache::lonhtmlcommon::date_setter($formname,      my $endform = &Apache::lonhtmlcommon::date_setter($formname,
                                                       'enddate',$endtime);                                                        'enddate',$endtime);
     my $perpetual = '<nobr><label><input type="checkbox" name="no_end_date" />      my $perpetual = ' <span class="LC_nobreak"><label>'
                                                 no ending date</label></nobr>';                     .'<input type="checkbox" name="no_end_date" />'
     my $start_table = '';                     .&mt('No end date')
     $start_table .= "<table>\n";                     .'</label></span>';
     $start_table .= '<tr><td align="right">Default starting date for       my $table = &Apache::lonhtmlcommon::start_pick_box()
                                            member access</td>'.                 .&Apache::lonhtmlcommon::row_title(&mt('Start Date'))
         '<td>'.$startform.'</td>'.                 .$startform
         '<td>&nbsp;</td>'."</tr>\n";                 .&Apache::lonhtmlcommon::row_closure()
     $start_table .= "</table>";                 .&Apache::lonhtmlcommon::row_title(&mt('End Date'))
     my $end_table = '';                 .$endform
     $end_table .= "<table>\n";                 .$perpetual
     $end_table .= '<tr><td align="right">Default ending date for                  .&Apache::lonhtmlcommon::row_closure(1)
                                          member access</td>'.                 .&Apache::lonhtmlcommon::end_pick_box();
         '<td>'.$endform.'</td>'.      return $table;
         '<td>'.$perpetual.'</td>'."</tr>\n";  }
     $end_table .= "</table>\n";  
     return ($start_table, $end_table);  sub add_group_folder {
       my ($cdom,$cnum,$now,$groupname,$action,$description,$tools,$groupinfo,
           $gpterm,$ucgpterm,$crstype) = @_;
       if ($cdom eq '' || $cnum eq '') {
           my $error = '<span class="LC_error">';
           if ($crstype eq 'Community') { 
               $error .= &mt("Error: invalid community domain or number - group folder creation failed.");
           } else {
               $error .= &mt("Error: invalid course domain or number - group folder creation failed.");
           }
           $error .= '</span>';
           return $error;
       }
       my ($outcome,$allgrpsmap,$grpmap,$boardsmap,$grppage,$warning);
       my $crspath = '/uploaded/'.$cdom.'/'.$cnum.'/';
       $allgrpsmap = $crspath.'group_allfolders.sequence';
       if ($action eq 'create') {
           if (&get_folder_lock($cdom,$cnum,'group_allfolders',$now) eq 'ok') {
               # check if group_allfolders.sequence exists.
               my $mapcontents = &Apache::lonnet::getfile($allgrpsmap);
               if ($mapcontents eq '-1') { #file does not exist;
                   my $grpstitle = &mt("$crstype $ucgpterm".'s');
                   my $topmap_url = '/'.$env{'course.'.$env{'request.course.id'}.'.url'};
                   $topmap_url =~ s|/+|/|g;
                   if ($topmap_url =~ m|^/uploaded|) {
                       $outcome = &map_updater($cdom,$cnum,'group_allfolders.sequence',
                                               'toplevelgroup',$grpstitle,$topmap_url);
                   } else {
                       $outcome = '<span class="LC_warning">'
                                 .&mt('Non-standard course - folder for all groups not added.')
                                 .'</span>';
                   }
                   if ($outcome ne 'ok') {
                       my $delresult = &release_folder_lock($cdom,$cnum,'group_allfolders');
                       if ($delresult ne 'ok') {
                           $warning = $delresult;
                       }
                       return $outcome.$warning;
                   }
               }
               my $delresult = &release_folder_lock($cdom,$cnum,'group_allfolders');
               if ($delresult ne 'ok') {
                   $warning = $delresult ;
               }
           } else {
               $outcome = '<span class="LC_error">'
                         .&mt('Could not obtain exclusive lock to check status of the folder for all groups. No group folder added.')
                         .'</span>';
               return $outcome;
           }
           my $grpfolder = &mt($ucgpterm.' Folder - [_1]',$description);
           $grppage='/adm/'.$cdom.'/'.$cnum.'/'.$groupname.'/smppg';
           my $grptitle = &mt('Group homepage - [_1]',$description);
           my ($discussions,$disctitle);
           my $outcome = &map_updater($cdom,$cnum,'group_folder_'.$groupname.'.sequence',
                                      'grpseq',$grpfolder,$allgrpsmap,$grppage,
                                      $grptitle);
           if ($outcome ne 'ok') {
               return $outcome.$warning;
           }
           my $pageout = &create_homepage($cdom,$cnum,$groupname,$groupinfo,
                                          $tools,$gpterm,$ucgpterm,$now);
           # Link to folder for bulletin boards
           $grpmap = $crspath.'group_folder_'.$groupname.'.sequence';
           if (grep/^discussion$/,@{$tools}) {
               $disctitle = &mt('Discussion Boards');
               my $outcome = &map_updater($cdom,$cnum,'group_boards_'.$groupname.
                                          '.sequence','bbseq',$disctitle,$grpmap);
               if ($outcome ne 'ok') {
                   return $outcome.$warning;
               }
               $boardsmap = $crspath.'group_boards_'.$groupname.'.sequence';
           }
       } else {
           #modify group folder if status of discussions tools is changed
       }
       my ($furl,$ferr)= &Apache::lonuserstate::readmap($cdom.'/'.$cnum);
       my $navmap = Apache::lonnavmaps::navmap->new();
       if (!defined($navmap)) {
           $warning .= '<span class="LC_error">';
           if ($crstype eq 'Community') {
               $warning .= &mt("Error retrieving community contents").
                           ' '.&mt("You need to re-initialize the community.");
           } else {
               $warning  .= &mt("Error retrieving course contents").
                            ' '.&mt("You need to re-initialize the course.");
           }
           $warning .= '</span>';
           return $warning;
       }
       # modify parameters
       my $parm_result;
       if ($action eq 'create') {
           if ($grpmap) {
               $parm_result .= &parm_setter($navmap,$cdom,$grpmap,$groupname);
           }
           if ($grppage) {
               $parm_result .= &parm_setter($navmap,$cdom,$grppage,$groupname);
           }
           if ($boardsmap) {
               $parm_result .= &parm_setter($navmap,$cdom,$boardsmap,$groupname);
           }
       }
       undef($navmap);
       if ($parm_result) {
           return $warning.$parm_result;
       } else {
           return 'ok';
       }
   }
   
   sub get_folder_lock {
       my ($cdom,$cnum,$folder_name,$now) = @_;  
       # get lock for folder being edited.
       my $lockhash = {
                     $folder_name."\0".'locked_folder' => $now.':'.$env{'user.name'}.
                                                        ':'.$env{'user.domain'},
                      };
       my $tries = 0;
       my $gotlock = &Apache::lonnet::newput('coursegroups',$lockhash,$cdom,$cnum);
   
       while (($gotlock ne 'ok') && $tries <3) {
           $tries ++;
           sleep(1);
           $gotlock = &Apache::lonnet::newput('coursegroups',$lockhash,$cdom,$cnum);
       }
       return $gotlock;
   }
   
   sub release_folder_lock {
       my ($cdom,$cnum,$folder_name) = @_;  
       #  remove lock
       my @del_lock = ($folder_name."\0".'locked_folder');
       my $dellockoutcome=&Apache::lonnet::del('coursegroups',\@del_lock,$cdom,$cnum);
       if ($dellockoutcome ne 'ok') {
           return ('<div class="LC_error">'
                  .&mt('Warning: failed to release lock for folder: [_1].','<tt>'.$folder_name.'</tt>')
                  .'</div>'
                  );
       } else {
           return 'ok';
       }
   }
   
   sub map_updater {
       my ($cdom,$cnum,$newfile,$itemname,$itemtitle,$parentmap,$startsrc,
           $starttitle,$endsrc,$endtitle) = @_;
       my $outcome;
       $env{'form.'.$itemname} = &new_map($startsrc,$starttitle,$endsrc,
                                          $endtitle);
       my $newmapurl=&Apache::lonnet::finishuserfileupload($cnum,$cdom,$itemname,
                                                           $newfile);
       if ($newmapurl !~ m|^/uploaded|) {
           $outcome = '<div class="LC_error">'
                     .&mt('Error uploading new folder.')." ($newfile): $newmapurl"
                     .'</div>';
           return $outcome;
       }
       my ($errtext,$fatal)=&LONCAPA::map::mapread($parentmap);
       if ($fatal) {
           $outcome = '<div class="LC_error">'
                     .&mt('Error reading contents of parent folder.')." ($parentmap): $errtext"
                     .'</div>';
           return $outcome;
       } else {
           my $newidx=&LONCAPA::map::getresidx($newmapurl);
           $LONCAPA::map::resources[$newidx] = $itemtitle.':'.$newmapurl.
                                                    ':false:normal:res';
           $LONCAPA::map::order[1+$#LONCAPA::map::order]=$newidx;
           my ($outtext,$errtext) = &LONCAPA::map::storemap($parentmap,1,1);
           if ($errtext) {
               $outcome = '<div class="LC_error">'
                         .&mt('Error saving updated parent folder.')." ($parentmap):  $errtext"
                         .'</div>';
               return $outcome;
           }
       }
       return 'ok';
   }
   
   sub new_map {
       my ($startsrc,$starttitle,$endsrc,$endtitle) = @_;
       my $newmapstr = '
   <map>
    <resource id="1" src="'.$startsrc.'" type="start" title="'.$starttitle.'"></resource>
    <link from="1" to="2" index="1"></link>
    <resource id="2" src="'.$endsrc.'" type="finish" title="'.$endtitle.'"></resource>
   </map>
   ';
       return $newmapstr;
   }
   
   sub parm_setter {
       my ($navmap,$cdom,$url,$groupname,$crstype) = @_;
       if (!defined($navmap)) {
           my $allresults;
           if ($crstype eq 'Community') { 
               $allresults = &mt("Parameters not set for [_1] because the contents of the community could not be retrieved.",$url).' '.
                             &mt("You need to reinitialize the community.");
           } else {
               $allresults = &mt("Parameters not set for [_1] because the contents of the course could not be retrieved.",$url).' '.
                             &mt("You need to reinitialize the course.");
   
           }
           return '<div class="LC_warning">'.$allresults.'</div>';
       }
       my %hide_settings = (
                              'course' =>  {
                                             'num' => 13,
                                             'set' => 'yes',
                                           },
                               'group' =>  {
                                             'num' => 5,
                                             'set' => 'no',
                                             'extra' => $groupname,
                                           },
                           );
       my $res = $navmap->getResourceByUrl($url);
       my $allresults;
       if ($res) {
           my $symb = $res->symb();
           foreach my $level (keys(%hide_settings)) {
               my $parmresult =  
                          &Apache::lonparmset::storeparm_by_symb($symb,
                                                    '0_hiddenresource',
                                                    $hide_settings{$level}{'num'},
                                                    $hide_settings{$level}{'set'},
                                                    'string_yesno',undef,$cdom,
                                                    undef,undef,
                                                    $hide_settings{$level}{'extra'});
               if ($parmresult) {
                   $allresults .= $level.': '.$parmresult;
               }
           }
       } else {
           $allresults = '<div class="LC_warning">';
           if ($crstype eq 'Community') {
               $allresults .= &mt("Parameters not set for [_1] because the resource was not recognized as part of the community.",'<tt>'.$url.'</tt>');
           } else {
               $allresults .= &mt('Parameters not set for [_1] because the resource was not recognized as part of the course.','<tt>'.$url.'</tt>');
           }
           $allresults .= '</div>';
       }
       return $allresults;
 }  }
   
 sub create_homepage {  sub create_homepage {
     my ($cdom,$cnum,$name,$groupinfo,$tools) = @_;      my ($cdom,$cnum,$name,$groupinfo,$tools,$gpterm,$ucgpterm,$now) = @_;
     my $functionality = join(',',@{$tools});      my $functionality = join(',',@{$tools});
     my $content = &Apache::lonnet::unescape($$groupinfo{description});      my $content = &unescape($$groupinfo{description});
     $content=~s/\s+$//s;      chomp($content);
     $content=~s/^\s+//s;      my $gateway = Apache::lonhtmlgateway->new();
     $content=~s/\<br\s*\/*\>$//s;      $content = $gateway->process_incoming_html($content,1);
     $content=&Apache::lonfeedback::clear_out_html($content,1);  
   
     my %pageinfo = (      my %pageinfo = (
                      'aaa_title' => 'Group: '.$name,                       'aaa_title' => "$ucgpterm: $name",
                      'abb_links' => $functionality,                       'abb_links' => $functionality,
                      'bbb_content' => $content,                       'bbb_content' => $content,
                      'ccc_webreferences' => '',                       'ccc_webreferences' => '',
                      'uploaded.lastmodified' => time,                       'uploaded.lastmodified' => $now,
                    );                     );
    my $putresult = &Apache::lonnet::put('grppage_'.$name,\%pageinfo,$cdom,$cnum);     my $putresult = &Apache::lonnet::put('grppage_'.$name,\%pageinfo,$cdom,$cnum);
    return $putresult;     return $putresult;
Line 3408  function toggleTools(field,caller) { Line 4209  function toggleTools(field,caller) {
 }  }
   
 sub validate_groupname {  sub validate_groupname {
     my ($groupname,$action,$cdom,$cnum) = @_;      my ($groupname,$action,$cdom,$cnum,$gpterm,$ucgpterm,$crstype) = @_;
     my %sectioncount;      my %sectioncount = &Apache::loncommon::get_sections($cdom,$cnum);
     my $numsec=&Apache::loncommon::get_sections($cdom,$cnum,\%sectioncount);      my %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum);
     my %curr_groups;      my %deleted_groups = &Apache::longroup::coursegroups($cdom,$cnum,undef,
     my $numgroups=&Apache::loncommon::coursegroups(\%curr_groups,$cdom,$cnum);                                                           'deleted_groups');
                                                                                                if (my $tmp = &Apache::lonnet::error(%deleted_groups)) {
           undef(%deleted_groups);
           &Apache::lonnet::logthis('Error retrieving groups: '.$tmp.' in '.$cnum.':'.$cdom);
       }
     my %lt = &Apache::lonlocal::texthash (      my %lt = &Apache::lonlocal::texthash (
                       igna => 'Invalid group name',                        igna => "Invalid $gpterm name",
                       tgne => 'The group name entered ',                        grna => "$ucgpterm names and section names used in a ".
                       grna => 'Group names and section names used in a course '.                                 "$crstype must be unique.",
                               'must be unique.',                        gnmo => "$ucgpterm names may only contain letters, ". 
                       isno => 'is not a valid name.',                                "numbers or underscores.",
                       gnmo => 'Group names may only contain letters, numbers '.  
                               'or underscores.',  
                       cnnb => 'can not be used as it is the name of ',  
                       inth => ' in this course.',  
                       thgr => '- does not correspond to the name of an existing'.    
                               ' group ',      
     );      );
                                                                                            
     my $exitmsg = '<b>'.$lt{'igna'}.'</b><br /><br />'.$lt{'tgne'}.' "'.      my $exitmsg = '<span class="LC_error">'.$lt{'igna'}.'</span><br /><br />';
                   $groupname.'" ';      my $nameshown = &Apache::loncommon::cleanup_html($groupname);
     my $dupmsg = $lt{'grna'};  
     my $earlyout;  
     if (($groupname eq '') || ($groupname =~ /\W/)) {      if (($groupname eq '') || ($groupname =~ /\W/)) {
         $earlyout = $exitmsg.$lt{'isno'}.'<br />'.$lt{'gnmo'};          return $exitmsg.
         return $earlyout;                 &mt("The $gpterm name entered '[_1]' is not a valid name.",$nameshown).
     }                 '<br />'.$lt{'gnmo'};
     if ($numsec) {      } elsif ($groupname eq 'syllabus') {
         if (exists($sectioncount{$groupname})) {          return $exitmsg.
             $earlyout = $exitmsg.$lt{'cnnb'}.&mt('a section').$lt{'inth'}.                 &mt("The $gpterm name entered '[_1]' is reserved for use by LON-CAPA.",$nameshown);
                         '<br />'.$lt{'grna'};      }
             return $earlyout;      if (exists($sectioncount{$groupname})) {
         }   return  $exitmsg.
     }                  &mt("The $gpterm name entered '[_1]' can not be used as it is the name of a section in this $crstype.",$nameshown).
     if ($action eq 'create') {          '<br />'.$lt{'grna'};
         if ($numgroups) {      }
             if (exists($curr_groups{$groupname})) {      if ($action eq 'create') { 
                 $earlyout = $exitmsg.$lt{'cnnb'}.&mt('an existing group').   if (exists($curr_groups{$groupname})) {
                             $lt{'inth'}.'<br />'.$lt{'grna'};      return $exitmsg.
                 return $earlyout;                     &mt("The $gpterm name entered '[_1]' can not be used as it is the name of an existing $gpterm in this $crstype.",$nameshown).
             }                    '<br />'.$lt{'grna'};
           } elsif (exists($deleted_groups{$groupname})) {
               return $exitmsg.
                      &mt("The $gpterm name entered '[_1]' can not be used as it is the name of a $gpterm which previously existed in this $crstype.",$nameshown).
                      '<br />'.$lt{'grna'};
         }          }
     } elsif ($action eq 'modify') {      } elsif ($action eq 'modify') {
         unless(exists($curr_groups{$groupname})) {          unless(exists($curr_groups{$groupname})) {
             $earlyout = &mt('Group name:').' '.$groupname.$lt{'thgr'}.$lt{'inth'};              return &mt("$ucgpterm name: [_1] does not correspond to the name of an existing $gpterm in this $crstype.",$nameshown);
             return $earlyout;  
         }          }
     }      }
     return;      return;
 }  }
   
 sub topic_bar {  
     my ($r,$tabcol,$imgnum,$title) = @_;  
     $r->print('  
  <tr bgcolor="'.$tabcol.'">  
   <td>&nbsp;</td>  
   <td valign="middle" align="left">  
    <nobr>  
     <img src="/res/adm/pages/bl_step'.$imgnum.'.gif" valign="middle">&nbsp;  
    </nobr>  
   </td>  
   <th align="left"><nobr>'.$title.'<nobr>  
   </th>  
   <td width="100%">&nbsp;</td>  
  </tr>  
  <tr>  
   <td colspan="4">&nbsp;</td>  
  </tr>  
 ');  
     return;  
 }  
   
 sub check_changes {  sub check_changes {
     my ($member_changes,$memchg) = @_;      my ($member_changes,$memchg) = @_;
     my %exclusions;      my %exclusions;
Line 3520  sub check_changes { Line 4298  sub check_changes {
 }  }
   
 1;  1;
   

Removed from v.1.9  
changed lines
  Added in v.1.130


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