Diff for /loncom/interface/loncoursegroups.pm between versions 1.4 and 1.5

version 1.4, 2005/11/22 00:01:41 version 1.5, 2006/02/18 01:27:07
Line 51  sub handler { Line 51  sub handler {
     }      }
   
     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},      &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                                             ['action','refpage']);                          ['action','refpage','state','groupname','branch']);
                                                                                         
     my $function = &Apache::loncommon::get_users_function();      my $function = &Apache::loncommon::get_users_function();
     my $tabcol = &Apache::loncommon::designparm($function.'.tabbg');      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'};
Line 62  sub handler { Line 61  sub handler {
           &Apache::lonnet::allowed('vcg',$env{'request.course.id'});            &Apache::lonnet::allowed('vcg',$env{'request.course.id'});
     my $manage_permission =      my $manage_permission =
           &Apache::lonnet::allowed('mdg',$env{'request.course.id'});            &Apache::lonnet::allowed('mdg',$env{'request.course.id'});
   
     &Apache::lonhtmlcommon::clear_breadcrumbs();      &Apache::lonhtmlcommon::clear_breadcrumbs();
   
     my %functions = (      my %functions = (
Line 80  sub handler { Line 78  sub handler {
     $idx{udom} = &Apache::loncoursedata::CL_SDOM();      $idx{udom} = &Apache::loncoursedata::CL_SDOM();
     $idx{uname} = &Apache::loncoursedata::CL_SNAME();      $idx{uname} = &Apache::loncoursedata::CL_SNAME();
   
       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') {       if ($action eq 'create' || $action eq 'modify' || $action eq 'view') { 
         if ($view_permission || $manage_permission) {          if ($view_permission || $manage_permission) {
             &group_administration($r,$action,$cdom,$cnum,$function,$tabcol,              &group_administration($r,$action,$cdom,$cnum,$function,$tabcol,
                         \%functions,\%idx,$view_permission,$manage_permission);                                    \%functions,\%idx,$view_permission,
                                     $manage_permission,$rowColor1,$rowColor2);
         } else {          } else {
             $r->print('You do not have group administration '.              $r->print('You do not have group administration '.
                       'privileges in this course');                        'privileges in this course');
         }          }
     } else {      } else {
         &print_main_menu($r,$cdom,$cnum,$function,$tabcol,\%functions,\%idx,          &print_main_menu($r,$cdom,$cnum,$function,$tabcol,\%functions,\%idx,
                                           $view_permission,$manage_permission);                           $view_permission,$manage_permission,$action,
                            $rowColor1,$rowColor2);
     }      }
     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,$function,$tabcol,$functions,$idx,$view_permission,
                                                           $manage_permission)          $manage_permission,$action,$rowColor1,$rowColor2) = @_;
                                                                           = @_;  
     $r->print(&header('Course Groups',&mt('LON-CAPA Course Groups'),      $r->print(&header('Course Groups',&mt('LON-CAPA Course Groups'),
                                                  undef,undef,undef,$function));                undef,undef,undef,undef,$function));
     &Apache::lonhtmlcommon::add_breadcrumb      &Apache::lonhtmlcommon::add_breadcrumb
         ({href=>"/adm/coursegroups",          ({href=>"/adm/coursegroups",
           text=>"Course Groups",});            text=>"Course Groups",});
     $r->print(&Apache::lonhtmlcommon::breadcrumbs      $r->print(&Apache::lonhtmlcommon::breadcrumbs
                 (undef,'Course Groups'));                (undef,'Course Groups'));
     &display_groups($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,      &display_groups($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,
                                           $view_permission,$manage_permission);                      $view_permission,$manage_permission,$action,$rowColor1,
                       $rowColor2);
     $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,$function,$tabcol,$functions,$idx,$view_permission,
                                                           $manage_permission) = @_;          $manage_permission,$action,$rowColor1,$rowColor2) = @_;
     my %curr_groups = ();      my %curr_groups = ();
     my %grp_info = ();      my %grp_info = ();
     my $rowColor1 = "#dddddd";  
     my $rowColor2 = "#eeeeee";  
   
       my %actionlinks = (
         modify => '<a href="/adm/coursegroups?action=modify&state=pick_task&refpage='.
                   $env{'form.refpage'}.'&groupname=',
         view => '<a href="/adm/'.$cdom.'/'.$cnum.'/',
         delete => '<a href="/adm/coursegroups?action=delete&refpage='.
                   $env{'form.refpage'}.'&groupname=',
       );
       my %actiontext = &Apache::lonlocal::texthash( 
                             modify => 'Modify',
                             view => 'View',
                             delete => 'Delete',
                        );  
     $r->print('<br /><br />');      $r->print('<br /><br />');
     if ($view_permission) {      if ($view_permission) {
           if (!defined($action)) {
               $action = 'view';
           }
         my %curr_groups;          my %curr_groups;
         if (&Apache::loncommon::coursegroups(\%curr_groups,$cdom,$cnum)) {          if (&Apache::loncommon::coursegroups(\%curr_groups,$cdom,$cnum)) {
             $r->print(&Apache::lonhtmlcommon::start_pick_box());              $r->print(&Apache::lonhtmlcommon::start_pick_box());
Line 152  END Line 168  END
                 %{$grp_info{$group}} =                   %{$grp_info{$group}} = 
                                   &Apache::loncommon::get_group_settings(                                    &Apache::loncommon::get_group_settings(
                                                          $curr_groups{$group});                                                           $curr_groups{$group});
                 my $members_result = &group_members($cdom,$cnum,$group,\%grp_info);                  my $members_result = &group_members($cdom,$cnum,$group,
                                                       \%grp_info);
                 my $files_result = &group_files($group,\%grp_info);                   my $files_result = &group_files($group,\%grp_info); 
                 if ($env{'form.sortby'} eq 'groupname') {                  if ($env{'form.sortby'} eq 'groupname') {
                     push(@{$Sortby{$group}},$group);                      push(@{$Sortby{$group}},$group);
Line 171  END Line 188  END
                     push(@{$Sortby{$grp_info{$group}{'totalmembers'}}},                      push(@{$Sortby{$grp_info{$group}{'totalmembers'}}},
                                                                        $group);                                                                         $group);
                 } elsif ($env{'form.sortby'} eq 'totalfiles') {                  } elsif ($env{'form.sortby'} eq 'totalfiles') {
                     push(@{$Sortby{$grp_info{$group}{'totalfiles'}}},                      push(@{$Sortby{$grp_info{$group}{'totalfiles'}}},$group);
                                                                        $group);  
                 } elsif ($env{'form.sortby'} eq 'boards') {                  } elsif ($env{'form.sortby'} eq 'boards') {
                     push(@{$Sortby{$grp_info{$group}{'boards'}}},$group);                      push(@{$Sortby{$grp_info{$group}{'boards'}}},$group);
                 } elsif ($env{'form.sortby'} eq 'diskuse') {                  } elsif ($env{'form.sortby'} eq 'diskuse') {
Line 201  END Line 217  END
                     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;
                     foreach my $tool (sort keys(%{$functions})) {                      foreach my $tool (sort(keys(%{$functions}))) {
                         if (defined($grp_info{$group}{functions}{$tool})) {                          if (defined($grp_info{$group}{functions}{$tool})) {
                             $functionality .= ' '.$tool;                              $functionality .= ' '.$tool;
                         }                          }
Line 209  END Line 225  END
                     if (!$functionality) {                      if (!$functionality) {
                         $functionality = 'None available';                          $functionality = 'None available';
                     }                      }
                     $r->print('<tr bgcolor="'.$rowColor.'"><td align="right">                      my $link = $actionlinks{$action};
    <a href="/adm/'.$cdom.'/'.$cnum.'/'.$group.'/grppg?register=1"/>View</a>&nbsp;<a href="/adm/coursegroups?action=modify&group='.$group.'">Modify</a></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>');                      if ($action eq 'modify' || $action eq 'delete') {
                           $link .= $group;
                       } else {
                           $link .= $group.'/grppg?register=1';
                       }
                       $link .= '">'.$actiontext{$action}.'</a>';  
                       $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>');
                     $rowNum ++;                      $rowNum ++;
                 }                  }
             }              }
Line 226  END Line 248  END
             if (&Apache::loncommon::coursegroups(\%curr_groups,$cdom,$cnum)) {              if (&Apache::loncommon::coursegroups(\%curr_groups,$cdom,$cnum)) {
                 foreach my $group (@coursegroups) {                  foreach my $group (@coursegroups) {
                     my %group_info =  &Apache::loncommon::get_group_settings(                      my %group_info =  &Apache::loncommon::get_group_settings(
                                                    $curr_groups{$group});                                          $curr_groups{$group});
                     my $description = &Apache::lonnet::unescape(                      my $description = &Apache::lonnet::unescape(
                                                      $group_info{description});                                          $group_info{description});
                     my ($uname,$udom) = split(/:/,$group_info{creator});                      my ($uname,$udom) = split(/:/,$group_info{creator});
                     $r->print('<font size="+1"><a href="/adm/'.$udom.'/'.$uname.'/'.$group.'/grppg?register=1">'.$group,'</a><font><br /><small>'.$description.'</small><br /><br />');                      $r->print('<font size="+1"><a href="/adm/'.$udom.'/'.$uname.'/'.$group.'/grppg?register=1">'.$group,'</a><font><br /><small>'.$description.'</small><br /><br />');
                 }                  }
Line 242  END Line 264  END
   
 sub group_administration {  sub group_administration {
     my ($r,$action,$cdom,$cnum,$function,$tabcol,$functions,$idx,      my ($r,$action,$cdom,$cnum,$function,$tabcol,$functions,$idx,
                                      $view_permission,$manage_permission) = @_;          $view_permission,$manage_permission,$rowColor1,$rowColor2) = @_;
     my %sectioncount = ();      my %sectioncount = ();
     my @tools = ();      my @tools = ();
     my @types = ();      my @types = ();
Line 252  sub group_administration { Line 274  sub group_administration {
     my %userdata = ();      my %userdata = ();
     my @members = ();      my @members = ();
     my %usertools = ();      my %usertools = ();
       my %stored = ();
       my %memchg;
       my @member_changes = ('delete','expire','activate','reenable',
                             'changefunc','changepriv');
     my $state = $env{'form.state'};      my $state = $env{'form.state'};
     my ($groupname,$description,$startdate,$enddate);      my ($groupname,$description,$startdate,$enddate,$granularity,$specificity);
   
     if ($action eq 'create') {      if (defined($env{'form.groupname'})) {
           $groupname = $env{'form.groupname'};
       }
   
       if (($action eq 'create') && ($state eq '')) {
           $state = 'pick_name';
       }
       if (($action eq 'create') || 
           (($action eq 'modify') && ($state eq 'chgresult'))) { 
           ($startdate,$enddate) = &get_dates_from_form();
           if (defined($env{'form.description'})) {
               $description = $env{'form.description'};
           }
           if (defined($env{'form.tool'})) {
               @tools=&Apache::loncommon::get_env_multiple('form.tool');
           }
           if (defined($env{'form.granularity'})) {
               $granularity=$env{'form.granularity'};
           }
           if (defined($env{'form.specificity'})) {
               $specificity=$env{'form.specificity'};
           }
   
       }
       if (($action eq 'create') || (($action eq 'modify') 
           && (($state eq 'pick_privs') || ($state eq 'addresult')))) {
           if (defined($env{'form.member'})) {
               @members = &Apache::loncommon::get_env_multiple('form.member');
               foreach my $user (@members) {
                   %{$usertools{$user}} = ();
               }
           }
       }
   
       if (($action eq 'modify') && (($state eq 'change_privs') || ($state eq 'memresult'))) {
           foreach my $chg (@member_changes) {
               if (defined($env{'form.'.$chg})) {
                   @{$memchg{$chg}} = &Apache::loncommon::get_env_multiple('form.'.$chg);
               }
           }
           &check_changes(\@member_changes,\%memchg);
           foreach my $change (@member_changes) {
               if (($change eq 'delete') || ($change eq 'expire')) {
                   next;
               } 
               foreach my $user (@{$memchg{$change}}) {
                   %{$usertools{$user}} = ();
               }
           }
       }
   
       if ($action eq 'modify') {
         if ($state eq '') {          if ($state eq '') {
             $state = 'pick_name';              $state = 'pick_group';
         } else {          } else {
             ($startdate,$enddate) = &get_dates_from_form();              %stored = &retrieve_settings($cdom,$cnum,$groupname);
             if (defined($env{'form.groupname'})) {              if (ref($stored{'types'}) eq 'ARRAY') {
                 $groupname = $env{'form.groupname'};                  @types = @{$stored{'types'}};
             }              }
             if (defined($env{'form.description'})) {              if (ref($stored{'roles'}) eq 'ARRAY') {
                 $description = $env{'form.description'};                  @roles = @{$stored{'roles'}};
             }              }
             if (defined($env{'form.tool'})) {              if (ref($stored{'sectionpick'}) eq 'ARRAY') {
                 @tools=&Apache::loncommon::get_env_multiple('form.tool');                  @sections = @{$stored{'sectionpick'}};
             }              }
             if (defined($env{'form.member'})) {              unless ($state eq 'chgresult') {
                 @members = &Apache::loncommon::get_env_multiple('form.member');                  if (ref($stored{'tool'}) eq 'ARRAY') { 
                 foreach my $user (@members) {                      @tools = @{$stored{'tool'}};
                     %{$usertools{$user}} = ();  
                 }                  }
                   $startdate = $stored{'startdate'};
                   $enddate = $stored{'enddate'};
                   $description = $stored{'description'};
                   $granularity = $stored{'granularity'};
                   $specificity =  $stored{'specificity'};
             }              }
         }          }
     }      }
Line 322  sub group_administration { Line 402  sub group_administration {
         startdate_hour => 'selectbox',          startdate_hour => 'selectbox',
         enddate_month => 'selectbox',          enddate_month => 'selectbox',
         enddate_hour => 'selectbox',          enddate_hour => 'selectbox',
         types => 'selectbox',  
         roles => 'selectbox',  
         startdate_day => 'text',          startdate_day => 'text',
         startdate_year => 'text',          startdate_year => 'text',
         startdate_minute => 'text',          startdate_minute => 'text',
Line 338  sub group_administration { Line 416  sub group_administration {
         granularity => 'radio',          granularity => 'radio',
         no_end_date => 'checkbox',          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') {
           foreach my $role (@{$stored{'autorole'}}) {
               $elements{'modify'}{'change_settings'}{'sec_'.$role} = 'selectbox'; 
           }
       }
     %{$elements{'create'}{'pick_members'}} = (      %{$elements{'create'}{'pick_members'}} = (
         member => 'checkbox',          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'}{'roles'} = 'selectbox';
       }
       if ((($action eq 'create') &&  
           (($state eq 'pick_name') || ($state eq 'pick_privs'))) ||
          (($action eq 'modify') && (($state eq 'change_settings') ||
                                     ($state eq 'add_members')))) {
         my $numsections = &Apache::loncommon::get_sections($cdom,$cnum,          my $numsections = &Apache::loncommon::get_sections($cdom,$cnum,
                            \%sectioncount);                                                             \%sectioncount);
         if ($numsections > 0) {          if ($numsections > 0) {
             $elements{'create'}{'pick_name'}{'sectionpick'} = 'selectbox';              $elements{'create'}{'pick_name'}{'sectionpick'} = 'selectbox';
               $elements{'modify'}{'change_mapping'}{'sectionpick'} = 'selectbox';
               $elements{'modify'}{'add_members'}{'sectionpick'} = 'selectbox';
         }          }
     }      }
                                                                                         
     if (($action eq 'create') && (($state eq 'pick_members') ||      if ($action eq 'create') {
                                   ($state eq 'pick_privs'))) {  
         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 363  sub group_administration { Line 469  sub group_administration {
                 @sections = sort {$a cmp $b} keys(%sectioncount);                  @sections = sort {$a cmp $b} keys(%sectioncount);
             }              }
         }          }
       }
   
       if (($state eq 'pick_members') || ($state eq 'pick_privs')) {
         &build_members_list($cdom,$cnum,\@types,\@roles,          &build_members_list($cdom,$cnum,\@types,\@roles,
                         \@sections,\%users,\%userdata);                              \@sections,\%users,\%userdata);
         if ((keys(%users) > 0) && (@tools > 0)) {          if ((keys(%users) > 0) && (@tools > 0)) {
             foreach my $tool (@tools) {              foreach my $tool (@tools) {
                 if ($env{'form.granularity'} eq 'Yes') {                  if ($granularity eq 'Yes') {
                     $elements{'create'}{'pick_members'}{'user_'.$tool} = 'checkbox';                      $elements{$action}{'pick_members'}{'user_'.$tool} = 'checkbox';
                 }                  }
             }              }
             $elements{'create'}{'pick_members'}{'specificity'} = 'radio';              $elements{$action}{'pick_members'}{'specificity'} = 'radio';
         }          }
     }      }
   
     if (($action eq 'create') && (($state eq 'pick_privs') || (($state eq 'result') &&      if (($state eq 'pick_privs') || ($state eq 'change_privs') ||
          ($env{'form.specificity'} eq 'No')))) {          (($specificity eq 'No') && 
            (($state eq 'result') || ($state eq 'memresult')))) {
         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) {
Line 385  sub group_administration { Line 495  sub group_administration {
                 }                  }
             }              }
         }          }
         if (($state eq 'pick_privs') && ($env{'form.specificity'} eq 'Yes')) {          if ((($state eq 'pick_privs') || ($state eq 'change_privs'))
             foreach my $member (@members) {              && ($specificity eq 'Yes')) {
                 foreach my $tool (keys(%{$usertools{$member}})) {              foreach my $user (sort(keys(%usertools))) {
                   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{'create'}{'pick_privs'}{'userpriv_'.$priv} =                              $elements{$action}{$state}{'userpriv_'.$priv} = 'checkbox';
                                                                    'checkbox';  
                         }                          }
                     }                      }
                 }                  }
Line 399  sub group_administration { Line 509  sub group_administration {
         }          }
     }      }
     
     my $jscript;      my $jscript = &Apache::loncommon::check_uncheck_jscript();
     if ($env{'form.action'} eq 'create') {  
         $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;
Line 414  function backPage(formname,prevstate) { Line 521  function backPage(formname,prevstate) {
 }  }
                                                                                                                                                                               
 |;  |;
                                                                                         
     $jscript .= &Apache::lonhtmlcommon::set_form_elements(      $jscript .= &Apache::lonhtmlcommon::set_form_elements(
                            \%{$elements{$action}{$state}});                             \%{$elements{$action}{$state}},\%stored);
       my $page = 0;
       my %states = ();
       my %branchstates = ();
       @{$states{'create'}} = ('pick_name','pick_members','pick_privs','result');
       @{$states{'modify'}} = ('pick_group','pick_task');
       @{$branchstates{'noprivs'}} = ('result');
       @{$branchstates{'settings'}} = ('change_settings','chgresult');
       @{$branchstates{'members'}} = ('change_members','change_privs','memresult');
       @{$branchstates{'adds'}} = ('add_members','pick_members','pick_privs',
                                   'addresult');
       
       if (defined($env{'form.branch'})) {
           push (@{$states{$action}},@{$branchstates{$env{'form.branch'}}});
       }
   
       if (($action eq 'create') || ($action eq 'modify')) {
           my $done = 0;
           my $i=0;
           while ($i<@{$states{$action}} && !$done) {
               if ($states{$action}[$i] eq $state) {
                   $page = $i;
                   $done = 1;
               }
               $i++;
           }
       }
   
     my $loaditems =  &onload_action($action,$state);      my $loaditems =  &onload_action($action,$state);
     $r->print(&header('Course Groups Manager',&mt('LON-CAPA Groups Manager'),      $r->print(&header('Course Groups Manager',&mt('LON-CAPA Groups Manager'),
                                $jscript,$action,$state,$function,$loaditems));                            $jscript,$action,$state,$page,$function,$loaditems));
   
     if ($env{'form.refpage'} eq 'enrl') {      if ($env{'form.refpage'} eq 'enrl') {
         &Apache::lonhtmlcommon::add_breadcrumb          &Apache::lonhtmlcommon::add_breadcrumb
Line 435  function backPage(formname,prevstate) { Line 566  function backPage(formname,prevstate) {
           faq=>9,bug=>'Instructor Interface',});            faq=>9,bug=>'Instructor Interface',});
     }      }
   
     my %states = ();  
     @{$states{'create'}} = ('pick_name','pick_members','pick_privs','result');  
     @{$states{'modify'}} = ();  
                                                                                         
     my %trail = ();      my %trail = ();
     %{$trail{'create'}} = (      %{$trail{'create'}} = &Apache::lonlocal::texthash (
                             pick_name => 'Group Settings',                              pick_name => 'Group 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'}} = ();      %{$trail{'modify'}} = &Apache::lonlocal::texthash(
                                                                                                                     pick_group => 'Groups',
                               pick_task => 'Choose Task',
                               change_settings => 'Group Settings',
                               change_members => 'Modify/Delete Members',
                               change_privs => 'Change Privileges',
                               change_mapping => 'Membership Mapping',
                               add_members => 'Add Members',
                               pick_members => 'Select Members',
                               pick_privs => 'Choose Privileges',
                               chgresult => 'Setting Changes Complete',
                               memresult => 'Modifications Complete',
                               addresult => 'Additions Complete',
                             );
       my %navbuttons = &Apache::lonlocal::texthash(
                                gtns => 'Go to next step',
                                gtps => 'Go to previous step',
                                crgr => 'Create group',
                                mose => 'Modify settings',
                                gtpp => 'Go to previous page',
                                adme => 'Add members',
       );
     if ((($action eq 'create') || ($action eq 'modify')) &&      if ((($action eq 'create') || ($action eq 'modify')) &&
               ($manage_permission)) {                ($manage_permission)) {
         for (my $i=0; $i<@{$states{$action}}; $i++) {          for (my $i=0; $i<@{$states{$action}}; $i++) {
Line 456  function backPage(formname,prevstate) { Line 603  function backPage(formname,prevstate) {
                    {text=>"$trail{$action}{$state}"});                     {text=>"$trail{$action}{$state}"});
                 $r->print(&Apache::lonhtmlcommon::breadcrumbs                  $r->print(&Apache::lonhtmlcommon::breadcrumbs
                      (undef,'Course Groups Manager'));                       (undef,'Course Groups Manager'));
                 &display_control($r,$cdom,$cnum,$tabcol,$action,$state,                  &display_control($r,$cdom,$cnum,$tabcol,$action,$state,$page,
                          \%sectioncount,$groupname,$description,$functions,                         \%sectioncount,$groupname,$description,$functions,
                          \@tools,\%toolprivs,\%fixedprivs,$startdate,$enddate,                         \@tools,\%toolprivs,\%fixedprivs,$startdate,$enddate,
                          \%users,\%userdata,$idx,\@members,\%usertools);                         \%users,\%userdata,$idx,\%memchg,\%usertools,
                          $function,$view_permission,$manage_permission,
                          \%stored,$granularity,$specificity,\@types,\@roles,
                          \@sections,\%states,\%navbuttons,$rowColor1,$rowColor2);
                 last;                  last;
             } else {              } else {
                 if ($state eq 'result' && $i > 0) {                  if (($state  =~ /^\w+result$/) && ($i > 0)) {
                     &Apache::lonhtmlcommon::add_breadcrumb(                      &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]}"});
Line 479  function backPage(formname,prevstate) { Line 629  function backPage(formname,prevstate) {
         $r->print(&Apache::lonhtmlcommon::breadcrumbs          $r->print(&Apache::lonhtmlcommon::breadcrumbs
                      (undef,'Course Groups Manager'));                       (undef,'Course Groups Manager'));
         &display_groups($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,          &display_groups($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,
                                         $view_permission,$manage_permission);                          $view_permission,$manage_permission,$action,
                           $rowColor1,$rowColor2);
   
     }      }
     $r->print(&footer());      $r->print(&footer());
     return;      return;
 }  }
   
   sub retrieve_settings {
       my ($cdom,$cnum,$groupname) = @_;
       my %groupinfo;
       my %stored;
       my %curr_groups;
       my $numgroups = &Apache::loncommon::coursegroups(\%curr_groups,$cdom,
                                                                $cnum,$groupname);
       if ($numgroups > 0) {
           %groupinfo = &Apache::loncommon::get_group_settings(
                                                        $curr_groups{$groupname});
           $stored{'description'} = &Apache::lonnet::unescape(
                                                       $groupinfo{'description'});
           $stored{'startdate'} = $groupinfo{'startdate'};
           $stored{'enddate'} = $groupinfo{'enddate'};
           if ($stored{'enddate'} == 0) {
               $stored{'no_end_date'} = 1;
           }
           $stored{'granularity'} = $groupinfo{'granularity'};
           $stored{'specificity'} = $groupinfo{'specificity'};
           $stored{'creation'} = $groupinfo{'creation'};
           $stored{'creator'} = $groupinfo{'creator'};
   
           foreach my $tool (sort(keys(%{$groupinfo{'functions'}}))) {
               if ($groupinfo{functions}{$tool} eq 'on') {
                   push(@{$stored{tool}},$tool);
               }
           }
           foreach my $role (@{$groupinfo{'roles'}}) {
               push(@{$stored{roles}},$role);
           }
           foreach my $type (@{$groupinfo{'types'}}) {
               push(@{$stored{types}},$type);
           }
           foreach my $section (@{$groupinfo{'sectionpick'}}) {
               push(@{$stored{sectionpick}},$section);
           }
           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'}}))) {
                   foreach my $section (@{$groupinfo{'autosec'}{$role}}) {
                       push (@{$stored{'sec_'.$role}},$section);
                   }
                   if (@{$groupinfo{'autosec'}{$role}} > 0) {
                       push(@{$stored{'autorole'}},$role);
                   }
               }
           }
       }
       return %stored;
   }
   
 sub display_control {  sub display_control {
     my ($r,$cdom,$cnum,$tabcol,$action,$state,$sectioncount,$groupname,      my ($r,$cdom,$cnum,$tabcol,$action,$state,$page,$sectioncount,$groupname,
         $description,$functions,$tools,$toolprivs,$fixedprivs,$startdate,          $description,$functions,$tools,$toolprivs,$fixedprivs,$startdate,
                       $enddate,$users,$userdata,$idx,$members,$usertools) = @_;          $enddate,$users,$userdata,$idx,$memchg,$usertools,$function,
           $view_permission,$manage_permission,$stored,$granularity,$specificity,
           $types,$roles,$sections,$states,$navbuttons,$rowColor1,$rowColor2)=@_;
     if ($action eq 'create') {      if ($action eq 'create') {
         if ($state eq 'pick_name') {          if ($state eq 'pick_name') {
             &first_creation_form($r,$cdom,$cnum,$tabcol,$state,$functions,              &general_settings_form($r,$cdom,$cnum,$action,$tabcol,$state,$page,
                                                                 $sectioncount);                                     $functions,$tools,$toolprivs,$fixedprivs,
                                      $sectioncount,$stored,$states,$navbuttons,
                                      $rowColor1,$rowColor2);
         } elsif ($state eq 'pick_members') {          } elsif ($state eq 'pick_members') {
             &second_creation_form($r,$cdom,$cnum,$tabcol,$state,$groupname,              &choose_members_form($r,$cdom,$cnum,$tabcol,$action,$state,$page,
                                   $description,$startdate,$enddate,$tools,                                   $groupname,$description,$granularity,
                                              $functions,$users,$userdata,$idx);                                   $startdate,$enddate,$tools,$fixedprivs,
                                    $toolprivs,$functions,$users,$userdata,$idx,
                                    $stored,$states,$navbuttons,$rowColor1,
                                    $rowColor2);
         } elsif ($state eq 'pick_privs') {          } elsif ($state eq 'pick_privs') {
             &third_creation_form($r,$cdom,$cnum,$tabcol,$state,$startdate,              &choose_privs_form($r,$cdom,$cnum,$tabcol,$action,$state,$page,
                            $enddate,$tools,$functions,$toolprivs,$fixedprivs,                                 $startdate,$enddate,$tools,$functions,
                                            $userdata,$members,$usertools,$idx);                                 $toolprivs,$fixedprivs,$userdata,$usertools,
                                  $idx,$states,$stored,$sectioncount,$navbuttons,
                                  $rowColor1,$rowColor2);
         } elsif ($state eq 'result') {          } elsif ($state eq 'result') {
             &completed_creation($r,$cdom,$cnum,$tabcol,$state,$groupname,              &process_request($r,$cdom,$cnum,$tabcol,$action,$state,$page,
                             $description,$userdata,$startdate,$enddate,$tools,                               $groupname,$description,$specificity,$userdata,
                                $functions,$toolprivs,$members,$usertools,$idx);                               $startdate,$enddate,$tools,$functions,
                                $toolprivs,$usertools,$idx,$types,$roles,
                                $sections,$states,$navbuttons,$memchg,
                                $sectioncount,$stored,$rowColor1,$rowColor2);
           }
       } elsif ($action eq 'modify') {
           my $groupname = $env{'form.groupname'};
           if ($state eq 'pick_group') {
               &display_groups($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,
                               $view_permission,$manage_permission,$action,
                               $rowColor1,$rowColor2);
           } elsif ($state eq 'pick_task') {
               &modify_menu($r,$groupname,$page);
           } elsif ($state eq 'change_settings') {
               &general_settings_form($r,$cdom,$cnum,$action,$tabcol,$state,$page,
                                      $functions,$tools,$toolprivs,$fixedprivs,
                                      $sectioncount,$stored,$states,$navbuttons,
                                      $rowColor1,$rowColor2);
           } elsif ($state eq 'change_members') {
               &change_members_form($r,$cdom,$cnum,$tabcol,$action,$state,$page,
                                    $groupname,$description,$startdate,$enddate,
                                    $tools,$fixedprivs,$functions,$users,
                                    $userdata,$granularity,$specificity,$idx,
                                    $states,$navbuttons,$rowColor1,$rowColor2);
           } elsif ($state eq 'add_members') {
               &add_members_form($r,$tabcol,$action,$state,$page,$startdate,
                                 $enddate,$groupname,$description,$granularity,
                                 $sectioncount,$tools,$functions,$stored,$states,
                                 $navbuttons,$rowColor1,$rowColor2);
           } elsif ($state eq 'pick_members') {
               &choose_members_form($r,$cdom,$cnum,$tabcol,$action,$state,$page,
                                    $groupname,$description,$granularity,
                                    $startdate,$enddate,$tools,$fixedprivs,
                                    $toolprivs,$functions,$users,$userdata,$idx,
                                    $stored,$states,$navbuttons,$rowColor1,
                                    $rowColor2);
           } elsif ($state eq 'pick_privs') {
               &choose_privs_form($r,$cdom,$cnum,$tabcol,$action,$state,$page,
                                  $startdate,$enddate,$tools,$functions,
                                  $toolprivs,$fixedprivs,$userdata,$usertools,
                                  $idx,$states,$stored,$sectioncount,$navbuttons,
                                  $rowColor1,$rowColor2);
           } elsif ($state eq 'change_privs') {
               &change_privs_form($r,$cdom,$cnum,$tabcol,$action,$state,$page,
                                  $startdate,$enddate,$tools,$functions,
                                  $toolprivs,$fixedprivs,$userdata,$usertools,
                                  $memchg,$idx,$states,$stored,$sectioncount,
                                  $navbuttons,$rowColor1,$rowColor2) = @_;
           } elsif ($state eq 'chgresult' || $state eq 'memresult' || 
                    $state eq 'addresult') {
               &process_request($r,$cdom,$cnum,$tabcol,$action,$state,$page,
                                $groupname,$description,$specificity,$userdata,
                                $startdate,$enddate,$tools,$functions,
                                $toolprivs,$usertools,$idx,$types,$roles,
                                $sections,$states,$navbuttons,$memchg,
                                $sectioncount,$stored,$rowColor1,$rowColor2);
         }          }
     }      }
 }  }
   
 sub header {  sub header {
     my ($bodytitle,$title,$jscript,$action,$state,$function,$loaditems) = @_;      my ($bodytitle,$title,$jscript,$action,$state,$page,$function,$loaditems) = @_;
     my $html=&Apache::lonxml::xmlbegin();      my $html=&Apache::lonxml::xmlbegin();
     my $bodytag=&Apache::loncommon::bodytag($bodytitle,$function,$loaditems);      my $bodytag=&Apache::loncommon::bodytag($bodytitle,$function,$loaditems);
     my $output = <<"END";      my $output = <<"END";
Line 531  END Line 801  END
  <input type="hidden" name="action" value="$action" />   <input type="hidden" name="action" value="$action" />
  <input type="hidden" name="state" value="" />   <input type="hidden" name="state" value="" />
  <input type="hidden" name="origin" value="$state" />   <input type="hidden" name="origin" value="$state" />
    <input type="hidden" name="page" value="$page" />
 END  END
     }      }
     return $output;      return $output;
Line 547  sub onload_action { Line 818  sub onload_action {
              'onload="javascript:setFormElements(document.'.$state.')"';               'onload="javascript:setFormElements(document.'.$state.')"';
         }          }
     }      }
       if (($action eq 'modify') &&
                   ($state eq 'change_settings' || $state eq 'change_members' ||
                    $state eq 'change_privs') || $state eq 'add_members') {
               $loaditems =
                'onload="javascript:setFormElements(document.'.$state.')"';
       }
     return $loaditems;      return $loaditems;
 }  }
   
Line 568  sub build_members_list { Line 845  sub build_members_list {
         $access{$type} = $type;          $access{$type} = $type;
     }      }
     &Apache::loncommon::get_course_users($cdom,$cnum,\%access,$roles,      &Apache::loncommon::get_course_users($cdom,$cnum,\%access,$roles,
                                           $sections,$users,$userdata);                                           $sections,$users,$userdata);
     return;      return;
 }  }
   
Line 610  sub group_members { Line 887  sub group_members {
 }  }
   
   
 sub first_creation_form {  sub general_settings_form {
     my ($r,$cdom,$cnum,$tabcol,$formname,$functions,$sectioncount) = @_;      my ($r,$cdom,$cnum,$action,$tabcol,$formname,$page,$functions,$tools,
           $toolprivs,$fixedprivs,$sectioncount,$stored,$states,$navbuttons,
           $rowColor1,$rowColor2) = @_;
       my ($nexttext,$prevtext);
       $r->print(' <br />
    <table width="100%" cellpadding="0" cellspacing="0" border="0">
   ');
       &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') {
           &membership_options($r,$action,$formname,$tabcol,$sectioncount,3);
           $nexttext = $$navbuttons{'gtns'};
       } else {
           my @available = ();
           my @unavailable = ();
           &check_tools($functions,$tools,\@available,\@unavailable);
           @{$tools} = sort(keys(%{$functions}));
           &privilege_specificity($r,$tabcol,$rowColor1,$rowColor2,$action,
                                  3,$tools,$stored,$toolprivs,$fixedprivs,
                                  \@available,$formname);
           $r->print('
     <tr>
      <td colspan="4">&nbsp;</td>
     </tr>');
           &mapping_options($r,$action,$formname,$page,$tabcol,$sectioncount,
                            $states,$stored,$navbuttons,4,5,$rowColor1,
                            $rowColor2);
           $nexttext = $$navbuttons{'mose'};
       }
       $prevtext = $$navbuttons{'gtpp'};
       &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext,
                           $$states{$action}[$page+1],$nexttext);
       $r->print('
    </table>');
       return;
   }
   
   sub groupsettings_options {
       my ($r,$tabcol,$functions,$action,$formname,$stored,$image) = @_;
     my %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
         'gmem' => 'Group membership options',  
         'picr' => 'Pick the criteria to use to build a list of course users '.  
                   'from which you will select members of the new group',     
         'gdat' => 'Group open and close dates',          'gdat' => 'Group open and close dates',
         'sten' => 'Set a start date/time and end date/time for the group',          'sten' => 'Set a start date/time and end date/time for the group',
         'acty' => 'Access types',  
         'coro' => 'Course roles',  
         'cose' => 'Course sections',  
         'gfun' => 'Group functionality',          'gfun' => 'Group functionality',
           'gnde' => 'Group name, description and available functionality',
           'desc' => 'Description',
           'func' => 'Functionality',
           'gnam' => 'Group Name',
           'doyo' => 'Do you want to assign different functionality '.
                     'to different group members?',
     );      );
       &topic_bar($r,$tabcol,$image,$lt{'gnde'});
     my %status_types = (      $r->print('
                    active => &mt('Currently has access'),  
                    previous => &mt('Previously had access'),  
                    future => &mt('Will have future access'),  
                    );  
   
     my @roles = ('st','cc','in','ta','ep','cr');  
   
     my $starttime = time;  
     my $endtime = time+(6*30*24*60*60); # 6 months from now, approx  
     my ($start_table,$end_table) = &date_setting_table  
                                     ($starttime,$endtime,$formname);  
   
     my @sections = ();  
     my $section_sel = '';  
     my $numvisible = 4;  
   
     @sections = sort {$a cmp $b} keys(%{$sectioncount});  
     if (@sections > 0) {  
         unshift(@sections,'_all'); # Put 'all' at the front of the list  
         if (@sections < 4) {  
             $numvisible = @sections;  
         }  
         foreach (@sections) {  
             if ($_ eq '_all') {  
                 $section_sel .= '  <option value="'.$_.'" />all sections'."\n";  
             } else {  
                 $section_sel .= '  <option value="'.$_.'" />'.$_."\n";  
             }  
         }  
     }  
   
     $r->print(<<"END");  
  <br />  
  <table width="100%" cellpadding="0" cellspacing="0" border="0">  
    <tr bgcolor="$tabcol">  
      <td>&nbsp;</td>  
      <td valign="bottom"><nobr><img src="/res/adm/pages/bl_step1.gif"   
          valign="bottom">&nbsp;&nbsp;</nobr>  
      </td>  
      <td align="left"><nobr>  
        <font face="arial,helvetica,sans-serif"><b>Group name, description  
          and available functionality</b></font></nobr>   
      </td>  
      <td width="100%">&nbsp;</td>  
    </tr>  
    <tr>  
     <td colspan="4">&nbsp;</td>  
    </tr>  
    <tr>     <tr>
     <td>&nbsp;</td>      <td>&nbsp;</td>
     <td colspan="3">      <td colspan="3">
      <table border="0" cellpadding="2" cellspacing="2">       <table border="0" cellpadding="2" cellspacing="2">
       <tr>        <tr>
        <td><b>Group Name:</b></td>         <td><b>'.$lt{'gnam'}.':</b></td>
        <td colspan="5"><input type="text" name="groupname" size="25" />         <td colspan="5">
   ');
       if ($action eq 'create') {
           $r->print('<input type="text" name="groupname" size="25" />');
       } else {
           $r->print('<input type="hidden" name="groupname" value="'.
                            $env{'form.groupname'}.'" />'.$env{'form.groupname'});
       }
       $r->print(<<"END");
        </td>         </td>
       <tr>        <tr>
       <tr>        <tr>
        <td><b>Description:</b></td>         <td><b>$lt{'desc'}:</b></td>
        <td colspan="5"><input type="text" name="description" size="40" />         <td colspan="5"><input type="text" name="description" size="40"
                                                       value="" />
        </td>         </td>
       <tr>        <tr>
       <tr>        <tr>
        <td><b>Functionality:</b></td>         <td><b>$lt{'func'}:</b></td>
 END  END
     my $numitems = keys(%{$functions});      my $numitems = keys(%{$functions});
     my $halfnum = int($numitems/2);      my $halfnum = int($numitems/2);
Line 696  END Line 980  END
     if ($remnum) {      if ($remnum) {
         $halfnum ++;          $halfnum ++;
     }      }
     my @allfunctions = sort (keys (%{$functions}));      my @allfunctions = sort(keys (%{$functions}));
     for (my $i=0; $i<$halfnum; $i++) {      for (my $i=0; $i<$halfnum; $i++) {
         $r->print('<td><input type="checkbox" name="tool" value="'.          $r->print('<td><input type="checkbox" name="tool" value="'.
                   $allfunctions[$i].'" />&nbsp;'.                    $allfunctions[$i].'" />&nbsp;'.
Line 715  END Line 999  END
     if ($remnum) {      if ($remnum) {
         $r->print('<td>&nbsp;</td>');          $r->print('<td>&nbsp;</td>');
     }      }
     $r->print(<<"END");       $r->print('
        <td>         <td>
         <input type="button" value="uncheck all"           <input type="button" value="uncheck all"
           onclick="javascript:uncheckAll(document.$formname.tool)" />            onclick="javascript:uncheckAll(document.'.$formname.'.tool)" />
        </td>         </td>
       </tr>        </tr>
       <tr>        <tr>
        <td><b>Granularity:</b></td>         <td><b>Granularity:</b></td>
        <td colspan="9">Do you want to assign different functionality to different group members?&nbsp;<input type="radio" name="granularity" value="Yes" />Yes&nbsp;<input type="radio" name="granularity" value="No" checked="checked" />No</td>         <td colspan="9">'.$lt{'doyo'}.'&nbsp;<input type="radio" name="granularity" value="Yes" />'.&mt('Yes').'&nbsp;<input type="radio" name="granularity" value="No" checked="checked" />'.&mt('No'));
       </tr>       if ($action eq 'modify') {
           $r->print('&nbsp;&nbsp;('.&mt('Currently set to "[_1]"',
                                         $$stored{'granularity'}).')');
       }
       $r->print('
          </td>
         </tr>
      </table>       </table>
     </td>      </td>
    </tr>     </tr>
    <tr>  ');
     <td colspan="4">&nbsp;</td>      return;
    </tr>  }
    <tr bgcolor="$tabcol">  
     <td>&nbsp;</td>  sub membership_options {
     <td valign="bottom"><nobr><img src="/res/adm/pages/bl_step2.gif"       my ($r,$action,$state,$tabcol,$sectioncount,$image) = @_;
         valign="bottom">&nbsp;&nbsp;</nobr>      my %lt = &Apache::lonlocal::texthash(
     </td>                  'pipa' => 'Pick parameters to generate membership list',
     <td align="left"><nobr>                  'gmem' => 'Group membership options',
       <font face="arial,helvetica,sans-serif"><b>Start and end dates for group                  'picr' => 'Pick the criteria to use to build a list of '.
                                                   access</b></font></nobr>                            'course users from which you will select ',
     </td>                  'meof' => 'members of the new group.',
     <td width="100%">&nbsp;</td>                  'adme' => 'additional members of the group.',
    </tr>                  'ifno' => 'If you do not wish to add members when you first '.
    <tr>                            'create the group, do not make any selections',  
     <td colspan="4">&nbsp;</td>                  'acty' => 'Access types',
    </tr>                  'coro' => 'Course roles',
    <tr>                  'cose' => 'Course sections',
     <td>&nbsp;</td>               );
     <td colspan="3">$start_table</td>      my %status_types = (
    <tr>                     active => &mt('Currently has access'),
    <tr>                     previous => &mt('Previously had access'),
     <td colspan="4">&nbsp;</td>                     future => &mt('Will have future access'),
    </tr>                     );
    <tr>                                                                                   
     <td>&nbsp;</td>      my @roles = ('st','cc','in','ta','ep','cr');
     <td colspan="3">$end_table</td>  
    <tr>      my @sections = keys(%{$sectioncount});
    <tr>  
     <td colspan="4">&nbsp;</td>      &topic_bar($r,$tabcol,$image,$lt{'pipa'});
    </tr>      $r->print('
    <tr bgcolor="$tabcol">  
     <td>&nbsp;</td>  
     <td valign="bottom"><nobr><img src="/res/adm/pages/bl_step3.gif"   
         valign="bottom">&nbsp;&nbsp;</nobr>  
     </td>  
     <td align="left"><nobr>  
      <font face="arial,helvetica,sans-serif"><b>Pick parameters to generate   
          membership list</b></nobr>  
      </font>  
     </td>  
     <td width="100%">&nbsp;</td>  
    </tr>  
    <tr>  
     <td colspan="4">&nbsp;</td>  
    </tr>  
    <tr>     <tr>
     <td>&nbsp;</td>      <td>&nbsp;</td>
     <td colspan="3">      <td colspan="3">
      <b>$lt{'gmem'}</b><br/> $lt{'picr'}       <b>'.$lt{'gmem'}.'</b><br/>'.$lt{'picr'});
      <br /><br />      if ($action eq 'create') {
           $r->print($lt{'meof'}.'<br />'.$lt{'ifno'});
       } else {
           $r->print($lt{'adme'});
       }
       $r->print('
        <br />
        <br />
      <table border="0">       <table border="0">
       <tr>        <tr>
        <td><b>$lt{'acty'}</b></td>         <td><b>'.$lt{'acty'}.'</b></td>
        <td>&nbsp;</td>         <td>&nbsp;</td>
        <td><b>$lt{'coro'}</b></td>         <td><b>'.$lt{'coro'}.'</b></td>');
 END  
     if (@sections >0) {      if (@sections >0) {
          $r->print('          $r->print('
        <td>&nbsp;</td>         <td>&nbsp;</td>
        <td><b>'.$lt{'cose'}.'</b></td>         <td><b>'.$lt{'cose'}.'</b></td>
        <td>&nbsp;</td>');         <td>&nbsp;</td>');
Line 796  END Line 1077  END
     $r->print('<td>&nbsp;</td>');      $r->print('<td>&nbsp;</td>');
     $r->print(&Apache::lonhtmlcommon::role_select_row(\@roles));      $r->print(&Apache::lonhtmlcommon::role_select_row(\@roles));
     if (@sections > 0) {      if (@sections > 0) {
         $r->print('          @sections = sort {$a cmp $b} @sections;
        <td>&nbsp;</td>          unshift(@sections,'_all'); # Put 'all' at the front of the list
        <td colspan="3" align="center" valign="top">          unshift(@sections,'_nosec'); # Put 'no sections' next
         <select name="sectionpick" multiple="true" size="'.$numvisible.'">          $r->print('<td>&nbsp;</td>
           '.$section_sel.'                     <td colspan="3" align="center" valign="top">'.
         </select>          &sections_selection(\@sections,'sectionpick').'</td>');
        </td>');  
     }      }
     $r->print('      $r->print('
       </tr>        </tr>
      </table>       </table>
     </td>      </td>
    </tr>     </tr>');
       return;
   }
   
   sub sections_selection {
       my ($sections,$elementname) = @_;
       my $section_sel;
       my $numvisible = 4;
       if (@{$sections} < 4) {
           $numvisible = @{$sections};
       }
       foreach my $sec (@{$sections}) {
           if ($sec eq '_all') {
               $section_sel .= '  <option value="'.$sec.'" />all sections'."\n";
           } elsif ($sec eq '_nosec') {
               $section_sel .= '  <option value="'.$sec.'" />no section'."\n"; 
           } else {
               $section_sel .= '  <option value="'.$sec.'" />'.$sec."\n";
           }
       }
       my $output = '
           <select name="'.$elementname.'" multiple="true" size="'.$numvisible.'">
             '.$section_sel.'
           </select>';
       return $output;
   }
   
   sub access_date_settings {
       my ($r,$tabcol,$action,$formname,$stored,$image) = @_;
       my %lt = &Apache::lonlocal::texthash(
                   'sten' => 'Default start and end dates for group access',
                );
       my $starttime = time;
       my $endtime = time+(6*30*24*60*60); # 6 months from now, approx
       if ($action eq 'modify') {
           $starttime = $$stored{'startdate'};
           unless ($$stored{'enddate'} == 0) {
               $endtime = $$stored{'enddate'};
           }
       }
       my ($start_table,$end_table) = &date_setting_table
                                       ($starttime,$endtime,$formname);
       &topic_bar($r,$tabcol,$image,$lt{'sten'});
       $r->print('
      <tr>
       <td>&nbsp;</td>
       <td colspan="3">'.$start_table.'</td>
      <tr>
    <tr>     <tr>
     <td colspan="4">&nbsp;</td>      <td colspan="4">&nbsp;</td>
    </tr>     </tr>
    <tr>     <tr>
     <td>&nbsp;</td>      <td>&nbsp;</td>
     <td colspan="3" align="left">      <td colspan="3">'.$end_table.'</td>
      <input type="button" value="Go to next step"       <tr>');
      onclick="javascript:nextPage(document.'.$formname.','."'pick_members'".')>  
     </td>  
    </tr>  
 </table>  
 ');  
     return;      return;
 }  }
   
 sub second_creation_form {  sub choose_members_form {
     my ($r,$cdom,$cnum,$tabcol,$formname,$groupname,$description,$startdate,      my ($r,$cdom,$cnum,$tabcol,$action,$formname,$page,$groupname,$description,
                         $enddate,$tools,$functions,$users,$userdata,$idx) = @_;          $granularity,$startdate,$enddate,$tools,$fixedprivs,$toolprivs,
     my @regexps = ('user_','userpriv_');          $functions,$users,$userdata,$idx,$stored,$states,$navbuttons,
           $rowColor1,$rowColor2) = @_;
       my @regexps = ('user_','userpriv_','sec_');
       my %origmembers;
     $r->print(&Apache::lonhtmlcommon::echo_form_input(      $r->print(&Apache::lonhtmlcommon::echo_form_input(
                 ['origin','action','state','member','specificity'],\@regexps));           ['origin','action','state','page','member','specificity','branch',
     my %sectioncount = ();            'defpriv','autorole','autoadd','autodrop'],
     my $numsec = &Apache::loncommon::get_sections($cdom,$cnum,\%sectioncount);           \@regexps));
     my %curr_groups;      my $earlyout = &validate_groupname($groupname,$action,$cdom,$cnum);
     my $numgroups =  &Apache::loncommon::coursegroups(\%curr_groups,$cdom,$cnum);      $r->print('
     my $earlyout;  <table width="100%" cellpadding="0" cellspacing="0" border="0">
     my $exitmsg = '<b>Invalid group name</b><br /><br />The group name entered "'.  
                   $groupname.'" ';  
     my $dupmsg = 'Group names and section names used in a course must be unique.';   
     if ($groupname =~ /\W/) {  
         $earlyout = $exitmsg.'is not a valid name.<br />Group names may only contain letters, numbers or underscores';  
     }  
     if ($numsec) {  
         if (exists($sectioncount{$groupname})) {  
             $earlyout = $exitmsg.'can not be used as it is the name of a '.  
                                  'section in this course.<br />'.$dupmsg;  
         }  
     }  
     if ($numgroups) {  
         if (exists($curr_groups{$groupname})) {  
             $earlyout = $exitmsg.'can not be used as it is the name of an   
                                  existing group in this course.<br />'.$dupmsg;  
         }  
     }  
     if ($earlyout) {  
         $r->print('<table border="0" cellpadding="2" cellspacing="2">  
  <tr>  
   <td>&nbsp;</td>  
   <td>'.$earlyout.'</td>  
  </tr>  
  <tr>  
   <td colspan="2">&nbsp;</td>  
  </tr>  
  <tr>   <tr>
   <td>&nbsp;</td>    <td>&nbsp;</td>
   <td align="left">    <td colspan="3">
    <input type="button" name="previous" value = "Go to previous page"  ');
     onclick="javascript:backPage(document.'.$formname.','."'pick_name'".')"/>      if ($earlyout) {
   </td>          $r->print($earlyout.'</td></tr>');
  </tr>          &display_navbuttons($r,$formname,$$states{$action}[$page-1],
 </table>                             $$navbuttons{'gtps'});
         ');          $r->print('</table>');
         return;          return;
       } 
       my ($specimg,$memimg);
       my @available = ();
       my @unavailable = ();
       &check_tools($functions,$tools,\@available,\@unavailable);
       if ($action eq 'create') {
           &print_current_settings($r,$action,$tabcol,$rowColor1,$rowColor2,
                                   $functions,$startdate,$enddate,$groupname,
                                   $description,$granularity,\@available,
                                   \@unavailable);
           $specimg = 4;
           $memimg = 5;
       } else {
           $specimg = 2;
           $memimg = 3;
           my %membership = &Apache::lonnet::get_group_membership($cdom,$cnum,
                                                                  $groupname);
           foreach my $key (sort(keys(%membership))) {
               if ($key =~ /^\Q$groupname\E:([^:]+):([^:]+)$/) {
                   my $uname = $1;
                   my $udom = $2;
                   my $user = $uname.':'.$udom;
                   $origmembers{$user} = 1; 
               }
           }
     }      }
     my $rowColor1 = "#dddddd";      &privilege_specificity($r,$tabcol,$rowColor1,$rowColor2,$action,
     my $rowColor2 = "#eeeeee";                            $specimg,$tools,$stored,$toolprivs,
                             $fixedprivs,\@available,$formname);
       my $newusers = &pick_new_members($r,$action,$formname,$tabcol,$rowColor1,
                                       $rowColor2,\@available,$idx,$stored,
                                       $memimg,$users,$userdata,$granularity,
                                       \%origmembers);
       if ($newusers || $action eq 'create') {
           &display_navbuttons($r,$formname,$$states{$action}[$page-1],
                               $$navbuttons{'gtps'},$$states{$action}[$page+1],
                               $$navbuttons{'gtns'});
       } else {
           &display_navbuttons($r,$formname,$$states{$action}[$page-1],
                               $$navbuttons{'gtps'});
       }
       $r->print('</table>');
       return;
   }
   
   sub display_navbuttons {
       my ($r,$formname,$prev,$prevtext,$next,$nexttext) = @_;
       $r->print('
       <tr>
        <td colspan="4">&nbsp;</td>
       </tr>
       <tr>
        <td>&nbsp;</td>
        <td colspan="3">');
       if ($prev) {
           $r->print('
         <input type="button" name="previous" value = "'.$prevtext.'"
       onclick="javascript:backPage(document.'.$formname.','."'".$prev."'".')"/>
      &nbsp;&nbsp;&nbsp;');
       }
       if ($next) {
           $r->print('
         <input type="button" name="next" value="'.$nexttext.'"
    onclick="javascript:nextPage(document.'.$formname.','."'".$next."'".')" />');
       }
       $r->print('
        </td>
       </tr>
   ');
   }
   
   sub check_tools {
       my ($functions,$tools,$available,$unavailable) = @_;
       foreach my $item (sort(keys(%{$functions}))) {
           if (grep/^$item$/,@{$tools}) {
               push(@{$available},$item);
           } else {
               push(@{$unavailable},$item);
           }
       }
       return;
   }
   
   sub print_current_settings {
       my ($r,$action,$tabcol,$rowColor1,$rowColor2,$functions,$startdate,$enddate,
              $groupname,$description,$granularity,$available,$unavailable) =@_;
   
       my %lt = &Apache::lonlocal::texthash(
           grna => 'Group Name',
           desc => 'Description',
           grfn => 'Group Functions',
           gran => 'Granularity',
           dfac => 'Default access dates',
           ygrs => 'Your group selections',
           tfwa => 'The following settings will apply to the group:',
           difn => 'Different functionality<br />for different users:',
           stda => 'Start date',
           enda => 'End date:',
       );
     my $showstart = &Apache::lonlocal::locallocaltime($startdate);      my $showstart = &Apache::lonlocal::locallocaltime($startdate);
     my $showend = &Apache::lonlocal::locallocaltime($enddate);      my $showend;
     $r->print('<table border="0" cellpadding="0" cellspacing="20">      if ($enddate == 0) {
           $showend = &mt('No end date set'); 
       } else {
           $showend = &Apache::lonlocal::locallocaltime($enddate);
       }
       $r->print('<table border="0" cellpadding="0" cellspacing="20">');
       if ($action eq 'create') {
           $r->print('
 <tr>  <tr>
  <td><font face="arial,helvetica,sans-serif"><b>New group selections</b></font>   <td><font face="arial,helvetica,sans-serif"><b>'.$lt{'ygrs'}.'</b></font>
 <br />When you create the new group, the following settings will apply:  <br />'.$lt{'tfwa'}.'
  </td>   </td>
 </tr>  </tr>');
 <tr>      }
  <td>');      $r->print('<tr><td>');
     $r->print(&Apache::lonhtmlcommon::start_pick_box());      $r->print(&Apache::lonhtmlcommon::start_pick_box());
     $r->print('      $r->print('
   <tr>
    <td>
 <table cellspacing="1" cellpadding="4">  <table cellspacing="1" cellpadding="4">
  <tr bgcolor="'.$tabcol.'" align="center">   <tr bgcolor="'.$tabcol.'" align="center">
   <td><b>Group Name</b></td>    <td><b>'.$lt{'grna'}.'</b></td>
   <td><b>Description</b></td>    <td><b>'.$lt{'desc'}.'</b></td>
   <td><b>Group Functionality</b></td>    <td><b>'.$lt{'grfn'}.'</b></td>
   <td><b>Default access dates</b></td>    <td><b>'.$lt{'gran'}.'</b></td>
     <td><b>'.$lt{'dfac'}.'</b></td>
  </tr>   </tr>
  <tr bgcolor="'.$rowColor2.'">   <tr bgcolor="'.$rowColor2.'">
   <td valign="top"><small>'.$groupname.'</small></td>    <td valign="top"><small>'.$groupname.'</small></td>
   <td valign="top"><small>'.$description.'</small></td>    <td valign="top"><small>'.$description.'</small></td>
   <td>    <td>
 ');  ');
     my @available = ();      if (@{$available} > 0) {
     my @unavailable = ();  
     foreach my $item (sort(keys(%{$functions}))) {  
         if (grep/^$item$/,@{$tools}) {  
             push(@available,$item);  
         } else {  
             push(@unavailable,$item);  
         }  
     }  
     if (@available > 0) {  
         $r->print('<small><b>Available:</b></small>          $r->print('<small><b>Available:</b></small>
                     <table cellpadding="" cellspacing="1"><tr>');                      <table cellpadding="" cellspacing="1"><tr>');
         my $rowcell = int(@available/2) + @available%2;          my $rowcell = int(@{$available}/2) + @{$available}%2;
         for (my $i=0; $i<@available; $i++) {          for (my $i=0; $i<@{$available}; $i++) {
             if (@available > 3) {              if (@{$available} > 3) {
                 if ($i==$rowcell) {                  if ($i==$rowcell) {
                     $r->print('</tr><tr>');                      $r->print('</tr><tr>');
                 }                  }
             }              }
             $r->print('<td><small>'.$$functions{$available[$i]}.              $r->print('<td><small>'.$$functions{$$available[$i]}.
                                           '</small></td><td>&nbsp;</td>');                                            '</small></td><td>&nbsp;</td>');
         }          }
         if ((@available > 3) && (@available%2)) {          if ((@{$available} > 3) && (@{$available}%2)) {
             $r->print('<td>&nbsp;</td><td>&nbsp;</td>');              $r->print('<td>&nbsp;</td><td>&nbsp;</td>');
         }          }
         $r->print('</tr></table><br />');          $r->print('</tr></table><br />');
     }      }
     if (@unavailable > 0) {      if (@{$unavailable} > 0) {
         $r->print('<small><b>Unavailable:</b></small>          $r->print('<small><b>Unavailable:</b></small>
                     <table cellpadding="0" cellspacing="1"  border="0"><tr>');                      <table cellpadding="0" cellspacing="1"  border="0"><tr>');
         my $rowcell = int(@unavailable/2) + @unavailable%2;          my $rowcell = int(@{$unavailable}/2) + @{$unavailable}%2;
         for (my $j=0; $j<@unavailable; $j++) {          for (my $j=0; $j<@{$unavailable}; $j++) {
             if (@unavailable > 3) {              if (@{$unavailable} > 3) {
                 if ($j==$rowcell) {                  if ($j==$rowcell) {
                     $r->print('</tr><tr>');                      $r->print('</tr><tr>');
                 }                  }
             }              }
             $r->print('<td><small>'.$$functions{$unavailable[$j]}.              $r->print('<td><small>'.$$functions{$$unavailable[$j]}.
                                               '</small></td><td>&nbsp;</td>');                                                '</small></td><td>&nbsp;</td>');
         }          }
         if ((@unavailable > 3) && (@unavailable%2)) {          if ((@{$unavailable} > 3) && (@{$unavailable}%2)) {
             $r->print('<td>&nbsp;</td><td>&nbsp;</td>');              $r->print('<td>&nbsp;</td><td>&nbsp;</td>');
         }          }
         $r->print('</tr></table>');          $r->print('</tr></table>');
     }      }
     $r->print(<<"END");      $r->print(<<"END");
   </td>    </td>
   <td valign="top"><small><b>Start date:</b> $showstart<br />    <td valign="top"><small><b>$lt{'difn'}
       <b>End date:</b> $showend</small>    </b> $granularity</small> 
     <td valign="top"><small><b>$lt{'stda'}</b> $showstart<br />
         <b>$lt{'enda'}</b> $showend</small>
   </td>    </td>
  </tr>   </tr>
 </table>  </table>
   </td>
   </tr>
 END  END
     $r->print(&Apache::lonhtmlcommon::end_pick_box());      $r->print(&Apache::lonhtmlcommon::end_pick_box());
     my %members = ();      $r->print('</td></tr></table><br />');
       return;
   }
   
   sub pick_new_members {
       my ($r,$action,$formname,$tabcol,$rowColor1,$rowColor2,$available,$idx,
           $stored,$img,$users,$userdata,$granularity,$origmembers) = @_;
       my %lt = &Apache::lonlocal::texthash(
             'gpme' => 'Group membership',
             'addm' => 'Add members',
             'setf' => 'Set functionality',
             'func' => 'Functionality',
             'nome' => 'No members to add at this time.',
             'nnew' => 'There are no users to add as new members, as all users'.
                       ' matching the specified type(s), role(s), and/or '.
                       'section(s) are already affiliated with this group.',
             'yoma' =>  'You may need to use the '."'".'modify existing, past or '.
                        'future members'."'".' page if you need to re-enable '.
                        'or activate access for previous or future members.',
       );
       my %members;
       my $totalusers = 0;
       my $newusers = 0;
     foreach my $role (keys(%{$users})) {      foreach my $role (keys(%{$users})) {
         foreach my $user (keys(%{$$users{$role}})) {          foreach my $user (keys(%{$$users{$role}})) {
               $totalusers ++;
               if (ref($origmembers) eq 'HASH') {
                   if (exists($$origmembers{$user})) {
                       next;
                   }
               }    
             unless (defined($members{$user})) {              unless (defined($members{$user})) {
                 @{$members{$user}} = @{$$userdata{$user}};                  @{$members{$user}} = @{$$userdata{$user}};
                   $newusers ++;
             }              }
         }          }
     }      }
     $r->print('</td></tr></table><br />');  
     if (keys(%members) > 0) {      if (keys(%members) > 0) {
         if ($env{'form.granularity'} eq 'Yes') {          if (@{$available} > 0 && $granularity eq 'Yes') {
             $r->print('              $r->print(&check_uncheck_tools($r,$available));
 <script type="text/javascript">          }
 function checkAllTools(formname) {      }
 ');      &topic_bar($r,$tabcol,$img,$lt{'gpme'});
             foreach my $tool (@available) {      if (keys(%members) > 0) {
                 $r->print('  checkAll(formname.user_'.$tool.');'."\n");          $r->print('
             }  
             $r->print('  
 }  
 function uncheckAllTools(formname) {  
 ');  
             foreach my $tool (@available) {  
                 $r->print('  uncheckAll(formname.user_'.$tool.');'."\n");  
             }  
             $r->print('  
 }  
 </script>  
             ');  
        }  
        $r->print(<<"END");  
 <table width="100%" cellpadding="0" cellspacing="0" border="0">  
  <tr bgcolor="$tabcol">  
   <td>&nbsp;</td>  
   <td valign="top" align="left">  
    <nobr><img src="/res/adm/pages/bl_step4.gif" valign="middle">&nbsp;</nobr>  
   </td>  
   <td alin="left">  
    <nobr>  
    <font face="arial,helvetica,sans-serif">  
     <b>Select group members</b>  
    </font></nobr>  
   </td>  
   <td width="100%">&nbsp;</td>  
  </tr>  
  <tr>  
   <td colspan="4">&nbsp;</td>  
  </tr>  
  <tr>   <tr>
   <td>&nbsp;</td>    <td>&nbsp;</td>
   <td colspan="2">    <td colspan="3">
     <table>      <table>
      <tr>       <tr>');
       <td>          &check_uncheck_buttons($r,$formname,'member',$lt{'addm'});
    <nobr>          if (@{$available} > 0 && $granularity eq 'Yes') {
     <fieldset><legend><b>Add members</b></legend>              $r->print('<td><nobr>
      <input type="button" value="check all"        <fieldset><legend><b>'.$lt{'setf'}.'</b></legend>
        onclick="javascript:checkAll(document.$formname.member)" />        <input type="button" value="check all"
       &nbsp;&nbsp;          onclick="javascript:checkAllTools(document.'.$formname.')" />
      <input type="button" value="uncheck all"           &nbsp;&nbsp;
       onclick="javascript:uncheckAll(document.$formname.member)" />        <input type="button" value="uncheck all"
     </fieldset></nobr></td>  
 END  
         if (@available > 0 && $env{'form.granularity'} eq 'Yes') {  
             $r->print('<td><nobr><fieldset><legend><b>   
                                       Set functionality</b></legend>  
      <input type="button" value="check all"   
        onclick="javascript:checkAllTools(document.'.$formname.')" />  
        &nbsp;&nbsp;  
      <input type="button" value="uncheck all"   
         onclick="javascript:uncheckAllTools(document.'.$formname.')" />          onclick="javascript:uncheckAllTools(document.'.$formname.')" />
     </fieldset></nobr></td>');       </fieldset></nobr></td>');
         }          }
         $r->print('</tr></table>          $r->print('</tr></table>
   </td>    </td>
   <td width="100%">&nbsp;</td>  
  </tr>   </tr>
  <tr>   <tr>
   <td colspan="4">&nbsp;</td>    <td colspan="4">&nbsp;</td>
Line 1038  END Line 1424  END
   <td colspan="3">    <td colspan="3">
         ');          ');
         $r->print(&Apache::lonhtmlcommon::start_pick_box());          $r->print(&Apache::lonhtmlcommon::start_pick_box());
         $r->print(<<"END");          $r->print('
    <table border="0" cellpadding="4" cellspacing="1">     <table border="0" cellpadding="4" cellspacing="1">
     <tr bgcolor="$tabcol" align="center">      <tr bgcolor="'.$tabcol.'" align="center">
      <td><b>Add?</b></td>       <td><b>'.&mt('Add?').'</b></td>
      <td><b><a href="javascript:changeSort('fullname')">Name</a></b></td>       <td><b><a href="javascript:changeSort('."'fullname'".')">'.&mt('Name').'</a></b></td>
      <td><b><a href="javascript:changeSort('username')">Username</a></b>       <td><b><a href="javascript:changeSort('."'username'".')">'.&mt('Username').'</a></b>
      </td>       </td>
      <td><b><a href="javascript:changeSort('domain')">Domain</a></b></td>       <td><b><a href="javascript:changeSort('."'domain'".')">'.&mt('Domain').'</a></b></td>
      <td><b><a href="javascript:changeSort('id')">ID</a></b></td>       <td><b><a href="javascript:changeSort('."'id'".')">ID</a></b></td>
 END  ');
         if (@available > 0) {          if (@{$available} > 0) {
             $r->print('<td><b>Functionality</b></td>');              $r->print('<td><b>'.$lt{'func'}.'</b></td>');
         }          }
         $r->print('</tr>');          $r->print('</tr>');
           if (@{$available} > 0) {
               if ($granularity eq 'Yes') {
                   $r->print('<tr bgcolor="#cccccc">
    <td colspan="5">&nbsp;</td>
    <td align="center"><small><nobr><b>All:</b>&nbsp;');
                   foreach my $tool (@{$available}) {
                       $r->print('<input type="checkbox" name="togglefunc" '.
      'onclick="javascript:toggleTools(document.'.$formname.'.user_'.$tool.',this);">'.
      '<b>'.$tool.'</b>&nbsp;&nbsp;&nbsp;');
                   }
                   $r->print('</nobr></small></td></tr>');
               }
           }
         my %Sortby = ();          my %Sortby = ();
         foreach my $user (sort(keys(%members))) {          foreach my $user (sort(keys(%members))) {
             if ($env{'form.sortby'} eq 'fullname') {              if ($env{'form.sortby'} eq 'fullname') {
Line 1083  END Line 1482  END
    <input type="checkbox" name="member" value="'.$user.'" /></td><td><small>'.     <input type="checkbox" name="member" value="'.$user.'" /></td><td><small>'.
     $fullname.'</small></td><td><small>'.$uname.'</small></td><td><small>'.      $fullname.'</small></td><td><small>'.$uname.'</small></td><td><small>'.
     $udom.'</small></td><td><small>'.$id.'</small></td>');      $udom.'</small></td><td><small>'.$id.'</small></td>');
                 if (@available > 0) {                  if (@{$available} > 0) {
                     $r->print('<td align="center"><small>');                       $r->print('<td align="center"><nobr><small>'.
                     foreach my $tool (@available) {                                '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;');
                         if ($env{'form.granularity'} eq 'Yes') {                      foreach my $tool (@{$available}) {
                           if ($granularity eq 'Yes') {
                             $r->print('<input type="checkbox" name="user_'.                              $r->print('<input type="checkbox" name="user_'.
                           $tool.'" value="'.$user.'" />'.$tool.'&nbsp;&nbsp;&nbsp;');                            $tool.'" value="'.$user.'" />'.$tool.'&nbsp;&nbsp;&nbsp;');
                         } else {                          } else {
Line 1094  END Line 1494  END
                           $tool.'" value="'.$user.'" />'.$tool.'&nbsp;&nbsp;&nbsp;');                            $tool.'" value="'.$user.'" />'.$tool.'&nbsp;&nbsp;&nbsp;');
                         }                          }
                     }                      }
                     $r->print('</small></td>');                      $r->print('</small></nobr></td>');
                 }                  }
                 $r->print('</tr>'."\n");                  $r->print('</tr>'."\n");
                 $rowNum ++;                  $rowNum ++;
Line 1102  END Line 1502  END
         }          }
         $r->print(&Apache::lonhtmlcommon::end_pick_box());          $r->print(&Apache::lonhtmlcommon::end_pick_box());
         $r->print('          $r->print('
        </td>
       </tr>');
       } else {
           $r->print('
       <tr>
        <td>&nbsp;</td>
        <td colspan="3">
   ');
           if ($totalusers > 0) {
               $r->print($lt{'nnew'}.'<br /><br />'.$lt{'yoma'});
           } else { 
               $r->print($lt{'nome'});
           }
           $r->print('
        </td>
       </tr>');
       }
       return $newusers;
   }
   
   sub privilege_specificity {
       my ($r,$tabcol,$rowColor1,$rowColor2,$action,$img,$tools,$stored,
           $toolprivs,$fixedprivs,$available,$formname) = @_;
       my %lt = &Apache::lonlocal::texthash (
         'uprv' => 'User privileges',
         'frty' => 'For each type of functionality you have chosen to include, '.
                   'there is a set of standard privileges which apply to all '.
                   'of those for whom the functionality is enabled.',
         'thar' => 'There are also additional privileges which can be set for '.
                   'some, or all, members. Please choose one of the following:',
         'fort' => 'For the types of functionality you have chosen to include '.
                   'there are no additional privileges which can be set for some '.
                   'or all members.',
         'eaty' => 'Each of the types of functionality includes standard '.
                   'privileges which apply to members with access to that '.
                   'functionality, and may also include additional privileges '.
                   'which can be set for specific members.',
         'cutg' => 'Currently the group is configured ',
         'sdif' => 'so different group members can receive different privileges.',
         'sall' => 'so all group members will receive the same privileges.',
         'algm' => 'All group members will receive the same privileges.',
         'smgp' => 'Some group members will receive different privileges from '.
                   'others.',
         'thwi' => 'These will be the privileges all group members receive, '. 
                   'if you selected the first option above.',
         'thes' => 'These will be the privileges given to members assigned '.   
                   'in the future, including via automatic group assignment '.
                   'for specific sections/roles ',
         'asyo' => 'As you have chosen not to include any functionality in the '.
                   'group, no default user privileges settings need to be set.',
         'plin' => 'Please indicate which <b>optional</b> privileges members '.
                   'will receive by default.',
         'oppr' => 'Optional privileges',
         'defp' => 'The default privileges new members will receive are:', 
       );
       my $totaloptionalprivs = 0;
       foreach my $tool (@{$tools}) {
           foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {
               if (!exists($$fixedprivs{$tool}{$priv})) {
                   $totaloptionalprivs ++;
               }
           }
       }
       &topic_bar($r,$tabcol,$img,$lt{'uprv'});
       $r->print('
    <tr>
     <td>&nbsp;</td>
     <td colspan="3">
     ');
       if ((($action eq 'create') && (@{$available} > 0)) || 
           (($action eq 'modify') && ($formname eq 'change_settings'))) {  
           my %specific = (
                         'No'  => 'checked="checked"',
                         'Yes' => '',
                     );
           if ($action eq 'create') {
               $r->print($lt{'frty'}.'<br />');
               if ($totaloptionalprivs) {
                   $r->print($lt{'thar'});
               } else {
                   $r->print($lt{'fort'});
               }
           } else {
               $r->print($lt{'eaty'}.'&nbsp;'.$lt{cutg});
               if ($$stored{'specificity'} eq 'Yes') {
                   $r->print($lt{'sdif'});
                   $specific{'Yes'} = $specific{'No'};
                   $specific{'No'} = '';
               } else {
                   $r->print($lt{'sall'});
               }
           }
           if ($totaloptionalprivs) {
               $r->print('
   <br /><br /><nobr><input type="radio" name="specificity" value="No" '.$specific{'No'}.' />&nbsp;'.$lt{'algm'}.'</nobr><br/>
   <nobr><input type="radio" name="specificity" value="Yes" '.$specific{'Yes'}.' />&nbsp;'.$lt{'smgp'}.'</nobr>
   </td>    </td>
  </tr>   </tr>
  <tr>   <tr>
   <td colspan="4">&nbsp;</td>    <td colspan="4">&nbsp;</td>
  </tr>');   </tr>');
         if (@available > 0) {          } else {
               $r->print('<input type="hidden" name="specificity" value="No" />');
           }
           if ($totaloptionalprivs) {
             $r->print('              $r->print('
  <tr bgcolor="'.$tabcol.'">   <tr>
   <td>&nbsp;</td>    <td>&nbsp;</td>
   <td valign="middle" align="left">    <td colspan="3">'.$lt{'plin'});
    <nobr><img src="/res/adm/pages/bl_step5.gif" valign="middle">&nbsp;</nobr>              if ($action eq 'create') {
   </td>                  $r->print(' '.$lt{'thwi'});
   <td align="left"><nobr>              }
    <font face="arial,helvetica,sans-serif">              $r->print('<br />'.$lt{'thes'});
     <b>User privileges</b>              if ($action eq 'create') {
    </font></nobr>                  $r->print('('.&mt('if enabled on the next page').').');
               } else {
                   $r->print('('.&mt('if enabled below').').');
               }
               $r->print('<br /><br />
   </td>    </td>
   <td width="100%">&nbsp;</td>  
  </tr>   </tr>
  <tr>   <tr>
   <td>&nbsp;</td>    <td>&nbsp;</td>
     <td colspan="2"><table><tr>');
           &check_uncheck_buttons($r,$formname,'defpriv',$lt{'oppr'});
           $r->print('
       </tr>
      </table>
     </td>
     <td width="100%">&nbsp;</td>
    </tr><tr>
     <td>&nbsp;</td>
   <td colspan="3">    <td colspan="3">
    <br />     <br />
    For each type of functionality you have chosen to include, there is a   
 set of standard privileges which apply to all of those for whom the functionality is enabled.<br />There are also additional privileges which can be set for some, or all, members. Please choose one of the following:<br />  
 <br /><input type="radio" name="specificity" value="No" checked="checked" />&nbsp;All group members will receive the same privileges.<br/><input type="radio" name="specificity" value="Yes" />&nbsp;Some group members will receive different privileges from others.  
   </td>  
  </tr>  
  <tr>  
   <td colspan="4">&nbsp;</td>  
  </tr>  
 ');  ');
           } else {
               $r->print('<tr><td>&nbsp;</td><td colspan="3">'.$lt{'algm'}.'<br /><br />');
         }          }
         $r->print('              &default_privileges($r,$action,$tabcol,$rowColor1,$rowColor2,
  <tr>                              $tools,$toolprivs,$fixedprivs,$available);
   <td>&nbsp;</td>  
   <td colspan="3">  
    <input type="button" name="previous" value = "Go to previous page"   
     onclick="javascript:backPage(document.'.$formname.','."'pick_name'".')"/>  
    &nbsp;&nbsp;&nbsp;  
    <input type="button" name="next" value="Go to next page"   
  onclick="javascript:nextPage(document.'.$formname.','."'pick_privs'".')" />  
   </td>  
  </tr>  
         ');  
     } else {      } else {
         $r->print('No members to add');          if ($action eq 'create') {
               $r->print($lt{'asyo'});
           } elsif ($action eq 'modify' && $formname eq 'pick_members') {
               my @defprivs;
               if (ref($$stored{'defpriv'}) eq 'ARRAY') {
                   @defprivs = @{$$stored{'defpriv'}};
               }
               $r->print($lt{'eaty'}.'&nbsp;'.$lt{cutg});
               if ($$stored{'specificity'} eq 'Yes') {
                   $r->print($lt{'sdif'});
               } else {
                   $r->print($lt{'sall'});
               }
               $r->print(' '.$lt{'defp'}.'<br /><br />');
               &display_defprivs($r,$tabcol,$rowColor1,$rowColor2,$tools,
                                 $toolprivs,\@defprivs);
           }
     }      }
     $r->print('      $r->print('
    </table>  
   </td>    </td>
  </tr>   </tr>
 </table>');  ');
     return;      return;
 }  }
   
 sub third_creation_form {  sub default_privileges {
     my ($r,$cdom,$cnum,$tabcol,$formname,$startdate,$enddate,$tools,$functions,      my ($r,$action,$tabcol,$rowColor1,$rowColor2,$tools,$toolprivs,
                $toolprivs,$fixedprivs,$userdata,$members,$usertools,$idx) = @_;          $fixedprivs,$available) = @_;
     my @regexps = ('userpriv_','allpriv_');      my %lt = &Apache::lonlocal::texthash(
     $r->print(&Apache::lonhtmlcommon::echo_form_input(                                  'addp' => 'Additional privileges',
                              ['origin','action','state'],\@regexps));                                  'fixp' => 'Fixed privileges',
     my %possibles = ();                                  'oppr' => 'Optional privileges',
     my %showboxes = ();                                  'func' => 'Function',
     my $totalboxes = 0;      );
     my $rowColor1 = "#dddddd";      $r->print(&Apache::lonhtmlcommon::start_pick_box());
     my $rowColor2 = "#eeeeee";      $r->print('<tr>
     my $numtools = 1 + @{$tools};                  <td bgcolor="'.$tabcol.'" valign="top">
                    <table cellspacing="0" cellpadding="1">
                     <tr>
                      <td valign="top"><b>'.$lt{'func'}.'</b></td>
                     </tr>
                     <tr>
                      <td valign="top"><b>'.$lt{'fixp'}.'</b></td>
                     </tr>
                     <tr>
                      <td valign="top"><b>'.$lt{'oppr'}.'</b></td>
                     </tr>
                    </table>
                   </td>
       ');
     foreach my $tool (@{$tools}) {      foreach my $tool (@{$tools}) {
         @{$showboxes{$tool}} = ();          $r->print('<td align="center" valign="top">
         foreach my $user (@{$members}) {                      <table cellspacing="0" cellpadding="1">
             if (exists($$usertools{$user}{$tool})) {                       <tr bgcolor="#cccccc">
                 foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {                        <td colspan="2" align="center"><b>'.$tool.'</b></td>
                     unless (exists($$fixedprivs{$tool}{$priv})) {                       </tr>
                         push(@{$possibles{$user}},$priv);          ');
                         unless(grep(/^$priv$/,@{$showboxes{$tool}})) {          my $privcount = 0;
                             push(@{$showboxes{$tool}},$priv);          my $fixed = '';
                             $totalboxes ++;          my $dynamic = '';
                         }          foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {
               if (exists($$fixedprivs{$tool}{$priv})) {
                   $fixed .= '<input type="hidden" name="defpriv" value="'.$priv.'" />'.$$toolprivs{$tool}{$priv}.'&nbsp;';
                   if ($action eq 'modify') {
                       if (grep/^$tool$/,@{$available}) {
                           $fixed .= '<small>'.&mt('(on)').'<small>&nbsp;';
                       } else {
                           $fixed .= '<small>'.&mt('(off)').'<small>&nbsp;';
                     }                      }
                 }                  }
               } else {
                   $privcount ++;
                   if ($privcount == 3) {
                       $dynamic .= '</tr>
                                    <tr bgcolor="'.$rowColor1.'">'."\n";
                   }
                   $dynamic .= '<td><input type="checkbox" name="defpriv" value="'.$priv.'" />'.$$toolprivs{$tool}{$priv}.'</td>'."\n";
             }              }
         }          }
     }          if ($dynamic eq '') {
     if ($totalboxes > 0) {              $dynamic = '<td>None</td>'."\n";
         $r->print('  
 <script type="text/javascript">  
 function checkAllTools(formname) {  
 ');  
         foreach my $tool (sort(keys(%showboxes))) {  
             foreach my $priv (@{$showboxes{$tool}}) {  
                 $r->print('  checkAll(formname.userpriv_'.$priv.');'."\n");  
             }  
         }          }
         $r->print('          if ($privcount < 3) {
               $dynamic .= '</tr>
                            <tr bgcolor="'.$rowColor1.'">
                             <td colspan="2">&nbsp;</td>'."\n";
           } elsif ($privcount%2) {
               $dynamic = '<td>&nbsp;</td>'."\n";
           }
           $r->print('<tr bgcolor="'.$rowColor2.'">
                       <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::end_pick_box());
       $r->print('<br />');
       return;
 }  }
 function uncheckAllTools(formname) {  
 ');  sub display_defprivs {
         foreach my $tool (sort(keys(%showboxes))) {      my ($r,$tabcol,$rowColor1,$rowColor2,$tools,$toolprivs,$defprivs) = @_;
             foreach my $priv (@{$showboxes{$tool}}) {      my %lt = &Apache::lonlocal::texthash(
                 $r->print('  uncheckAll(formname.userpriv_'.$priv.');'."\n");                                  'priv' => 'Privileges',
                                   'func' => 'Function',
       );
       $r->print(&Apache::lonhtmlcommon::start_pick_box());
       $r->print('<tr>');
       my $numrows = 0;
       my %currprivs;
       foreach my $tool (@{$tools}) {
           @{$currprivs{$tool}} = ();
           foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {
               if (ref($defprivs) eq 'ARRAY') {
                   if (grep/^\Q$priv\E$/,@{$defprivs}) {
                       push(@{$currprivs{$tool}},$priv);
                   }
             }              }
         }          }
         $r->print('          my $rowcount = int(@{$currprivs{$tool}}/3);
           if (@{$currprivs{$tool}}%3 > 0) {
               $rowcount ++;
           }
           if ($rowcount > $numrows) {
               $numrows = $rowcount;
           }
       }
       my @rowCols = ($rowColor1,$rowColor2);
       foreach my $tool (@{$tools}) {
           $r->print('<td align="center" valign="top">
                       <table cellspacing="0" cellpadding="5">
                        <tr bgcolor="#cccccc">
                         <td colspan="3" align="center"><b>'.$tool.'</b></td>
                        </tr>
           ');
           my $rownum = 1;
           my $privcount = 0;
           $r->print('<tr bgcolor="'.$rowColor1.'">');
           foreach my $priv (@{$currprivs{$tool}}) {
               $privcount ++;
               if ($privcount%4 == 0) {
                   $rownum ++;
                   my $bgcol = $rownum%2; 
                   $r->print('</tr>
                                <tr bgcolor="'.$rowCols[$bgcol].'">'."\n");
               }
               $r->print('<td>'.$$toolprivs{$tool}{$priv}.'</td>'."\n");
           }
           if ($privcount%3 > 0) {
               my $emptycells = 3-($privcount%3);
               while($emptycells > 0) {
                   $r->print('<td>&nbsp;</td>'."\n");
                   $emptycells --;
               }
           }
           while ($rownum < $numrows) {
               $rownum ++;
               my $bgcol = $rownum%2;
               $r->print('<tr bgcolor="'.$rowCols[$bgcol].'"><td colspan="3">&nbsp;</td></tr>');
           }
           $r->print('</table>'."\n".'</td>');
       }
       $r->print('</tr>'."\n");
       $r->print(&Apache::lonhtmlcommon::end_pick_box());
       $r->print('<br />');
       return;
 }  }
 </script>  
        ');  
    }  sub change_members_form {
    $r->print(<<"END");      my ($r,$cdom,$cnum,$tabcol,$action,$formname,$page,$groupname,$description,
           $startdate,$enddate,$tools,$fixedprivs,$functions,$users,$userdata,
           $granularity,$specificity,$idx,$states,$navbuttons,$rowColor1,
           $rowColor2) = @_;
       my %lt = &Apache::lonlocal::texthash(
                                            grse => 'Group settings',
                                            mogm => 'Modify group membership',
                                           );
       my @regexps = ('user_','userpriv_');
       $r->print(&Apache::lonhtmlcommon::echo_form_input(
                            ['origin','action','state','page','expire','delete',
                             'changefunc','changepriv'],\@regexps));
       my $rowimg = 1;
       my @available = ();
       my @unavailable = ();
       &check_tools($functions,$tools,\@available,\@unavailable);
       my $nexttext = $$navbuttons{'gtns'};
       my $prevtext = $$navbuttons{'gtpp'};
       $r->print('
 <br />  <br />
 <table width="100%" cellpadding="0" cellspacing="0" border="0">  <table width="100%" cellpadding="0" cellspacing="0" border="0">
  <tr bgcolor="$tabcol">  ');
       &topic_bar($r,$tabcol,1,$lt{'grse'});
       $r->print('
    <tr>
   <td>&nbsp;</td>    <td>&nbsp;</td>
   <td valign="middle" align="left">    <td colspan="3">
    <nobr><img src="/res/adm/pages/bl_step6.gif" valign="middle">&nbsp;</nobr>  ');
       &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,
                           $rowColor2,$groupname,\@available,\@unavailable,
                           $fixedprivs,$granularity,$specificity);
       $r->print('</td>');
       &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext,
                           $$states{$action}[$page+1],$nexttext);
       $r->print('</table>');
       return;
   }
   
   sub current_membership {
       my ($r,$cdom,$cnum,$formname,$tabcol,$rowColor1,$rowColor2,$groupname,
           $available,$unavailable,$fixedprivs,$granularity,$specificity) = @_;
       my %membership = &Apache::lonnet::get_group_membership($cdom,$cnum,
                                                                      $groupname);
       my %lt = &Apache::lonlocal::texthash(
                                             'expi' => 'Expire',
                                             'reen' => 'Re-enable',
                                             'acti' => 'Activate',
                                             'dele' => 'Delete',
                                             'curf' => 'Current Functionality',
                                             'chfn' => 'Change Functions',
                                             'chpr' => 'Change Privileges' 
                                           );
       if (keys(%membership) > 0) {
           my %current = ();
           my %allnames = ();
           my $hastools = 0;
           my $addtools = 0;
           my $num_reenable = 0;
           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>
       <tr>');
               if ($num_expire) {
                   &check_uncheck_buttons($r,$formname,'expire',$lt{'expi'});
               }
               if ($num_reenable) {
                   &check_uncheck_buttons($r,$formname,'reenable',$lt{'reen'});
               }
               if ($num_activate) {
                   &check_uncheck_buttons($r,$formname,'activate',$lt{'acti'});
               }
               &check_uncheck_buttons($r,$formname,'delete',$lt{'dele'});
               if (@{$available} > 0) {
                   if ($granularity eq 'Yes') {
                       &check_uncheck_buttons($r,$formname,'changefunc',$lt{'chfn'});
                   }
                   if ($specificity eq 'Yes') {
                       &check_uncheck_buttons($r,$formname,'changepriv',$lt{'chpr'});
                   }
                   if ($granularity eq 'Yes') {
                       $r->print(&check_uncheck_tools($r,$available));
                       $r->print('
        <td>
         <nobr>
          <fieldset><legend><b>'.$lt{'curf'}.'</b></legend>
          <input type="button" value="check all"
          onclick="javascript:checkAllTools(document.'.$formname.')" />
          &nbsp;&nbsp;
          <input type="button" value="uncheck all"
           onclick="javascript:uncheckAllTools(document.'.$formname.')" />
         </fieldset>
        </nobr>
       </td>
   ');
                   }
               }
               $r->print(<<"END");
      </tr>
     </table>
   </td>    </td>
   <th align="left"><nobr>  
     Group member privileges  
    </nobr>  
   </th>  
   <td width="100%">&nbsp;</td>    <td width="100%">&nbsp;</td>
  </tr>   </tr>
  <tr>   <tr>
Line 1231  function uncheckAllTools(formname) { Line 2014  function uncheckAllTools(formname) {
   <td>&nbsp;</td>    <td>&nbsp;</td>
   <td colspan="3">    <td colspan="3">
 END  END
     if ($env{'form.specificity'} eq 'Yes') {              $r->print(&Apache::lonhtmlcommon::start_pick_box());
         $r->print('              $r->print(<<"END");
    <table border="0" cellspacing="2" cellpadding="2" border="0">     <table border="0" cellpadding="4" cellspacing="1">
     <tr>      <tr bgcolor="$tabcol" align="center">
      <td valign="top">       <td><b>Action?</b></td>
        <td><b><a href="javascript:changeSort('fullname')">Name</a></b></td>
        <td><b><a href="javascript:changeSort('username')">Username</a></b>
        </td>
        <td><b><a href="javascript:changeSort('domain')">Domain</a></b></td>
        <td><b><a href="javascript:changeSort('id')">ID</a></b></td>
        <td><b><a href="javascript:changeSort('start')">Start Date</a></b></td>
        <td><b><a href="javascript:changeSort('end')">End Date</a></b></td>
   END
               if ($hastools) {
                   $r->print('<td><b>'.$lt{'curf'}.'</b></td>');
               }
               if ($addtools) {
                   $r->print('<td><b>Additional Functionality</b></td>');
               }
               $r->print('</tr>');
               my %Sortby = ();
               foreach my $user (sort(keys(%current))) {
                   if ($env{'form.sortby'} eq 'fullname') {
                       push(@{$Sortby{$current{$user}{fullname}}},$user);
                   } elsif ($env{'form.sortby'} eq 'username') {
                       push(@{$Sortby{$current{$user}{uname}}},$user);
                   } elsif ($env{'form.sortby'} eq 'domain') {
                       push(@{$Sortby{$current{$user}{udom}}},$user);
                   } elsif ($env{'form.sortby'} eq 'id') {
                       push(@{$Sortby{$current{$user}{id}}},$user);
                   } else {
                       push(@{$Sortby{$current{$user}{fullname}}},$user);
                   }
               }
               my $rowNum = 0;
               my $rowColor;
               foreach my $key (sort(keys(%Sortby))) {
                   foreach my $user (@{$Sortby{$key}}) {
                       if ($rowNum %2 == 1) {
                           $rowColor = $rowColor1;
                       } else {
                           $rowColor = $rowColor2;
                       }
                       my $id = $current{$user}{id};
                       my $fullname = $current{$user}{fullname};
                       my $udom = $current{$user}{udom};
                       my $uname = $current{$user}{uname};
                       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>'. 
      '<input type="checkbox" name="reenable" value="'.$user.'" />'.
      $lt{'reen'}.'</nobr><br />');
                       } elsif ($current{$user}{changestate} eq 'expire') {
                           $r->print('<nobr>'.
      '<input type="checkbox" name="expire" value="'.$user.'" />'.
      $lt{'expi'}.'</nobr><br />');
                       } elsif ($current{$user}{changestate} eq 'activate') {
                           $r->print('<nobr>'.
      '<input type="checkbox" name="activate" value="'.$user.'" />'.
      $lt{'acti'}.'</nobr><br />');
                       }
                       $r->print('<nobr>'.
      '<input type="checkbox" name="delete" value="'.$user.'" />'.
      $lt{'dele'}.'</nobr>');
                       if ($granularity eq 'Yes') {
                           $r->print('<br /><nobr>'.
      '<input type="checkbox" name="changefunc" value="'.$user.'" />'.$lt{'chfn'}.
      '</nobr>');
                       }
                       if ($specificity eq 'Yes') {
                           $r->print('<br /><nobr>'.
      '<input type="checkbox" name="changepriv" value="'.$user.'" />'.$lt{'chpr'}.
      '</nobr>');
                       }
                       $r->print('
      </td>
      <td><small>'.
       $fullname.'</small></td><td><small>'.$uname.'</small></td><td><small>'.
       $udom.'</small></td><td><small>'.$id.'</small></td><td><small>'.$start.
       '</small></td><td><small>'.$end.'</small></td>');
                       if ($hastools) {
                           $r->print('<td align="left"><small><nobr>');
                           foreach my $tool (@{$current{$user}{currtools}}) {
                               if ($granularity eq 'Yes') {
                                   $r->print('<input type="checkbox" 
                                          checked="checked"  
                                          name="user_'.$tool.'" value="'.
                                          $user.'" />');
                                } else {
                                  $r->print('<input type="hidden"
                                          checked="checked"
                                          name="user_'.$tool.'" value="'.
                                          $user.'" />');
                                }
                                $r->print($tool.'&nbsp;&nbsp;&nbsp;');
                           }
                           $r->print('</nobr></small></td>');
                       }
                       if ($addtools) {
                           $r->print('<td align="left"><small>');
                           if ($granularity eq 'Yes') {
                               foreach my $tool (@{$current{$user}{newtools}}) {
                                   $r->print('<nobr><input type="checkbox"  
                                             name="user_'.$tool.'" value="'.
                                             $user.'" />'.$tool.
                                                     '</nobr>&nbsp;&nbsp;&nbsp;');
                               }
                           } else {
                               foreach my $tool (@{$current{$user}{newtools}}) {
                                   $r->print('<nobr><input type="hidden" 
                                             name="user_'. $tool.'" value="'.
                                             $user.'" />'.$tool.
                                             '</nobr>&nbsp;&nbsp;&nbsp;');
                               }
                           }
                           $r->print('</small></td>');
                       }
                       $r->print('</tr>'."\n");
                       $rowNum ++;
                   }
               }
               $r->print(&Apache::lonhtmlcommon::end_pick_box());
               $r->print('
     </td>
    </tr>');
           }
       }
       return;
   }
   
   sub check_uncheck_buttons {
       my ($r,$formname,$field,$title,$colspan) = @_;
       $r->print('
        <td '.$colspan.'>
         <nobr>
          <fieldset>
          <legend><b>'.$title.'</b></legend>
          <input type="button" value="check all"
          onclick="javascript:checkAll(document.'.$formname.'.'.$field.')" />
          &nbsp;&nbsp;
          <input type="button" value="uncheck all"
          onclick="javascript:uncheckAll(document.'.$formname.'.'.$field.')" />
          </fieldset>
         </nobr>
        </td>
 ');  ');
         $r->print(&Apache::lonhtmlcommon::start_pick_box());  }
         $r->print(<<"END");  
    <tr bgcolor="$tabcol">  
     <th><b>Fullname</th>  sub change_privs_form {
     <th><b>Username</th>      my ($r,$cdom,$cnum,$tabcol,$action,$formname,$page,$startdate,$enddate,
     <th>Domain</th>         $tools,$functions,$toolprivs,$fixedprivs,$userdata,$usertools,
     <th colspan="$numtools">Additional Privileges</th>         $memchg,$idx,$states,$stored,$sectioncount,$navbuttons,$rowColor1,
          $rowColor2) = @_;
       my @regexps = ('userpriv_');
       my $nexttext;
                                                                                         
       $r->print(&Apache::lonhtmlcommon::echo_form_input(
            ['origin','action','state','page'],\@regexps));
       $nexttext = $$navbuttons{'adme'};
                                                                                         
       $r->print('<br /><table width="100%" cellpadding="0" cellspacing="0" border="0">');
       
       &topic_bar($r,$tabcol,3,&mt('Group member privileges'));
                                                                                         
       &member_privileges_form($r,$tabcol,$action,$formname,$tools,$toolprivs,
                               $fixedprivs,$userdata,$usertools,$idx,$memchg,
                               $states,$stored,$rowColor1,$rowColor2);
                                                                                         
       $r->print('</td></tr><tr><td colspan="4">&nbsp;</td></tr>');
       my $prevtext = $$navbuttons{'gtps'};
       &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext,
                           $$states{$action}[$page+1],$nexttext);
       $r->print('</table>');
       return;
   }
   
   sub add_members_form {
       my ($r,$tabcol,$action,$formname,$page,$startdate,$enddate,$groupname,
           $description,$granularity,$sectioncount,$tools,$functions,$stored,
           $states,$navbuttons,$rowColor1,$rowColor2) = @_; 
       $r->print(' <br />
   <table width="100%" cellpadding="0" cellspacing="0" border="0">
    <tr>
     <td>&nbsp;</td>
     <td colspan="3">
   ');
       my @available = ();
       my @unavailable = ();
       &check_tools($functions,$tools,\@available,\@unavailable);
       &print_current_settings($r,$action,$tabcol,$rowColor1,$rowColor2,
                               $functions,$startdate,$enddate,$groupname,
                               $description,$granularity,\@available,\@unavailable);
       $r->print('
      </td>
   </tr>    </tr>
 END    <tr>
      <td colspan="4">&nbsp;</td>
     </tr>');
   
       &membership_options($r,$action,$formname,$tabcol,$sectioncount,1);
       my $nexttext = $$navbuttons{'gtns'};
       my $prevtext = $$navbuttons{'gtpp'};
       &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext,
                           $$states{$action}[$page+1],$nexttext);
       $r->print('
    </table>');
       return;
   }
   
   sub choose_privs_form {
       my ($r,$cdom,$cnum,$tabcol,$action,$formname,$page,$startdate,$enddate,
          $tools,$functions,$toolprivs,$fixedprivs,$userdata,$usertools,$idx,
          $states,$stored,$sectioncount,$navbuttons,$rowColor1,$rowColor2) = @_;
   
       my @regexps = ('userpriv_');
       my $nexttext;
       
       if ($action eq 'create') {
           push(@regexps,'sec_');
           $r->print(&Apache::lonhtmlcommon::echo_form_input(
            ['origin','action','state','page','autoadd','autodrop'],
            \@regexps));
           $nexttext = $$navbuttons{'crgr'};
       } else {
           $r->print(&Apache::lonhtmlcommon::echo_form_input(
            ['origin','action','state','page'],\@regexps));
           $nexttext = $$navbuttons{'adme'};
     }      }
     if ($env{'form.specificity'} eq 'Yes') {  
         &member_privs_entries($r,$tabcol,$rowColor1,$rowColor2,$members,$tools,      $r->print('<br /><table width="100%" cellpadding="0" cellspacing="0" border="0">');
                              $usertools,$toolprivs,$fixedprivs,$userdata,$idx);      &topic_bar($r,$tabcol,6,&mt('Group member privileges'));
   
       &member_privileges_form($r,$tabcol,$action,$formname,$tools,$toolprivs,
                               $fixedprivs,$userdata,$usertools,$idx,undef,
                               $states,$stored,$rowColor1,$rowColor2);
   
       $r->print('</td></tr><tr><td colspan="4">&nbsp;</td></tr>');
       if ($action eq 'create') {
           if (keys(%{$sectioncount}) > 0) {
               my $img1 = 7;
               my $img2 = 8;
               &mapping_options($r,$action,$formname,$page,$tabcol,$sectioncount,
                                $states,$stored,$navbuttons,$img1,$img2,
                                $rowColor1,$rowColor2);
           }
     }      }
     if ($env{'form.specificity'} eq 'Yes') {      my $prevtext = $$navbuttons{'gtps'};
         $r->print('</td>');      &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext,
         $r->print(&Apache::lonhtmlcommon::end_pick_box());                          $$states{$action}[$page+1],$nexttext);
         $r->print('<td>&nbsp;</td>      $r->print('</table>');
                <td>&nbsp;</td><td valign="top">');      return;
         my @toolboxes = sort(keys(%showboxes));  }
         foreach my $tool (@{$tools}) {  
             if (@{$showboxes{$tool}} > 0) {   sub build_boxes {
                 $r->print('<table class="thinborder"><tr bgcolor="'.$tabcol.      my ($r,$tools,$usertools,$fixedprivs,$toolprivs,$showtools,
                       '"><th>'.$tool.'</th></tr>');          $showboxes,$prefix,$specificity) = @_;
                 foreach my $priv (@{$showboxes{$tool}}) {      my $totalboxes = 0;
                     $r->print(qq|      if (@{$tools} > 0) {
        <tr><td>          if ($specificity eq 'Yes') {
               foreach my $tool (@{$tools}) {
                   @{$$showboxes{$tool}} = ();
                   foreach my $user (sort(keys(%{$usertools}))) {
                       unless (grep/^$tool$/,@{$showtools}) {
                           push(@{$showtools},$tool);
                       }
                       foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {
                           unless (exists($$fixedprivs{$tool}{$priv})) {
                               unless(grep(/^$priv$/,@{$$showboxes{$tool}})) {
                                   push(@{$$showboxes{$tool}},$priv);
                                   $totalboxes ++;
                               }
                           }
                       }
                   }
               }
               if ($totalboxes > 0) {
                   $r->print('
   <script type="text/javascript">
   function checkAllTools(formname) {
   ');
                   foreach my $tool (sort(keys(%{$showboxes}))) {
                       foreach my $priv (@{$$showboxes{$tool}}) {
                           $r->print('  checkAll(formname.'.$prefix.$priv.');'."\n");
                       }
                   }
                   $r->print('
   }
   function uncheckAllTools(formname) {
   ');
                   foreach my $tool (sort(keys(%{$showboxes}))) {
                       foreach my $priv (@{$$showboxes{$tool}}) {
                           $r->print('  uncheckAll(formname'.$prefix.$priv.');'."\n");
                       }
                   }
                   $r->print('
   }
   </script>
                   ');
               }
           }
       }
       return $totalboxes;
   }
   
   sub member_privileges_form {
       my ($r,$tabcol,$action,$formname,$tools,$toolprivs,$fixedprivs,$userdata,
           $usertools,$idx,$memchg,$states,$stored,$rowColor1,$rowColor2) = @_;
       my %lt = &Apache::lonlocal::texthash(
               'addp' => 'Additional privileges',
               'fixp' => 'Fixed privileges',
               'oppr' => 'Optional privileges',
               'func' => 'Function',
               'forf' => 'For the functionality you have chosen to include '.
                         'there are no optional privileges to set besides '.
                         'the standard privileges.',
               'algr' => 'All group members will receive the same privileges.',
               'asno' => 'As no group members are being added, '.
                         'there are no specific user privileges to set.',
               'asng' => 'As no group tools will be made available to users, '.
                         'there are no specific user privileges to set.',
               'full' => 'Fullname',
               'user' => 'Username',
               'doma' => 'Domain',
       );
       my @defprivs;
       my $specificity;
       if ($action eq 'create') {
           if (defined($env{'form.defpriv'})) {
               @defprivs = &Apache::loncommon::get_env_multiple('form.defpriv');
           }
           $specificity = $env{'form.specificity'};
       } else {
           @defprivs = @{$$stored{'defpriv'}};
           $specificity = $$stored{'specificity'};
       }
       my @showtools;
       my %showboxes = ();
       my $totalboxes = 0;
       my $numtools = 1 + @{$tools};
   
       $totalboxes = &build_boxes($r,$tools,$usertools,$fixedprivs,$toolprivs,
                                  \@showtools,\%showboxes,'userpriv_',
                                  $specificity);
       if (@{$tools} > 0) {
           if ($specificity eq 'Yes') {
               if ($totalboxes > 0) {
                   my $numcells = 2;
                   my $colspan = $numcells + 1;
                   my %total;
                   $r->print('
    <tr>
     <td>&nbsp;</td>
     <td colspan="3">
      <table border="0" cellspacing="2" cellpadding="2" border="0">
       <tr>
   ');
                   foreach my $tool (@{$tools}) {
                       if (@{$showboxes{$tool}} > 0) {
                           $r->print('<td valign="top">');
                           $r->print('<table class="thinborder"><tr bgcolor="'.$tabcol.
                         '"><th colspan="'.$colspan.'">'.$tool.'</th></tr><tr>');
                           my $privcount = 0;
                           foreach my $priv (@{$showboxes{$tool}}) {
                               $privcount ++;
                               if (($privcount == @{$showboxes{$tool}}) && ($privcount > 1)) {
                                   if ($privcount%$numcells) {
                                       $r->print('<td colspan="'.$colspan.'">');
                                   } else {
                                       $r->print('<td>');
                                   }
                               } else {
                                   $r->print('<td>');
                               }
                               $r->print(qq|
        <fieldset><legend><b>$$toolprivs{$tool}{$priv}</b></legend>         <fieldset><legend><b>$$toolprivs{$tool}{$priv}</b></legend>
          <nobr>
        <input type="button" value="check all"         <input type="button" value="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="uncheck all"
         onclick="javascript:uncheckAll(document.$formname.userpriv_$priv)" />          onclick="javascript:uncheckAll(document.$formname.userpriv_$priv)" />
       </nobr></fieldset></td></tr>|);        </nobr></fieldset><br />|);
                 }                              $r->print('</td>');
                 $r->print('</table><br /><br />');                              if ($privcount < @{$showboxes{$tool}}) {
             }                                  if (@{$showboxes{$tool}} > 2) {
         }                                      if ($privcount%$numcells == 0) {
         $r->print('</td></tr></table>');                                          $r->print('</tr><tr>');
     } else {                                      }
         $r->print(&Apache::lonhtmlcommon::start_pick_box());                                  } else {
         $r->print('<tr><td bgcolor="'.$tabcol.'" valign="top"><table cellspacing="0" cellpadding="1"><tr><td valign="top"><b>Function</b></td></tr><tr><td valign="top"><b>Fixed privileges</b>'.                                      $r->print('<tr></tr>');
                   '</td></tr><tr><td valign="top"><b>Optional privileges</b></td></tr></table></td>');                                  }
         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>');                          $r->print('</tr></table></td><td>&nbsp;</td>');
             my $privcount = 0;  
             my $fixed = '';  
             my $dynamic = '';  
             foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {  
                 if (exists($$fixedprivs{$tool}{$priv})) {  
                     $fixed .= '<input type="hidden" name="allpriv_'.$priv.'" value="all" />'.$$toolprivs{$tool}{$priv}.'&nbsp;';  
                 } else {  
                     $privcount ++;  
                     if ($privcount == 3) {  
                         $dynamic .= '</tr><tr bgcolor="'.$rowColor1.'">';  
                     }                      }
                     $dynamic .= '<td><input type="checkbox" name="allpriv_'.$priv.'" value="all" />'.$$toolprivs{$tool}{$priv}.'</td>';  
                 }                  }
                   $r->print('</tr></table></td></tr>');
                   $r->print('<tr><td colspan="4">&nbsp;</td></tr><tr><td>&nbsp;</td><td colspan="3">');
                   $r->print(&Apache::lonhtmlcommon::start_pick_box());
                   $r->print(<<"END");
      <tr bgcolor="$tabcol">
       <th><b>$lt{'full'}</th>
       <th><b>$lt{'user'}</th>
       <th>$lt{'doma'}</th>
       <th colspan="$numtools">$lt{'addp'}</th>
     </tr>
   END
                   &member_privs_entries($r,$tabcol,$rowColor1,$rowColor2,
                                         $usertools,$toolprivs,$fixedprivs,
                                         $userdata,$idx,\@showtools,\@defprivs);
                   $r->print('</td>');
                   $r->print(&Apache::lonhtmlcommon::end_pick_box());
                   $r->print('</td></tr>
    <tr>
     <td colspan="4">&nbsp;</td>
    </tr>
   ');
               } else {
                   $r->print('<tr><td>&nbsp;</td><td colspan="3">'.$lt{'forf'}.
                             '<br />');
                   &display_defprivs($r,$tabcol,$rowColor1,$rowColor2,$tools,
                               $toolprivs,\@defprivs);
                                                                                         
             }              }
             if ($dynamic eq '') {          } else {
                 $dynamic = '<td>None</td>';               if (keys(%{$usertools}) > 0) {
             }                  $r->print('<tr><td>&nbsp;</td><td colspan="3">'.$lt{'algr'}.
             if ($privcount < 3) {                            '<br /><br />');
                 $dynamic .= '</tr><tr bgcolor="'.$rowColor1.'"><td colspan="2">&nbsp;</td>';                  &display_defprivs($r,$tabcol,$rowColor1,$rowColor2,$tools,
             } elsif ($privcount%2) {                              $toolprivs,\@defprivs);
                 $dynamic = '<td>&nbsp;</td>';              } else {
                   $r->print('<tr><td>&nbsp;</td><td colspan="3">'.$lt{'asno'}.
                             '<br />');
             }              }
             $r->print('<tr bgcolor="'.$rowColor2.'"><td colspan="2" align="center"><nobr>'.$fixed.'</nobr></td></tr><tr bgcolor="'.$rowColor1.'">'.$dynamic.'</tr></table></td>');  
         }          }
         $r->print('</tr>');      } else {
         $r->print(&Apache::lonhtmlcommon::end_pick_box());          $r->print('<tr><td>&nbsp;</td><td colspan="3">'.$lt{'asng'});
     }      }
     $r->print('</td></tr>      return;
  <tr>  }
   <td colspan="4">&nbsp;</td>  
  </tr>  sub process_request {
       my ($r,$cdom,$cnum,$tabcol,$action,$state,$page,$groupname,$description,
           $specificity,$userdata,$startdate,$enddate,$tools,$functions,$toolprivs,
           $usertools,$idx,$types,$roles,$sections,$states,$navbuttons,$memchg,
           $sectioncount,$stored,$rowColor1,$rowColor2) = @_;
   
       $r->print(&Apache::lonhtmlcommon::echo_form_input(
                                           ['origin','action','state','page']));
   
       my $earlyout = &validate_groupname($groupname,$action,$cdom,$cnum);
       if ($earlyout) {
           $r->print('
   <table width="100%" cellpadding="0" cellspacing="0" border="0">
  <tr>   <tr>
   <td>&nbsp;</td>    <td>&nbsp;</td>
   <td colspan="3">    <td colspan="3">
    <input type="button" name="previous" value = "Go to previous page"  '.$earlyout.'</td></tr>');
     onclick="javascript:backPage(document.'.$formname.','."'pick_members'".')"/>          &display_navbuttons($r,$state,$$states{$action}[$page-1],
    &nbsp;&nbsp;                              $$navbuttons{'gtps'});
    <input type="button" name="next" value="Create group"          $r->print('</table>');
  onclick="javascript:nextPage(document.'.$formname.','."'result'".')" />          return;
   </td>      }
  </tr>  
     ');      my @defprivs = ();
     $r->print('      if ($action eq 'create' || $state eq 'chgresult') { 
 </table>');          if (defined($env{'form.defpriv'})) {
               @defprivs = &Apache::loncommon::get_env_multiple('form.defpriv');
           }
           if ($state eq 'chgresult') {
               my @okprivs = ();
               foreach my $tool (@{$tools}) {
                   foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {
                       push(@okprivs,$priv);
                   }
               }
               my @temp = ();
               foreach my $defpriv (@defprivs) {
                   if (grep/^$defpriv$/,@okprivs) {
                       push(@temp,$defpriv);
                   }
               }
               @defprivs = @temp; 
           }
       } else {
           @defprivs = @{$$stored{'defpriv'}};
       }
   
       my $outcome;
       if ($action eq 'create' || $state eq 'chgresult') {
           $outcome = &write_group_data($r,$cdom,$cnum,$action,$state,$groupname,
                                        $description,$startdate,$enddate,
                                        $specificity,$functions,$tools,
                                        $sectioncount,$roles,$types,$sections,
                                        \@defprivs,$stored); 
       }
       if (($action eq 'create' && $outcome eq 'ok') || (($action eq 'modify') && 
          (($state eq 'memresult') || ($state eq 'addresult')))) {
           &process_membership($r,$cdom,$cnum,$groupname,$tools,$enddate,
                               $startdate,$userdata,$idx,$toolprivs,$usertools,
                               $specificity,\@defprivs);
       }
     return;      return;
 }  }
   
 sub completed_creation {  sub write_group_data {
     my ($r,$cdom,$cnum,$tabcol,$formname,$groupname,$description,$userdata,      my ($r,$cdom,$cnum,$action,$state,$groupname,$description,$startdate,
 $startdate,$enddate,$tools,$functions,$toolprivs,$members,$usertools,$idx) = @_;          $enddate,$specificity,$functions,$tools,$sectioncount,$roles,$types,
           $sections,$defprivs,$stored) = @_;
       my $now = time;
       my $creation = $now;
       my $creator = $env{'user.name'}.':'.$env{'user.domain'};
       if ($state eq 'chgresult') {
           $creation = $$stored{'creation'};
           $creator = $$stored{'creator'};
       }
       my $esc_description = &Apache::lonnet::escape($description);
       my @single_attributes = ('description','functions','startdate','enddate',
                                'creation','modified','creator','granularity',
                                'specificity','autoadd','autodrop');
       my @mult_attributes = ('roles','types','sectionpick','defpriv');
                                                                                       
       my %groupinfo = (
                        description => $esc_description,
                        startdate => $startdate,
                        enddate => $enddate,
                        creation => $creation,
                        modified => $now,
                        creator => $creator,
                        granularity => $env{'form.granularity'},
                        specificity => $specificity,
                        autoadd => $env{'form.autoadd'},
                        autodrop => $env{'form.autodrop'},
                      );
       foreach my $func (keys(%{$functions})) {
           my $status;
           if (grep(/^$func$/,@{$tools})) {
               $status = 'on';
           } else {
               $status = 'off';
           }
           $groupinfo{'functions'} .=  qq|<name id="$func">$status</name>|;
       }
   
       $groupinfo{'roles'} = $roles;
       $groupinfo{'types'} = $types;
       $groupinfo{'sectionpick'} = $sections;
       $groupinfo{'defpriv'} = $defprivs;
   
     $r->print(&Apache::lonhtmlcommon::echo_form_input(      my %groupsettings = ();
                                         ['origin','action','state']));      foreach my $item (@single_attributes) {
           $groupsettings{$groupname} .= qq|<$item>$groupinfo{$item}</$item>|;
       }
       foreach my $item (@mult_attributes) {
           foreach my $entry (@{$groupinfo{$item}}) {
               $groupsettings{$groupname} .= qq|<$item>$entry</$item>|;
           }
       }
       my $autosec;
       my @autorole = &Apache::loncommon::get_env_multiple('form.autorole');
                                                                                       
       foreach my $role (@autorole) {
           if (defined($env{'form.sec_'.$role})) {
               my @autosections=&Apache::loncommon::get_env_multiple('form.sec_'.
                                                                     $role);
               if (grep/^_all$/,@autosections) {
                   @autosections = sort {$a cmp $b} keys(%{$sectioncount});
               }
               $autosec .= '<role id="'.$role.'">';
               foreach my $sec (@autosections) {
                   $autosec .= '<section>'.$sec.'</section>';
               }
               $autosec .= '</role>';
           }
       }
       if ($autosec) {
           $groupsettings{$groupname} .= qq|<autosec>$autosec</autosec>|;
       }
       my $result = &Apache::lonnet::modify_coursegroup($cdom,$cnum,
                                                        \%groupsettings);
   
       if ($result eq 'ok') {
           if ($action eq 'create') {
               my $put_result = &create_homepage($cdom,$cnum,$groupname,
                                                 \%groupinfo,$tools);
               $r->print('Group '.$groupname.' was created.<br />');
           } else {
               $r->print('Group '.$groupname.' was updated.<br />');
           }
       } else {
           my %actiontype = (
                             'create' => 'creating',
                             'modify' => 'modifying',
                            );
           &Apache::lonnet::logthis('Failed to store group '.$groupname.
                                    'in course: '.$cnum.' in domain: '.$cdom);
           $r->print(&mt('An error occurred when [_1] the new group. '.
                         'Please try again.',$actiontype{$action}));
       }
       return $result;
   }
   
   sub process_membership {
       my ($r,$cdom,$cnum,$groupname,$tools,$enddate,$startdate,$userdata,$idx,
           $toolprivs,$usertools,$specificity,$defprivs) = @_;
       my %usersettings = ();
     my @added= ();      my @added= ();
     my @failed = ();      my @failed = ();
     my $now = time;  
     my %group_privs = ();      my %group_privs = ();
     my %tooltype = ();      my %tooltype = ();
   
     foreach my $tool (@{$tools}) {      foreach my $tool (@{$tools}) {
         foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {          foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {
             $tooltype{$priv} = $tool;              $tooltype{$priv} = $tool;
             if ($env{'form.specificity'} eq 'Yes') {              if ($specificity eq 'Yes') {
                 my @users =                  my @users =
                   &Apache::loncommon::get_env_multiple('form.userpriv_'.$priv);                    &Apache::loncommon::get_env_multiple('form.userpriv_'.$priv);
                 foreach my $user (@users) {                  foreach my $user (@users) {
                     $group_privs{$user} .= $priv.':';                      $group_privs{$user} .= $priv.':';
                 }                  }
             } else {              } else {
                 if (defined($env{'form.allpriv_'.$priv})) {                  if (@{$defprivs} > 0) {
                     foreach my $user (@{$members}) {                      foreach my $priv (@{$defprivs}) {
                         if ($$usertools{$user}{$tool}) {                          foreach my $user (sort(keys(%{$usertools}))) {
                             $group_privs{$user} .= $priv.':';                              if ($$usertools{$user}{$tool}) {
                                   $group_privs{$user} .= $priv.':';
                               }
                         }                          }
                     }                      }
                 }                  }
Line 1365  $startdate,$enddate,$tools,$functions,$t Line 2654  $startdate,$enddate,$tools,$functions,$t
     foreach my $user (keys(%group_privs)) {      foreach my $user (keys(%group_privs)) {
         $group_privs{$user} =~ s/:$//;          $group_privs{$user} =~ s/:$//;
     }      }
     my $esc_description = &Apache::lonnet::escape($description);  
     my @attributes = ('description','functions','startdate','enddate','creation','modified','creator');      foreach my $user (sort(keys(%{$usertools}))) {
                   $usersettings{$groupname.':'.$user} = $enddate.':'.$startdate.':'.
     my %groupinfo = (                                                $group_privs{$user};
                       description => $esc_description,          if (&Apache::lonnet::modify_group_roles($cdom,$cnum,$groupname,
                       startdate => $startdate,                                                  $user,$enddate,$startdate,
                       enddate => $enddate,                                                  $group_privs{$user}) eq 'ok') {
                       creation => $now,              push(@added,$user);
                       modified => $now,  
                       creator => $env{'user.name'}.':'.$env{'user.domain'},   
                     );  
     foreach my $func (keys(%{$functions})) {  
         my $status;  
         if (grep(/^$func$/,@{$tools})) {  
             $status = 'on';  
         } else {          } else {
             $status = 'off';              push(@failed,$user);
         }           }
         $groupinfo{'functions'} .=  qq|<name id="$func">$status</name>|;  
     }      }
       my $roster_result = &Apache::lonnet::modify_coursegroup_membership($cdom,
     my %curr_groups = ();                                                         $cnum,\%usersettings);
     my %groupsettings = ();      if (@added > 0) {
     my %usersettings = ();          $r->print('Users were added with following privileges:<br />');
     if (&Apache::loncommon::coursegroups(\%curr_groups,$cdom,$cnum,$groupname)) {          foreach my $user (@added) {
         if (exists($curr_groups{$groupname})) {              my @privs = split(/:/,$group_privs{$user});
             $r->print('Non-unique name - please choose another');              my $privlist= '';
             return;               my $curr_tool = '';
               foreach my $priv (@privs) {
                   unless ($curr_tool eq $tooltype{$priv}) {
                       $curr_tool = $tooltype{$priv};
                       $privlist .= '<b>'.$curr_tool.'</b>: ';
                   }
                   $privlist .= $$toolprivs{$curr_tool}{$priv}.', ';
               }
               $privlist =~ s/, $//;
               $r->print($$userdata{$user}[$$idx{fullname}].'&nbsp;-&nbsp;'.$user.': '.$privlist.'<br />');
         }          }
     }      }
     my $groupentry;      if (@failed > 0) {
     foreach my $item (@attributes) {          $r->print('Addition of the following users was unsuccessful:<br />');
         $groupsettings{$groupname} .= qq|<$item>$groupinfo{$item}</$item>|;          foreach my $user (@failed) {
               $r->print($$userdata{$user}[$$idx{fullname}].' - '.$user.'<br />');
           }
     }      }
     my $result = &Apache::lonnet::modify_coursegroup($cdom,$cnum,      if ($roster_result eq 'ok') {
                                                           \%groupsettings);          $r->print('<br />Group membership list updated.');
     if ($result eq 'ok') {      } else {
         my $put_result = &create_homepage($cdom,$cnum,$groupname,\%groupinfo,$tools);          $r->print('<br />An error occurred while updating the group membership list -'.$roster_result.'<br />');
         foreach my $user (sort(@{$members})) {      }
             $usersettings{$groupname.':'.$user} = $enddate.':'.$startdate.':'.$group_privs{$user};      return;
             if (&Apache::lonnet::modify_group_roles($cdom,$cnum,$groupname,  }
                   $user,$enddate,$startdate,$group_privs{$user}) eq 'ok') {  
                 push(@added,$user);  sub mapping_options {
             } else {      my ($r,$action,$formname,$page,$tabcol,$sectioncount,$states,$stored,
                 push(@failed,$user);          $navbuttons,$img1,$img2,$rowColor1,$rowColor2) = @_;
             }      my %lt = &Apache::lonlocal::texthash(
           'auto' => 'Settings for automatic group enrollment',
           'gmma' => 'Group membership mapping to specific sections/roles',
           'endi' => 'Enable/disable automatic group enrollment for '.
                             '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.',
           '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.",
           'pirs' => 'Pick roles and sections for automatic group enrollment',
           'curr' => 'Currently set to',
           'on' => 'on',
           'off' => 'off',
           'auad' => 'Automatically enable group membership when roles are added?',
           'auex' => 'Automatically expire group membership when roles are removed?',
           'mapr' => 'Mapping of roles and sections affected by automatic group enrollment/disenrollment follows scheme chosen below.',
       );
       &automapping($r,$action,$tabcol,$stored,\%lt,$img1);
       $r->print('
      <tr>
       <td colspan="4">&nbsp;</td>
      </tr>');
       &mapping_settings($r,$tabcol,$rowColor1,$rowColor2,$sectioncount,\%lt,
                                                          $stored,$img2);
       return;
   }
   
   sub automapping {
       my ($r,$action,$tabcol,$stored,$lt,$image) = @_;
       my $add = 'off';
       my $drop = 'off';
       if (exists($$stored{'autoadd'})) {
           $add = $$stored{'autoadd'};
       }
       if (exists($$stored{'autodrop'})) {
           $drop = $$stored{'autodrop'};
       }
       &topic_bar($r,$tabcol,$image,$$lt{'endi'});
       $r->print('
     <tr>
      <td>&nbsp;</td>
      <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') {
           $r->print('&nbsp;&nbsp;&nbsp;&nbsp;('.$$lt{'curr'}.' <b>'.$$lt{$add}.'</b>)');
       }
       $r->print('
       </nobr>
      </td>
     </tr>
     <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') {
           $r->print('&nbsp;&nbsp;&nbsp;&nbsp;('.$$lt{'curr'}.' <b>'.$$lt{$drop}.'</b>)');
       }
       $r->print('</nobr>
      </td>
     </tr>
     <tr>
      <td colspan="4">&nbsp;</td>
     </tr>
     <tr>
      <td>&nbsp;</td>
      <td colspan="3">'.$$lt{'mapr'}.'
      </td>
     </tr>
   ');
   }
   
   sub mapping_settings {
       my ($r,$tabcol,$rowColor1,$rowColor2,$sectioncount,$lt,$stored,$image) = @_;
       my @sections = keys(%{$sectioncount});
       if (@sections > 0) {
           @sections = sort {$a cmp $b} @sections;
           unshift(@sections,'_nosec'); # Put 'no sections' next
           unshift(@sections,'_all'); # Put 'all' at the front of the list
       }
       &topic_bar($r,$tabcol,$image,$$lt{'pirs'});
       $r->print('
      <tr>
       <td>&nbsp;</td>
       <td colspan="3">
   ');
       my @roles = &standard_roles();
       my %customroles = &my_custom_roles();
       $r->print(&Apache::lonhtmlcommon::start_pick_box());
       $r->print('
                   <tr bgcolor="'.$tabcol.'">
                    <th>'.&mt('Active?').'</th>
                    <th>'.&mt('Role').'</th>');
       if (@sections > 0) {
           $r->print('<th>'.&mt('Sections').'</th></tr>'."\n");
       }
       my $rowNum = 0;
       my $rowColor;
       foreach my $role (@roles) {
           my $plrole=&Apache::lonnet::plaintext($role);
           my $sections_sel;
           if (@sections > 0) {
               $sections_sel='<td>'.&sections_selection(\@sections,'sec_'.$role).
                                                                          '</td>';
         }          }
         my $roster_result = &Apache::lonnet::modify_coursegroup_membership(          if ($rowNum %2 == 1) {
              $cdom,$cnum,\%usersettings);              $rowColor = $rowColor1;
         $r->print('          } else {
 Group '.$groupname.' was created.<br />');              $rowColor = $rowColor2;
         if (@added > 0) {  
             $r->print('Users were added with following privileges:<br />');  
             foreach my $user (@added) {  
                 my @privs = split(/:/,$group_privs{$user});  
                 my $privlist= '';  
                 my $curr_tool = '';  
                 foreach my $priv (@privs) {  
                     unless ($curr_tool eq $tooltype{$priv}) {  
                         $curr_tool = $tooltype{$priv};  
                         $privlist .= '<b>'.$curr_tool.'</b>: ';  
                     }  
                     $privlist .= $$toolprivs{$curr_tool}{$priv}.', ';  
                 }  
                 $privlist =~ s/, $//;  
                 $r->print($$userdata{$user}[$$idx{fullname}].'&nbsp;-&nbsp;'.$user.': '.$privlist.'<br />');  
             }  
         }  
         if (@failed > 0) {  
             $r->print('Addition of the following users was unsuccessful:<br />');  
             foreach my $user (@failed) {  
                 $r->print($$userdata{$user}[$$idx{fullname}].' - '.$user.'<br />');  
             }  
         }          }
         if ($roster_result eq 'ok') {          $r->print('<tr bgcolor="'.$rowColor.'"><td><input type="checkbox" '.
             $r->print('<br />Group membership list updated.');                    'name="autorole" value="'.$role.'"></td><td>'.$plrole.
                     '</td>'.$sections_sel.'</tr>');
           $rowNum ++;
       }
       foreach my $role (sort(keys(%customroles))) {
           my $sections_sel;
           if (@sections > 0) {
               $sections_sel = '<td>'.&sections_selection(\@sections,'sec_'.$role).
                                                                           '</td>';
           }
           if ($rowNum %2 == 1) {
               $rowColor = $rowColor1;
         } else {          } else {
             $r->print('<br />An error occurred while updating the group membership list -'.$roster_result.'<br />');              $rowColor = $rowColor2;
         }           }
     } else {          $r->print('<tr bgcolor="'.$rowColor.'"><td><input type="checkbox" '.
         &Apache::lonnet::logthis('Failed to create group '.$groupname.                     'value="'.$role.'"></td><td>'.$role.'</td>'.
                                  'in course: '.$cnum.' in domain: '.$cdom);                    $sections_sel.'</tr>');
           $rowNum ++;
       }
       $r->print(&Apache::lonhtmlcommon::end_pick_box());
       return;
   }
   
         $r->print('An error occurred when creating the new group. '.  sub standard_roles {
                                                       'Please try again.');      my @roles = ('st','ep','ta','in','cc');
       return @roles;
   }
   
   sub my_custom_roles {
       my %returnhash=();
       my %rolehash=&Apache::lonnet::dump('roles');
       foreach (keys %rolehash) {
           if ($_=~/^rolesdef\_(\w+)$/) {
               $returnhash{$1}=$1;
           }
       }
       return %returnhash;
   }
   
   sub modify_menu {
       my ($r,$groupname,$page) = @_;
       my @menu =
           (
             { text => 'Modify default group settings',
               help => 'Course_Modify_Group',
               state => 'change_settings',
               branch => 'settings',
               },
             { text => 'Modify access, tools and/or privileges for previous,future'.
                       'or current members',
               help => 'Course_Modify_Group_Membership',
               state => 'change_members',
               branch => 'members',
               },
             { text => 'Add member(s) to the group',
               help => 'Course_Group_Add_Members',
               state => 'add_members',
               branch => 'adds',
               },
             );
       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,$members,$tools,$usertools,$toolprivs,      my ($r,$tabcol,$rowColor1,$rowColor2,$usertools,$toolprivs,
                                               $fixedprivs,$userdata,$idx) = @_;          $fixedprivs,$userdata,$idx,$showtools,$defprivs) = @_;
     my $rowColor;      my $rowColor;
     my $rowNum = 0;      my $rowNum = 0;
     foreach my $member (@{$members}) {      foreach my $user (sort(keys(%{$usertools}))) {
         my ($uname,$udom) = split(/:/,$member);          my ($uname,$udom) = split(/:/,$user);
         if ($rowNum %2 == 1) {          if ($rowNum %2 == 1) {
             $rowColor = $rowColor1;              $rowColor = $rowColor1;
         } else {          } else {
             $rowColor = $rowColor2;              $rowColor = $rowColor2;
         }          }
         $r->print('<tr bgcolor="'.$rowColor.'">          $r->print('<tr bgcolor="'.$rowColor.'">
                 <td>'.$$userdata{$member}[$$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>Function</b></td></tr><tr><td><b>Fixed</b></td></tr><tr><td><b>Optional</b></td></tr></table></td>');
         foreach my $tool (@{$tools}) {          foreach my $tool (@{$showtools}) {
             if (exists($$usertools{$member}{$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 bgcolor="'.$tabcol.'"><td colspan="2" align="center"><b>'.$tool.'</b></td></tr>');
                 my $privcount = 0;                  my $privcount = 0;
                 my $fixed = '';                  my $fixed = '';
                 my $dynamic = '';                  my $dynamic = '';
                 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="userpriv_'.$priv.'" value="'.$member.'" />'.$$toolprivs{$tool}{$priv}.'&nbsp;';                          $fixed .= '<input type="hidden" name="userpriv_'.$priv.'" value="'.$user.'" />'.$$toolprivs{$tool}{$priv}.'&nbsp;';
                     } else {                      } else {
                         $privcount ++;                          $privcount ++;
                         if ($privcount == 3) {                          if ($privcount == 3) {
                             $dynamic .= '</tr><tr>';                              $dynamic .= '</tr><tr>';
                         }                          }
                         $dynamic .= '<td><input type="checkbox" name="userpriv_'.$priv.'" value="'.$member.'" />'.$$toolprivs{$tool}{$priv}.'</td>';                          $dynamic .='<td><nobr><input type="checkbox" '.
                                  'name="userpriv_'.$priv.'" value="'.$user.'"';
                           if (grep/^\Q$priv\E$/,@{$defprivs}) {
                               $dynamic .= ' checked="checked" ';
                           }
                           $dynamic .= ' />'.$$toolprivs{$tool}{$priv}.
                                       '</nobr></td>';
                     }                      }
                 }                  }
                 $r->print('<tr><td colspan="2"><nobr>'.$fixed.'</nobr></td></tr><tr>'.$dynamic.'</tr></table></td>');                  $r->print('<tr><td colspan="2"><nobr>'.$fixed.'</nobr></td></tr><tr>'.$dynamic.'</tr></table></td>');
             } else {              } else {
                 $r->print('<td>&nbsp;</td>');                  $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>');
             }              }
         }          }
         $rowNum ++;          $rowNum ++;
     }      }
 }  }
   
   
 sub get_dates_from_form {  sub get_dates_from_form {
     my $startdate;      my $startdate;
     my $enddate;      my $enddate;
Line 1507  sub get_dates_from_form { Line 2955  sub get_dates_from_form {
         $enddate = 0;          $enddate = 0;
     }      }
     return ($startdate,$enddate);      return ($startdate,$enddate);
 }                                                                                       }
   
 sub date_setting_table {  sub date_setting_table {
     my ($starttime,$endtime,$formname) = @_;      my ($starttime,$endtime,$formname) = @_;
     my $startform = &Apache::lonhtmlcommon::date_setter($formname,      my $startform = &Apache::lonhtmlcommon::date_setter($formname,
Line 1553  sub create_homepage { Line 3002  sub create_homepage {
    return $putresult;     return $putresult;
 }  }
   
   sub check_uncheck_tools {
       my ($r,$available) = @_;
       if (ref($available) eq 'ARRAY') { 
           $r->print('
   <script type="text/javascript">
   function checkAllTools(formname) {
   ');
           foreach my $tool (@{$available}) {
               $r->print('  checkAll(formname.user_'.$tool.');'."\n");
           }
           $r->print(' checkAll(formname.togglefunc);'."\n");
           $r->print('
   }
   function uncheckAllTools(formname) {
   ');
           foreach my $tool (@{$available}) {
               $r->print('  uncheckAll(formname.user_'.$tool.');'."\n");
           }
           $r->print(' uncheckAll(formname.togglefunc);'."\n");
           $r->print('
   }
   function toggleTools(field,caller) {
        if (caller.checked) {
            checkAll(field);
        } else {
            uncheckAll(field);
        }
        return;   
   }
   </script>
   ');
       }
       return;
   }
   
   sub validate_groupname {
       my ($groupname,$action,$cdom,$cnum) = @_;
       my %sectioncount;
       my $numsec=&Apache::loncommon::get_sections($cdom,$cnum,\%sectioncount);
       my %curr_groups;
       my $numgroups=&Apache::loncommon::coursegroups(\%curr_groups,$cdom,$cnum);
                                                                                            
       my %lt = &Apache::lonlocal::texthash (
                         igna => 'Invalid group name',
                         tgne => 'The group name entered ',
                         grna => 'Group names and section names used in a course '.
                                 'must be unique.',
                         isno => 'is not a valid name.',
                         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'}.' "'.
                     $groupname.'" ';
       my $dupmsg = $lt{'grna'};
       my $earlyout;
       if (($groupname eq '') || ($groupname =~ /\W/)) {
           $earlyout = $exitmsg.$lt{'isno'}.'<br />'.$lt{'gnmo'};
           return $earlyout;
       }
       if ($numsec) {
           if (exists($sectioncount{$groupname})) {
               $earlyout = $exitmsg.$lt{'cnnb'}.&mt('a section').$lt{'inth'}.
                           '<br />'.$lt{'grna'};
               return $earlyout;
           }
       }
       if ($action eq 'create') {
           if ($numgroups) {
               if (exists($curr_groups{$groupname})) {
                   $earlyout = $exitmsg.$lt{'cnnb'}.&mt('an existing group').
                               $lt{'inth'}.'<br />'.$lt{'grna'};
                   return $earlyout;
               }
           }
       } elsif ($action eq 'modify') {
           unless(exists($curr_groups{$groupname})) {
               $earlyout = &mt('Group name:').' '.$groupname.$lt{'thgr'}.$lt{'inth'};
               return $earlyout;
           }
       }
       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 {
       my ($member_changes,$memchg) = @_;
       my %exclusions;
       @{$exclusions{'changefunc'}} = ('expire');
       @{$exclusions{'changepriv'}} = ('expire','changefunc');
   
       foreach my $change (@{$member_changes}) {
           if ($change eq 'delete') {
               next;
           }
           my @checks = ('delete');
           if (exists($exclusions{$change})) {
               push(@checks,@{$exclusions{$change}});
           }
           my @temp = ();
           foreach my $item (@{$$memchg{$change}}) {
               my $match = 0;
               foreach my $check (@checks) {
                   if (@{$$memchg{$check}} > 0) {
                       if (grep/^$item$/,@{$$memchg{$check}}) {
                           $match = 1;
                           last;
                       }
                   }
               }
               if ($match) {
                   next;
               }
               push(@temp,$item);
           }
           @{$$memchg{$change}} = @temp;
       }
   }
   
 1;  1;

Removed from v.1.4  
changed lines
  Added in v.1.5


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