Diff for /loncom/interface/courseprefs.pm between versions 1.8.2.8 and 1.49.2.18

version 1.8.2.8, 2010/02/22 15:59:28 version 1.49.2.18, 2015/05/22 16:39:43
Line 122  Creates table used to display and set co Line 122  Creates table used to display and set co
   
 Inputs: $cdom,$items,$ordered,$settings,$rowtotal,$crstype  Inputs: $cdom,$items,$ordered,$settings,$rowtotal,$crstype
 where $cdom is course's domain, $items is HASH ref for current config  where $cdom is course's domain, $items is HASH ref for current config
 item, $ordered is ARRAY ref of items to include in row in  item, $ordered is ARRAY ref of items to include in row in 
 display order, $settings is HASH ref of current values forrow,  display order, $settings is HASH ref of current values forrow,
 $rowtotal is SCALAR ref used to accumulate row count, $crstype is  $rowtotal is SCALAR ref used to accumulate row count, $crstype is    
 course type.  course type.
   
 Returns: $datatable  Returns: $datatable
 HTML mark-up of data table which accumulates individual rows.  HTML mark-up of data table which accumulates individual rows.  
   
 =item nothidepriv_row()  =item nothidepriv_row()
   
 Creates row containing form elements used to display and set  Creates row containing form elements used to display and set
 whether Domain coordinators who are currently included in  whether Domain coordinators who are currently included in  
 advanced course user .db file for a course are to be hidden (e.g.,  advanced course user .db file for a course are to be hidden (e.g.,
 in syllabus, or from course user lists).  in syllabus, or from course user lists).
   
 Inputs: $cdom,$item,$settings,$crstype  Inputs: $cdom,$item,$settings,$crstype
 where $cdom is course domain, item is nothideprivileged, $settings is  where $cdom is course domain, item is nothideprivileged, $settings is
 HASH ref of the current values for nothideprivileged, $crstype is  HASH ref of the current values for nothideprivileged, $crstype is 
 course type (Course or Community).  course type (Course or Community). 
   
 Returns: $datatable  Return: $datatable
 HTML mark-up for Privileged users (Domain Coordinators) in staff listing.  HTML mark-up for Privileged users (Domain Coordinators) in staff listing.
   
 =item print_hdrfmt_row()  =item print_hdrfmt_row()
Line 163  for the "Print header format" row. Line 163  for the "Print header format" row.
 =item position_selector()  =item position_selector()
   
 Creates a select box which can be used to reorder substitutions  Creates a select box which can be used to reorder substitutions
 and text included in a printout header.  and text included in a printout header. 
   
 Inputs: $pos,$num,$maxnum  Inputs: $pos,$num,$maxnum
 where $pos is current position, $num is the unique identifier,  where $pos is current position, $num is the unique identifier,
Line 171  and $maxnum is the total number of items Line 171  and $maxnum is the total number of items
 and text in the printout header.  and text in the printout header.
   
 Returns: $output  Returns: $output
 HTML mark-up for the selectbox and a hidden form element containing  HTML mark-up for the selectbox and a hidden form element containing 
 the current position.  the current position.   
   
 =item substitution_selector()  =item substitution_selector()
   
 Creates a combination of select box for choosing an item  Creates a combination of select box for choosing an item 
 (student name, course ID or assignment note) to substitute,  (student name, course ID or assignment note) to substitute, 
 and a corresponding size limit in the header used for printouts.  and a corresponding size limit in the header used for printouts.
   
 Inputs: $num,$subst,$limit,$crstype  Inputs: $num,$subst,$limit,$crstype
 where $num is the unique identifier, $subst is the current  where $num is the unique identifier, $subst is the current 
 substitution (n,c or a, for name, course or note respectively,  substitution (n,c or a, for name, course or note respectively,
 $limit is the current size limit (integer), and $crstype is  $limit is the current size limit (integer), and $crstype is
 course type - course or community.  course type - course or community.
   
 Returns: $output  Returns: $output
 HTML mark-up for selectbox and textbox (separate table cells).  HTML mark-up for selectbox and textbox (separate table cells).  
   
 =item change_clone()  =item change_clone()
   
Line 215  use Apache::lonnet; Line 215  use Apache::lonnet;
 use Apache::loncommon();  use Apache::loncommon();
 use Apache::lonhtmlcommon();  use Apache::lonhtmlcommon();
 use Apache::lonconfigsettings;  use Apache::lonconfigsettings;
   use Apache::lonrelrequtils;
   use Apache::lonparmset;
   use Apache::courseclassifier;
 use Apache::lonlocal;  use Apache::lonlocal;
 use LONCAPA qw(:DEFAULT :match);  use LONCAPA qw(:DEFAULT :match);
   
   my $registered_cleanup;
   my $modified_courses;
   
 sub handler {  sub handler {
     my $r=shift;      my $r=shift;
     if ($r->header_only) {      if ($r->header_only) {
Line 227  sub handler { Line 233  sub handler {
     }      }
     my $context = 'course';      my $context = 'course';
     my $cid = $env{'request.course.id'};      my $cid = $env{'request.course.id'};
     my ($cnum,$cdom) = &get_course($cid);      my ($cnum,$cdom,$chome) = &get_course($cid);
     my $crstype = &Apache::loncommon::course_type();      my $crstype = &Apache::loncommon::course_type();
     my $parm_permission = &Apache::lonnet::allowed('opa',$cid);      my $parm_permission = &Apache::lonnet::allowed('opa',$cid);
     my $navmap = Apache::lonnavmaps::navmap->new();      my $navmap = Apache::lonnavmaps::navmap->new();
Line 256  sub handler { Line 262  sub handler {
         return HTTP_NOT_ACCEPTABLE;          return HTTP_NOT_ACCEPTABLE;
     }      }
   
       $registered_cleanup=0;
       @{$modified_courses}=();
   
     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},      &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                                             ['phase','actions','origin']);                                              ['phase','actions','origin']);
     &Apache::lonhtmlcommon::clear_breadcrumbs();      &Apache::lonhtmlcommon::clear_breadcrumbs();
Line 267  sub handler { Line 276  sub handler {
     my %lt;      my %lt;
     if ($crstype eq 'Community') {      if ($crstype eq 'Community') {
         %lt = (          %lt = (
                 conf => 'Community Configuration',                  conf => 'Community Settings',
                 edit => 'Edit Community Configuration',                  edit => 'Edit Community Settings',
                 gens => 'General community settings',                  gens => 'General community settings',
                 idnu => 'Community ID or number',                  idnu => 'Community ID or number',
                   unco => 'Unique code',
                 desc => 'Community Description',                  desc => 'Community Description',
                 ownr => 'Community Owner',                  ownr => 'Community Owner',
                   cown => 'Community Co-owners',
                 catg => 'Categorize community',                  catg => 'Categorize community',
                 excc => 'Exclude from community catalog',                  excc => 'Exclude from community catalog',
                 clon => 'Users allowed to clone community',                  clon => 'Users allowed to clone community',
Line 285  sub handler { Line 296  sub handler {
                 defd => 'Default dates for member access',                  defd => 'Default dates for member access',
                 stuv => 'Member-viewable membership list options',                  stuv => 'Member-viewable membership list options',
                 stul => 'Member agreement needed to be listed',                  stul => 'Member agreement needed to be listed',
                 clas => 'Membership and Facilitator Listing',                  clas => 'Membership and facilitator listing',
                 priv => 'Privileged users (Domain Coordinators) in facilitator listing',                  prus => 'Privileged users (Domain Coordinators) in facilitator listing',
                 defc => 'Default Community Spreadsheet',                  defc => 'Default Community Spreadsheet',
                 defs => 'Default User Spreadsheet',                  defs => 'Default User Spreadsheet',
                 seme => 'Send message to member when clicking Done on Tasks'                  seme => 'Send message to member when clicking Done on Tasks'
               );                );
     } else {      } else {
         %lt = (          %lt = (
                 conf => 'Course Configuration',                  conf => 'Course Settings',
                 edit => 'Edit Course Configuration',                  edit => 'Edit Course Settings',
                 gens => 'General course settings',                  gens => 'General course settings',
                 idnu => 'Course ID or number',                  idnu => 'Course ID or number',
                   unco => 'Unique code',
                 desc => 'Course Description',                  desc => 'Course Description',
                   cred => 'Student credits',
                 ownr => 'Course Owner',                  ownr => 'Course Owner',
                   cown => 'Course Co-owners',
                 catg => 'Categorize course',                  catg => 'Categorize course',
                 excc => 'Exclude from course catalog',                  excc => 'Exclude from course catalog',
                 clon => 'Users allowed to clone course',                  clon => 'Users allowed to clone course',
Line 311  sub handler { Line 325  sub handler {
                 defd => 'Default dates for student access',                  defd => 'Default dates for student access',
                 stuv => 'Student-viewable classlist options',                  stuv => 'Student-viewable classlist options',
                 stul => 'Student agreement needed to be listed',                  stul => 'Student agreement needed to be listed',
                 clas => 'Classlists and Staff Listing',                  clas => 'Classlists and staff listing',
                 priv => 'Privileged users (Domain Coordinators) in staff listing',                  prus => 'Privileged users (Domain Coordinators) in staff listing',
                   prdo => "Domains to check for privileged users (besides course's domain)",
                 defc => 'Default Course Spreadsheet',                  defc => 'Default Course Spreadsheet',
                 defs => 'Default Student Spreadsheet',                  defs => 'Default Student Spreadsheet',
                 seme => 'Send message to student when clicking Done on Tasks',                  seme => 'Send message to student when clicking Done on Tasks',
               );                );
     }      }
       $lt{'lcrv'} = 'Required LON-CAPA version';
     &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/courseprefs',      &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/courseprefs',
         text=>$lt{'conf'}});          text=>$lt{'conf'}});
     my $breadcrumbs =      my $breadcrumbs =
Line 333  sub handler { Line 349  sub handler {
         return OK;          return OK;
     }      }
   
       if ($phase eq 'releaseinfo') {
           my $loncaparev = $env{'course.'.$cid.'.internal.releaserequired'};
           if ($loncaparev) { 
               if (&display_loncaparev_constraints($r,$navmap,$loncaparev,$crstype)) {
                   push(@{$modified_courses},[$cdom,$cnum,$chome,$crstype]);
                   unless ($registered_cleanup) {
                       my $handlers = $r->get_handlers('PerlCleanupHandler');
                       $r->set_handlers('PerlCleanupHandler' => [\&update_releasereq,@{$handlers}]);
                       $registered_cleanup=1;
                   }
               }
               return OK;
           }
       }
   
     my %values=&Apache::lonnet::dump('environment',$cdom,$cnum);      my %values=&Apache::lonnet::dump('environment',$cdom,$cnum);
     my @prefs_order = ('courseinfo','localization','feedback','discussion',      my @prefs_order = ('courseinfo','localization','feedback','discussion',
                        'classlists','appearance','grading','printouts',                         'classlists','appearance','grading','printouts',
Line 341  sub handler { Line 372  sub handler {
     my %prefs = (      my %prefs = (
         'courseinfo' =>          'courseinfo' =>
                    { text => $lt{'gens'},                     { text => $lt{'gens'},
                      help => 'Course_Environment',                       help => 'Course_Prefs_General',
                      header => [{col1 => 'Setting',                       ordered => ['owner','co-owners','loncaparev','description',
                                  col2 => 'Value'}],                                   'clonedfrom','courseid','uniquecode','categories',
                      ordered => ['owner','description','courseid','categories',                                   'hidefromcat','externalsyllabus','cloners','url',
                                  'hidefromcat','cloners','externalsyllabus',                                   'rolenames'],
                                  'url','rolenames'],  
                      itemtext => {                       itemtext => {
                                    owner            => $lt{'ownr'},                                     'owner'            => $lt{'ownr'},
                                    description      => $lt{'desc'},                                     'co-owners'        => $lt{'cown'},
                                    courseid         => $lt{'idnu'},                                     'description'      => $lt{'desc'},
                                    categories       => $lt{'catg'},                                     'courseid'         => $lt{'idnu'},
                                    hidefromcat      => $lt{'excc'},                                     'uniquecode'       => $lt{'unco'}, 
                                    cloners          => $lt{'clon'},                                      'categories'       => $lt{'catg'},
                                    externalsyllabus => 'URL of Syllabus',                                     'hidefromcat'      => $lt{'excc'},
                                    url              => 'Top Level Map',                                     'cloners'          => $lt{'clon'}, 
                                    rolenames        => $lt{'rept'},                                     'externalsyllabus' => 'Syllabus status',
                                      'url'              => 'Top Level Map',
                                      'rolenames'        => $lt{'rept'},
                                      'loncaparev'       => $lt{'lcrv'},
                                      'clonedfrom'       => 'Cloned from',
                                  },                                   },
                     },                      },
         'localization' =>          'localization' =>
                     { text => 'Language/TimeZone/Locale',                      { text => 'Language and time localization',
                       help => 'Course_Environment',                        help => 'Course_Prefs_Language',
                       header => [{col1 => 'Setting',  
                                   col2 => 'Value',}],  
                       ordered => ['languages','timezone','datelocale'],                        ordered => ['languages','timezone','datelocale'],
                       itemtext => {                        itemtext => {
                                     languages  => 'Languages used',                                      languages  => 'Languages used',
Line 373  sub handler { Line 405  sub handler {
                     },                      },
         'feedback' =>          'feedback' =>
                     { text => 'Feedback messages',                      { text => 'Feedback messages',
                       help => 'Course_Environment',                        help => 'Course_Prefs_Feedback',
                       header => [{col1 => 'Questions about:',                        header => [{col1 => 'Questions about:',
                                   col2 => 'Recipients'},                                    col2 => 'Recipients'}],
                                  {col1 => 'Questions about:',  
                                   col2 => 'Custom Text'}],  
                       ordered => ['question.email','comment.email','policy.email'],                        ordered => ['question.email','comment.email','policy.email'],
                       itemtext => {                        itemtext => {
                                      'question.email' => 'Resource Content',                                       'question.email' => 'Resource Content',
Line 387  sub handler { Line 417  sub handler {
                     },                      },
         'discussion' =>          'discussion' =>
                     { text => 'Discussion and Chat',                      { text => 'Discussion and Chat',
                       help => 'Course_Environment',                        help => 'Course_Prefs_Discussions',
                       header => [{col1 => 'Setting',                        ordered => ['pch.roles.denied','pch.users.denied',
                                   col2 => 'Value',}],                                    'plc.roles.denied','plc.users.denied',
                       ordered => ['plc.roles.denied','plc.users.denied',  
                                   'pch.roles.denied','pch.users.denied',  
                                   'allow_limited_html_in_feedback',                                    'allow_limited_html_in_feedback',
                                   'allow_discussion_post_editing'],                                    'allow_discussion_post_editing',
                                     'discussion_post_fonts'],
                       itemtext => {                        itemtext => {
                          'plc.roles.denied'             => 'No Resource Discussion',                           'pch.roles.denied'             => 'No Resource Discussion',
                          'plc.users.denied'             => 'No Resource Discussion',                           'pch.users.denied'             => 'No Resource Discussion',
                          'pch.roles.denied'             => 'No Chat room use',                           'plc.roles.denied'             => 'No Chat room use',
                          'pch.users.denied'             => 'No Chat room use',                           'plc.users.denied'             => 'No Chat room use',
                          allow_limited_html_in_feedback => 'Allow limited HTML in discussion posts',                           allow_limited_html_in_feedback => 'Allow limited HTML in discussion',
                          allow_discussion_post_editing  => 'Users can edit/delete own discussion posts',                           allow_discussion_post_editing  => 'Users can edit/delete own discussion posts',
                            discussion_post_fonts       => 'Discussion post fonts based on likes/unlikes',
                                   },                                    },
                     },                      },
         'classlists' =>          'classlists' =>
                    { text => $lt{'clas'},                     { text => $lt{'clas'},
                      help => 'Course_Environment',                       help => 'Course_Prefs_Classlists',
                      header => [{col1 => 'Type',                       header => [{col1 => 'Type',
                                  col2 => $lt{'defd'}},                                   col2 => $lt{'defd'}},
                                 {col1 => 'Setting',                                  {col1 => 'Setting',
Line 414  sub handler { Line 444  sub handler {
                                  col2 => $lt{'stuv'}}],                                   col2 => $lt{'stuv'}}],
                      ordered => ['default_enrollment_start_date',                       ordered => ['default_enrollment_start_date',
                                  'default_enrollment_end_date',                                   'default_enrollment_end_date',
                                  'nothideprivileged','student_classlist_view',                                   'defaultcredits',
                                  'student_opt_in','student_classlist_portfiles'],                                   'nothideprivileged','checkforpriv',
                                    'student_classlist_view',
                                    'student_classlist_opt_in','student_classlist_portfiles'],
                      itemtext => {                       itemtext => {
                          default_enrollment_start_date => 'Start date',                           default_enrollment_start_date => 'Start date',
                          default_enrollment_end_date   => 'End date',                           default_enrollment_end_date   => 'End date',
                          nothideprivileged             => $lt{'priv'},                           nothideprivileged             => $lt{'prus'},
                            checkforpriv                  => $lt{'prdo'},
                          student_classlist_view        => $lt{'stuv'},                           student_classlist_view        => $lt{'stuv'},
                          student_opt_in                => $lt{'stul'},                           student_classlist_opt_in      => $lt{'stul'},
                          student_classlist_portfiles   => 'Include link to accessible portfolio files',                           student_classlist_portfiles   => 'Include link to accessible portfolio files',
                            defaultcredits                => $lt{'cred'},
                                   },                                    },
                    },                     },
         'appearance' =>          'appearance' =>
                    { text => 'Display of resources ',                     { text => 'Display of resources ',
                      help => 'Course_Environment',                       help => 'Course_Prefs_Display',
                      header => [{col1 => 'Setting',  
                                  col2 => 'Value'}],  
                      ordered => ['default_xml_style','pageseparators',                       ordered => ['default_xml_style','pageseparators',
                                  'disable_receipt_display','texengine',                                   'disable_receipt_display','texengine',
                                  'tthoptions'],                                   'tthoptions','uselcmath','usejsme'],
                       itemtext => {                        itemtext => {
                           default_xml_style       => 'Default XML Style File',                            default_xml_style       => 'Default XML style file',
                           pageseparators          => 'Visibly Separate Items on Pages',                            pageseparators          => 'Visibly Separate Items on Pages',
                           disable_receipt_display => 'Disable display of problem receipts',                            disable_receipt_display => 'Disable display of problem receipts',
                           texengine               => 'Force use of a specific math rendering engine',                            texengine               => 'Force use of a specific math rendering engine',
                           tthoptions              => 'Default set of options to pass to tth/m when converting TeX',                            tthoptions              => 'Default set of options to pass to tth/m when converting TeX',
                             uselcmath               => 'Student formula entry uses inline preview, not DragMath pop-up',
                             usejsme                 => 'Molecule editor uses JSME (HTML5) in place of JME (Java)',
                                   },                                    },
                   },                    },
         'grading' =>          'grading' =>
                   { text => 'Grading',                    { text => 'Grading',
                     help => 'Course_Environment',                      help => 'Course_Prefs_Grading',
                     header => [{col1 => 'Setting',  
                                 col2 => 'Value',}],  
                     ordered => ['grading','rndseed',                      ordered => ['grading','rndseed',
                                 'receiptalg','disablesigfigs'],                                  'receiptalg','disablesigfigs'],
                     itemtext => {                      itemtext => {
Line 458  sub handler { Line 490  sub handler {
                   },                    },
         'printouts' =>          'printouts' =>
                   { text => 'Printout generation',                    { text => 'Printout generation',
                     help => 'Course_Environment',                      help => 'Course_Prefs_Printouts',
                     header => [{col1 => 'Setting',  
                                 col2 => 'Value',}],  
                     ordered => ['problem_stream_switch','suppress_tries',                      ordered => ['problem_stream_switch','suppress_tries',
                                 'default_paper_size','print_header_format',                                  'default_paper_size','print_header_format',
                                 'disableexampointprint'],                                  'disableexampointprint'],
Line 469  sub handler { Line 499  sub handler {
                         suppress_tries        => 'Suppress number of tries in printing',                          suppress_tries        => 'Suppress number of tries in printing',
                         default_paper_size    => 'Default paper type',                          default_paper_size    => 'Default paper type',
                         print_header_format   => 'Print header format',                          print_header_format   => 'Print header format',
                         disableexampointprint => 'Disable automatically printing point values on exams',                          disableexampointprint => 'Disable automatically printing point values on bubblesheet exams',
                           canuse_pdfforms    => 'Users can print problems as PDF forms and upload later for grading',
                                 },                                  },
                   },                    },
         'spreadsheet' =>          'spreadsheet' =>
                   { text => 'Spreadsheets',                    { text => 'Spreadsheets',
                     help => 'Course_Environment',                      help => 'Course_Prefs_Spreadsheet',
                     header => [{col1 => 'Setting',  
                                 col2 => 'Value'}],  
                     ordered => ['spreadsheet_default_classcalc',                      ordered => ['spreadsheet_default_classcalc',
                                 'spreadsheet_default_studentcalc',                                  'spreadsheet_default_studentcalc',
                                 'spreadsheet_default_assesscalc','hideemptyrows'],                                  'spreadsheet_default_assesscalc','hideemptyrows'],
Line 489  sub handler { Line 518  sub handler {
                   },                    },
         'bridgetasks' =>          'bridgetasks' =>
                   { text => 'Bridge tasks',                    { text => 'Bridge tasks',
                     help => 'Course_Environment',                      help => 'Course_Prefs_Bridgetasks',
                     header => [{col1 => 'Setting',  
                                 col2 => 'Value'}],  
                     ordered => ['task_messages','task_grading',                      ordered => ['task_messages','task_grading',
                                 'suppress_embed_prompt'],                                  'suppress_embed_prompt'],
                     itemtext => {                      itemtext => {
Line 502  sub handler { Line 529  sub handler {
                   },                    },
         'other' =>          'other' =>
                   { text => 'Other settings',                    { text => 'Other settings',
                     help => 'Course_Environment',                      help => 'Course_Prefs_Other',
                     header => [ {col1 => 'Item',                      header => [ {col1 => 'Item',
                                  col2 => 'Value',                                   col2 => 'Value',
                               }],                                }],
Line 512  sub handler { Line 539  sub handler {
         my @allitems = &get_allitems(%prefs);          my @allitems = &get_allitems(%prefs);
         &Apache::lonconfigsettings::make_changes($r,$cdom,$phase,$context,          &Apache::lonconfigsettings::make_changes($r,$cdom,$phase,$context,
                                                  \@prefs_order,\%prefs,\%values,                                                   \@prefs_order,\%prefs,\%values,
                                                   $cnum,undef,\@allitems);                                                    $cnum,undef,\@allitems,'coursepref');
     } elsif ($phase eq 'display') {      } elsif ($phase eq 'display') {
         my $jscript = &get_jscript($cdom,$phase,$crstype);          my $jscript = &get_jscript($cid,$cdom,$phase,$crstype,\%values);
         my @allitems = &get_allitems(%prefs);          my @allitems = &get_allitems(%prefs);
         &Apache::lonconfigsettings::display_settings($r,$cdom,$phase,$context,          &Apache::lonconfigsettings::display_settings($r,$cdom,$phase,$context,
             \@prefs_order,\%prefs,\%values,undef,$jscript,\@allitems,$crstype);              \@prefs_order,\%prefs,\%values,undef,$jscript,\@allitems,$crstype,'coursepref');
     } else {      } else {
         &Apache::lonconfigsettings::display_choices($r,$phase,$context,          &Apache::lonconfigsettings::display_choices($r,$phase,$context,
                                                     \@prefs_order,\%prefs);                                                      \@prefs_order,\%prefs,'coursepref');
     }      }
     return OK;      return OK;
 }  }
Line 549  sub print_config_box { Line 576  sub print_config_box {
     my $output =      my $output =
          '<table class="LC_nested_outer">           '<table class="LC_nested_outer">
           <tr>            <tr>
            <th align="left" valign="middle"><span class="LC_font_larger">'.             <th align="left" valign="middle"><span class="LC_nobreak" style="font-size: larger;" >'.
            &mt($item->{text}).'&nbsp;'.             &mt($item->{text});
            &Apache::loncommon::help_open_topic($item->{'help'}).'</span></th>'."\n".      if ($item->{'help'}) {
           '</tr>';          $output .= '&nbsp;'.
                      &Apache::loncommon::help_open_topic($item->{'help'});
       }
       $output .= '</span></th>'."\n".
                  '</tr>';
     if (($action eq 'feedback') || ($action eq 'classlists')) {      if (($action eq 'feedback') || ($action eq 'classlists')) {
         $output .= '          $output .= '
           <tr>            <tr>
            <td>             <td>
             <table class="LC_nested">              <table class="LC_nested">';   
              <tr class="LC_info_row">          if (exists $item->{'header'}->[0]->{'col1'} || 
               <td class="LC_left_item">'.&mt($item->{'header'}->[0]->{'col1'}).'</td>              exists $item->{'header'}->[0]->{'col2'}) {
               <td class="LC_right_item">'.&mt($item->{'header'}->[0]->{'col2'}).'</td>   $output .= '          
              </tr>';            <tr class="LC_info_row">
                 <td class="LC_left_item">'.&mt($item->{'header'}->[0]->{'col1'}).'</td>';
               if ($action eq 'feedback') {
                   $output .= '
                     <td class="LC_right_item" colspan="2">';
               } else {
                   $output .= '
                     <td class="LC_right_item">';
               }
               $output .= &mt($item->{'header'}->[0]->{'col2'}).'</td>
               </tr>';
           }
         $rowtotal ++;          $rowtotal ++;
         if ($action eq 'feedback') {          if ($action eq 'feedback') {
             $output .= &print_feedback('top',$cdom,$settings,$ordered,$itemtext,\$rowtotal);              $output .= &print_feedback('top',$cdom,$settings,$ordered,$itemtext,\$rowtotal);
Line 573  sub print_config_box { Line 615  sub print_config_box {
           </td>            </td>
          </tr>           </tr>
          <tr>           <tr>
            <td>            <td>
             <table class="LC_nested">              <table class="LC_nested">
              <tr class="LC_info_row">               <tr class="LC_info_row">
               <td class="LC_left_item">'.&mt($item->{'header'}->[1]->{'col1'}).'</td>';                <td class="LC_left_item">'.&mt($item->{'header'}->[1]->{'col1'}).'</td>';
         $output .= '          if ($action eq 'classlists') {
               <td class="LC_right_item">'.&mt($item->{'header'}->[1]->{'col2'}).'</td>              $output .= '
                 <td class="LC_right_item" colspan="2">';
           } else {
               $output .= '
                 <td class="LC_right_item">';
           }
           $output .= &mt($item->{'header'}->[1]->{'col2'}).'</td>
              </tr>';               </tr>';
         if ($action eq 'classlists') {          if ($action eq 'classlists') {
             $output .= &print_classlists('middle',$cdom,$settings,$itemtext,\$rowtotal,$crstype).              $output .= &print_classlists('middle',$cdom,$settings,$itemtext,\$rowtotal,$crstype).
Line 588  sub print_config_box { Line 636  sub print_config_box {
           </tr>            </tr>
           <tr>            <tr>
            <td>             <td>
             <table class="LC_nested">              <table class="LC_nested">';
              <tr class="LC_info_row">              if (exists $item->{'header'}->[2]->{'col1'} || 
               <td class="LC_left_item" valign="top">'.&mt($item->{'header'}->[2]->{'col1'}).'</td>              exists $item->{'header'}->[2]->{'col2'}) {
               <td class="LC_right_item" valign="top">'.&mt($item->{'header'}->[2]->{'col2'}).'</td>   $output .= '          
              </tr>';   <tr class="LC_info_row">
     <td class="LC_left_item">'.&mt($item->{'header'}->[2]->{'col1'}).'</td>
     <td class="LC_right_item">'.&mt($item->{'header'}->[2]->{'col2'}).'</td>
    </tr>';
           }
         }          }
     } else {      } else {
         $output .= '          $output .= '
           <tr>            <tr>
            <td>             <td>
             <table class="LC_nested">              <table class="LC_nested">';
              <tr class="LC_info_row">          if (exists $item->{'header'}->[0]->{'col1'} || 
               <td class="LC_left_item" valign="top">'.&mt($item->{'header'}->[0]->{'col1'}).'</td>              exists $item->{'header'}->[0]->{'col2'}) {
               <td class="LC_right_item" valign="top">'.&mt($item->{'header'}->[0]->{'col2'}).'</td>   $output .= '          
              </tr>';            <tr class="LC_info_row">
                 <td class="LC_left_item" valign="top">'.&mt($item->{'header'}->[0]->{'col1'}).'</td>';
               if (($action eq 'courseinfo') || ($action eq 'localization') ||
                   ($action eq 'print_discussion')) {
                   $output .= '<td class="LC_right_item" valign="top" colspan="2">';
               } else {
                   $output .= '<td class="LC_right_item" valign="top">';
               }
               $output .= &mt($item->{'header'}->[0]->{'col2'}).'</td>
               </tr>';
           }
     }      }
     $rowtotal ++;      $rowtotal ++;
     if ($action eq 'courseinfo') {      if ($action eq 'courseinfo') {
Line 613  sub print_config_box { Line 675  sub print_config_box {
         $output .= &print_feedback('bottom',$cdom,$settings,$ordered,$itemtext,\$rowtotal);          $output .= &print_feedback('bottom',$cdom,$settings,$ordered,$itemtext,\$rowtotal);
     } elsif ($action eq 'discussion') {      } elsif ($action eq 'discussion') {
         $output .= &print_discussion($cdom,$settings,$ordered,$itemtext,\$rowtotal);          $output .= &print_discussion($cdom,$settings,$ordered,$itemtext,\$rowtotal);
     } elsif ($action eq 'classlists') {      } elsif (($action eq 'classlists') || ($action eq 'viewableroster')) {
         $output .= &print_classlists('bottom',$cdom,$settings,$itemtext,\$rowtotal,$crstype);          $output .= &print_classlists('bottom',$cdom,$settings,$itemtext,\$rowtotal,$crstype);
     } elsif ($action eq 'appearance') {      } elsif ($action eq 'appearance') {
         $output .= &print_appearance($cdom,$settings,$ordered,$itemtext,\$rowtotal,$crstype);          $output .= &print_appearance($cdom,$settings,$ordered,$itemtext,\$rowtotal,$crstype);
Line 656  sub process_changes { Line 718  sub process_changes {
                     }                      }
                 }                  }
             } elsif (ref($item->{'ordered'}) eq 'ARRAY') {              } elsif (ref($item->{'ordered'}) eq 'ARRAY') {
                 @ordered = @{$item->{'ordered'}};                  if ($action eq 'courseinfo') {
                       my ($can_toggle_cat,$can_categorize) =
                           &can_modify_catsettings($cdom,$crstype);
                       foreach my $entry (@{$item->{'ordered'}}) {
                           next if (($entry eq 'hidefromcat') &&
                                    (!$can_toggle_cat));
                           next if (($entry eq 'categories') &&
                                    (!$can_categorize));
                           next if (($entry eq 'loncaparev') || 
                                   ($entry eq 'owner') ||
                                   ($entry eq 'clonedfrom'));
                           push(@ordered,$entry);
                       }
                   } elsif ($action eq 'classlists') {
                       foreach my $entry (@{$item->{'ordered'}}) {
                           next if ($entry eq 'defaultcredits');
                           push(@ordered,$entry);
                       }
                   } else {
                       @ordered = @{$item->{'ordered'}};
                   }
             }              }
             if (@ordered > 0) {              if (@ordered > 0) {
                 if ($action eq 'feedback') {                  if ($action eq 'feedback') {
Line 705  sub process_changes { Line 787  sub process_changes {
                                 my @clonedoms;                                  my @clonedoms;
                                 if (exists($env{'form.cloners_activate'})) {                                  if (exists($env{'form.cloners_activate'})) {
                                     my $actnum = $env{'form.cloners_activate'};                                      my $actnum = $env{'form.cloners_activate'};
                                     if ($actnum ne '') {                                      if ($actnum ne '-1') {
                                         if ($env{'form.clonersdom_'.$actnum} ne '') {                                          if ($env{'form.cloners_dom_'.$actnum} ne '') {
                                             my $clonedom = $env{'form.clonersdom_'.$actnum};                                              my $clonedom = $env{'form.cloners_dom_'.$actnum};
                                             if (&check_clone($clonedom,$disallowed) eq 'ok') {                                              if (&check_clone($clonedom,$disallowed) eq 'ok') {
                                                 $newvalues{$entry} = '*:'.$clonedom;                                                  $newvalues{$entry} = '*:'.$clonedom;
                                                 push(@clonedoms,$newvalues{$entry});                                                  push(@clonedoms,$newvalues{$entry});
Line 723  sub process_changes { Line 805  sub process_changes {
                                             my $clonedom = $env{'form.cloners_dom_'.$i};                                              my $clonedom = $env{'form.cloners_dom_'.$i};
                                             if (&check_clone($clonedom,$disallowed) eq 'ok') {                                              if (&check_clone($clonedom,$disallowed) eq 'ok') {
                                                 if (!grep(/^\*:\Q$clonedom\E$/,@clonedoms)) {                                                  if (!grep(/^\*:\Q$clonedom\E$/,@clonedoms)) {
                                                     push (@clonedoms,'*:'.$clonedom);                                                      push(@clonedoms,'*:'.$clonedom);
                                                 }                                                  }
                                             }                                              }
                                         }                                          }
Line 769  sub process_changes { Line 851  sub process_changes {
                                         }                                          }
                                     }                                      }
                                 }                                  }
                                   if (ref($values) eq 'HASH') {
                                       my (@code_order,%codedefaults);
                                       &Apache::lonnet::auto_instcode_defaults($cdom,\%codedefaults,
                                                                               \@code_order);
                                       my $clonebycode;
                                       if ($env{'form.cloners_instcode'}) {
                                           if (@code_order > 0) {
                                               my @standardnames = &Apache::loncommon::get_standard_codeitems();
                                               my %local_to_standard;
                                               for (my $i=0; $i<@code_order; $i++) {
                                                   $local_to_standard{$code_order[$i]} = $standardnames[$i];
                                               }
                                               foreach my $item (@code_order) {
                                                   my $key = $local_to_standard{$item};
                                                   if ($key ne '') {
                                                       if ($env{'form.'.$key}) {
                                                           $clonebycode .= $key.'='.&escape($env{'form.'.$key}).'&';
                                                       }
                                                   }
                                               }
                                               $clonebycode =~ s/\&$//;
                                           }
                                       }
                                       if ($clonebycode) {
                                           if ($newvalues{$entry}) {
                                               $newvalues{$entry} .= ','.$clonebycode;
                                           } else {
                                               $newvalues{$entry} = $clonebycode;
                                           }
                                       }
                                   }
                             }                              }
                             if (ref($disallowed) eq 'HASH') {                              if (ref($disallowed) eq 'HASH') {
                                 if (ref($disallowed->{'cloners'}) eq 'HASH') {                                  if (ref($disallowed->{'cloners'}) eq 'HASH') {
Line 777  sub process_changes { Line 890  sub process_changes {
                                     }                                      }
                                 }                                  }
                             }                              }
                           } elsif ($entry eq 'co-owners') {
                               my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                               my $coowners = $values->{'internal.co-owners'};
                               my @currcoown;
                               if ($coowners) {
                                   @currcoown = split(',',$coowners);
                               }
                               if (&Apache::lonnet::is_course_owner($cdom,$cnum)) {
                                   my $autocoowner;
                                   if (($crstype eq 'Course') && 
                                       ($values->{'internal.coursecode'})) {
                                       my %domconf =
                                           &Apache::lonnet::get_dom('configuration',['autoenroll'],$cdom);
                                       if (ref($domconf{'autoenroll'}) eq 'HASH') {
                                           $autocoowner = $domconf{'autoenroll'}{'co-owners'};
                                       }
                                   }
                                   unless ($autocoowner) {
                                       my @keepcoowners = &Apache::loncommon::get_env_multiple('form.coowners');
                                       my @pendingcoowners = &Apache::loncommon::get_env_multiple('form.pendingcoowners');
                                       my @invitecoowners =  &Apache::loncommon::get_env_multiple('form.invitecoowners');
                                       if (@invitecoowners) {
                                           push(@pendingcoowners,@invitecoowners);
                                       }
                                       $newvalues{'pendingco-owners'} = join(',',sort(@pendingcoowners));
                                       $newvalues{'co-owners'} = join(',',sort(@keepcoowners));
                                       if ($newvalues{'co-owners'} ne $values->{'internal.co-owners'}) {
                                           $changes->{$entry}{'co-owners'} = $newvalues{'co-owners'};
                                           push(@{$changes->{$entry}{'changed'}},'co-owners');
                                       }
                                       if ($newvalues{'pendingco-owners'} ne $values->{'internal.pendingco-owners'}) {
                                           $changes->{$entry}{'pendingco-owners'} = $newvalues{'pendingco-owners'};
                                           push(@{$changes->{$entry}{'changed'}},'pendingco-owners');
                                       }
                                   }
                               } else {
                                   my (@newpending,@newcoown);
                                   my $uname = $env{'user.name'};
                                   my $udom = $env{'user.domain'};
                                   my $pendingcoowners = $values->{'internal.pendingco-owners'};
                                   my @pendingcoown = split(',',$pendingcoowners);
                                   if ($env{'form.pending_coowoner'}) {
                                       foreach my $item (@pendingcoown) {
                                           unless ($item eq $uname.':'.$udom) {
                                               push(@newpending,$item);
                                           }
                                       }
                                       @newcoown = @currcoown;
                                       if ($env{'form.pending_coowoner'} eq 'accept') {
                                           unless (grep(/^\Q$uname\E:\Q$udom\E$/,@currcoown)) {
                                               push(@newcoown,$uname.':'.$udom);
                                           }
                                       }
                                   } elsif ($env{'form.remove_coowoner'}) {
                                       foreach my $item (@currcoown) {
                                           unless ($item eq $uname.':'.$udom) {
                                               push(@newcoown,$item);
                                           }
                                       }
                                       if ($pendingcoowners ne '') {
                                           @newpending = @pendingcoown;
                                       }
                                   }
                                   $newvalues{'pendingco-owners'} = join(',',sort(@newpending));
                                   $newvalues{'co-owners'} = join(',',sort(@newcoown));
                                   if ($newvalues{'co-owners'} ne $values->{'internal.co-owners'}) {
                                       $changes->{$entry}{'co-owners'} = $newvalues{'co-owners'};
                                       push(@{$changes->{$entry}{'changed'}},'co-owners');
                                   }
                                   if ($newvalues{'pendingco-owners'} ne $values->{'internal.pendingco-owners'}) {
                                       $changes->{$entry}{'pendingco-owners'} = $newvalues{'pendingco-owners'};
                                       push(@{$changes->{$entry}{'changed'}},'pendingco-owners');
                                   }
                               }
                         } elsif ($entry =~ /^default_enrollment_(start|end)_date$/) {                          } elsif ($entry =~ /^default_enrollment_(start|end)_date$/) {
                             $newvalues{$entry}=&Apache::lonhtmlcommon::get_date_from_form($entry);                              $newvalues{$entry}=&Apache::lonhtmlcommon::get_date_from_form($entry);
                         } elsif ($entry eq 'rolenames') {                          } elsif ($entry eq 'rolenames') {
Line 890  sub process_changes { Line 1077  sub process_changes {
                                 }                                  }
                             }                              }
                             $newvalues{$entry} =~ s/,$//;                              $newvalues{$entry} =~ s/,$//;
                           } elsif ($entry eq 'discussion_post_fonts') {
                               my ($classorder,$classtitles) = &discussion_vote_classes();
                               my $fontchange = 0;
                               foreach my $class (@{$classorder}) {
                                   my $ext_entry = $entry.'_'.$class;
                                   my $size = $env{'form.'.$ext_entry.'_size'};
                                   my $unit = $env{'form.'.$ext_entry.'_unit'};
                                   my $weight = $env{'form.'.$ext_entry.'_weight'};
                                   my $style = $env{'form.'.$ext_entry.'_style'};
                                   my $other = $env{'form.'.$ext_entry.'_other'};
                                   $size =~ s/,//g;
                                   $unit =~ s/,//g;
                                   $weight =~ s/,//g;
                                   $style =~ s/,//g;
                                   $other =~ s/[^\w;:\s\-\%.]//g;
                                   $other =~ s/(^\s+|\s+$)//g;
                                   $newvalues{$ext_entry} = join(',',($size.$unit,$weight,$style,$other));
                                   my $current = $values->{$ext_entry};
                                   if ($values->{$ext_entry} eq '') {
                                       $current = ',,,';
                                   }
                                   if ($newvalues{$ext_entry} ne $current) {
                                       $changes->{$ext_entry} = $newvalues{$ext_entry};
                                       $fontchange ++;
                                   }
                               }
                               if ($fontchange) {
                                   $changes->{$entry} = 1;
                               }
                         } elsif ($entry eq 'nothideprivileged') {                          } elsif ($entry eq 'nothideprivileged') {
                             my @curr_nothide;                              my @curr_nothide;
                             my @new_nothide;                              my @new_nothide;
Line 945  sub process_changes { Line 1161  sub process_changes {
                                                 $hdr .= $env{'form.printfmthdr_limit_'.$i};                                                  $hdr .= $env{'form.printfmthdr_limit_'.$i};
                                             }                                              }
                                             $hdr .= $env{'form.printfmthdr_sub_'.$i};                                              $hdr .= $env{'form.printfmthdr_sub_'.$i};
                                         } elsif ($env{'form.printfmthdr_sub_'.$i} ne '') {                                          } elsif ($env{'form.printfmthdr_text_'.$i} ne '') {
                                             $hdr = $env{'form.printfmthdr_sub_'.$i};                                              $hdr = $env{'form.printfmthdr_text_'.$i};
                                         }                                          }
                                         $newhdr[$env{'form.printfmthdr_pos_'.$i}] = $hdr;                                          $newhdr[$env{'form.printfmthdr_pos_'.$i}] = $hdr;
                                     }                                      }
Line 964  sub process_changes { Line 1180  sub process_changes {
                             my $newtext = $maxnum-1;                              my $newtext = $maxnum-1;
                             $newhdr[$env{'form.printfmthdr_pos_'.$newtext}] = $env{'form.printfmthdr_text_'.$newtext};                              $newhdr[$env{'form.printfmthdr_pos_'.$newtext}] = $env{'form.printfmthdr_text_'.$newtext};
                             $newvalues{$entry} = join('',@newhdr);                              $newvalues{$entry} = join('',@newhdr);
                         } elsif ($entry eq 'languages') {                          } elsif (($entry eq 'languages') ||
                             my $langstr;                                   ($entry eq 'checkforpriv')) {
                               my $settings;
                             my $total = $env{'form.'.$entry.'_total'};                              my $total = $env{'form.'.$entry.'_total'};
                             if ($total) {                              if ($total) {
                                 my @deletes = &Apache::loncommon::get_env_multiple('form.'.$entry.'_delete');                                  my @deletes = &Apache::loncommon::get_env_multiple('form.'.$entry.'_delete');
                                 for (my $i=0; $i<$total; $i++) {                                  for (my $i=0; $i<$total; $i++) {
                                     unless (grep(/^$i$/,@deletes)) {                                      unless (grep(/^$i$/,@deletes)) {
                                        $langstr .= $env{'form.'.$entry.'_'.$i}.',';                                          $settings .= $env{'form.'.$entry.'_'.$i}.',';
                                     }                                      }
                                 }                                  }
                             } else {                              } else {
                                 $total = 0;                                  $total = 0;
                             }                              }
                             if ($env{'form.'.$entry.'_'.$total} ne '') {                              if ($env{'form.'.$entry.'_'.$total} ne '') {
                                 my $newlang = $env{'form.'.$entry.'_'.$total};                                  my $new = $env{'form.'.$entry.'_'.$total};
                                 my %langchoices = &get_lang_choices();                                  if ($entry eq 'languages') {
                                 if ($langchoices{$newlang}) {                                      my %langchoices = &get_lang_choices();
                                     $langstr .= $newlang;                                      if ($langchoices{$new}) {
                                           $settings .= $new;
                                       } else {
                                           $settings =~ s/,$//;
                                           $disallowed->{'localization'}{$entry} = $new;
                                       }
                                 } else {                                  } else {
                                     $langstr =~ s/,$//;                                      my %domains=map { $_ => 1; } &Apache::lonnet::all_domains();
                                     $disallowed->{'localization'}{$entry} = $newlang;                                      if ($domains{$new}) {
                                           $settings .= $new;
                                       } else {
                                           $settings =~ s/,$//;
                                           $disallowed->{'classlists'}{$entry} = $new;
                                       }
                                 }                                  }
                             } else {                              } else {
                                 $langstr =~ s/,$//;                                  $settings =~ s/,$//;
                             }                              }
                             $newvalues{$entry} = $langstr;                              $newvalues{$entry} = $settings;
                         } else {                          } else {
                             $newvalues{$entry} = $env{'form.'.$entry};                              $newvalues{$entry} = $env{'form.'.$entry};
                         }                          }
                         if ($newvalues{$entry} ne $values->{$entry}) {                          unless (($entry eq 'co-owners') || ($entry eq 'discussion_post_fonts')) {
                             $changes->{$entry} = $newvalues{$entry};                              if ($newvalues{$entry} ne $values->{$entry}) {
                                   $changes->{$entry} = $newvalues{$entry};
                               }
                         }                          }
                     }                      }
                 }                  }
Line 1070  sub store_changes { Line 1299  sub store_changes {
             $output .= '<h3>'.&mt($prefs->{$item}{'text'}).'</h3>';              $output .= '<h3>'.&mt($prefs->{$item}{'text'}).'</h3>';
             if (ref($changes->{$item}) eq 'HASH') {              if (ref($changes->{$item}) eq 'HASH') {
                 if (keys(%{$changes->{$item}}) > 0) {                  if (keys(%{$changes->{$item}}) > 0) {
                     $output .= &mt('Changes made:').'<ul>';                      $output .= &mt('Changes made:').'<ul style="list-style:none;">';
                     if ($item eq 'other') {                      if ($item eq 'other') {
                         foreach my $key (sort(keys(%{$changes->{$item}}))) {                          foreach my $key (sort(keys(%{$changes->{$item}}))) {
                             $storehash{$key} = $changes->{$item}{$key};                              $storehash{$key} = $changes->{$item}{$key};
                             if ($changes->{$item}{$key} eq '') {                              if ($changes->{$item}{$key} eq '') {
                                 push(@delkeys,$key);                                  push(@delkeys,$key);
                                 $output .= '<li>'.&mt('Deleted setting for [_1]','<i>'.$key.'</i>').'</li>';                                  $output .= '<li>'.&Apache::lonhtmlcommon::confirm_success(&mt('Deleted setting for [_1]','<i>'.$key.'</i>')).'</li>';
                             } else {                              } else {
                                 $output .= '<li>'.&mt('[_1] set to [_2]','<i>'.$key.'</i>',                                  $output .= '<li>'.&Apache::lonhtmlcommon::confirm_success(&mt('[_1] set to [_2]','<i>'.$key.'</i>',
                                            "'$storehash{$key}'").'</li>';                                             "'$storehash{$key}'")).'</li>';
                             }                              }
                         }                          }
                     } else {                      } else {
Line 1111  sub store_changes { Line 1340  sub store_changes {
                                                 "'<b>".$newname."</b>'").'</li>';                                                  "'<b>".$newname."</b>'").'</li>';
                                     }                                      }
                                     if ($msg ne '') {                                      if ($msg ne '') {
                                         $output .= '<li>'.&mt($displayname).'<ul>'.$msg.'</ul></li>';                                          $output .= '<li>'.&Apache::lonhtmlcommon::confirm_success(&mt($displayname)).'<ul class="LC_success">'.$msg.'</ul></li>';
                                     }                                      }
                                 } else {                                  } else {
                                     next if (!exists($changes->{$item}{$key}));                                      next if (!exists($changes->{$item}{$key}));
                                     my ($displayname,$text);                                      my ($displayname,$text);
                                     $text = $prefs->{$item}->{'itemtext'}{$key};                                      $text = $prefs->{$item}->{'itemtext'}{$key};
                                     my $displayval = $changes->{$item}{$key};                                      my $displayval;
                                       unless (($key eq 'co-owners') || ($key eq 'discussion_post_fonts')) {
                                           $displayval = $changes->{$item}{$key};
                                       }
                                     if ($item eq 'feedback') {                                      if ($item eq 'feedback') {
                                         if ($key =~ /^(question|policy|comment)(\.email)\.text$/) {                                          if ($key =~ /^(question|policy|comment)(\.email)\.text$/) {
                                             $text = $prefs->{$item}->{'itemtext'}{$1.$2};                                              $text = $prefs->{$item}->{'itemtext'}{$1.$2};
Line 1151  sub store_changes { Line 1383  sub store_changes {
                                                     }                                                      }
                                                     $displayval = join(', ',@longroles);                                                      $displayval = join(', ',@longroles);
                                                 }                                                  }
                                               } elsif ($key eq 'discussion_post_fonts') {
                                                   my ($classorder,$classtitles)=&discussion_vote_classes();
                                                   my ($styleorder,$styleitems)=&discussion_vote_styles();
                                                   my $count = 1;
                                                   my $total = scalar(keys(%{$changes->{$item}}));
                                                   foreach my $class (@{$classorder}) {
                                                       $count ++;
                                                       next unless ($changes->{$item}{$key.'_'.$class});
                                                       my @vals = split(/,/,$changes->{$item}{$key.'_'.$class});
                                                       my $showval = '';
                                                       for (my $i=0; $i<@{$styleorder}; $i++) {
                                                           if ($vals[$i] ne '') {
                                                               $showval .= 'font-'.$styleorder->[$i].': '.$vals[$i].'; ';
                                                           }
                                                       }
                                                       if ($vals[3] ne '') {
                                                           $showval .= $vals[3];
                                                       }
                                                       if ($showval ne '') {
                                                           $displayval .= $classtitles->{$class}.':{ '.
                                                                          $showval.'}';
                                                           $storehash{$key.'_'.$class} = $changes->{$item}{$key.'_'.$class};
                                                       } else {
                                                           $displayval .= $classtitles->{$class}.': '.&mt('None');
                                                           push(@delkeys,$key.'_'.$class);
                                                       }
                                                       unless ($count == $total) {
                                                           $displayval .= ('&nbsp;'x2);
                                                       }
                                                   }
                                             }                                              }
                                             $displayname = &mt($text);                                              $displayname = &mt($text);
                                         }                                          }
Line 1171  sub store_changes { Line 1433  sub store_changes {
                                     if (defined($yesno{$key})) {                                      if (defined($yesno{$key})) {
                                         $displayval = &mt('No');                                          $displayval = &mt('No');
                                         if ($changes->{$item}{$key} eq 'yes') {                                          if ($changes->{$item}{$key} eq 'yes') {
                                             $displayval = &mt('Yes');                                                       $displayval = &mt('Yes');                          
                                         }                                          }
                                     } elsif (($key =~ /^default_enrollment_(start|end)_date$/) && ($displayval)) {                                      } elsif (($key =~ /^default_enrollment_(start|end)_date$/) && ($displayval)) {
                                         $displayval = &Apache::lonlocal::locallocaltime($displayval);                                          $displayval = &Apache::lonlocal::locallocaltime($displayval);
                                     } elsif ($key eq 'categories') {                                      } elsif ($key eq 'categories') {
                                         $displayval = $env{'form.categories_display'};                                          $displayval = $env{'form.categories_display'};
                                     }                                        } elsif (($key eq 'canuse_pdfforms') || ($key eq 'usejsme') || ($key eq 'uselcmath')) {
                                     if ($changes->{$item}{$key} eq '') {                                          if ($changes->{$item}{$key} eq '1') {
                                               $displayval = &mt('Yes');
                                           } elsif ($changes->{$item}{$key} eq '0') {
                                               $displayval = &mt('No');
                                           }
                                       }
                                       if ($key eq 'co-owners') {
                                           if (ref($changes->{$item}{$key}) eq 'HASH') {
                                               if (ref($changes->{$item}{$key}{'changed'}) eq 'ARRAY') {
                                                   foreach my $type ('co-owners','pendingco-owners') {
                                                       next unless (grep(/^\Q$type\E$/,@{$changes->{$item}{$key}{'changed'}}));
                                                       if ($type eq 'pendingco-owners') {
                                                           if (&Apache::lonnet::is_course_owner($cdom,$cnum)) {
                                                               $displayname = &mt('Invited as co-owners, pending acceptance');
                                                           }
                                                       }
                                                       if ($changes->{$item}{$key}{$type} eq '') {
                                                           push(@delkeys,'internal.'.$type);
                                                           if (&Apache::lonnet::is_course_owner($cdom,$cnum)) {
                                                               $output .= '<li>'.&Apache::lonhtmlcommon::confirm_success(&mt('Deleted setting for [_1]',
                                                               '<i>'.$displayname.'</i>')).'</li>';
                                                           }
                                                       } elsif (&Apache::lonnet::is_course_owner($cdom,$cnum)) {
                                                           $displayval = join(', ',map { &Apache::loncommon::plainname(split(':',$_)); } split(',',$changes->{$item}{$key}{$type}));
                                                           $output .= '<li>'.&Apache::lonhtmlcommon::confirm_success(&mt('[_1] set to [_2]',
                                                                      '<i>'.$displayname.'</i>',
                                                                      "'<b>$displayval</b>'")).'</li>';
                                                       }
                                                   }
                                               }
                                               unless (&Apache::lonnet::is_course_owner($cdom,$cnum)) {
                                                   if ($env{'form.pending_coowoner'} eq 'accept') {
                                                           $displayval = &mt('on');
                                                   } elsif ($env{'form.pending_coowoner'} eq 'decline') {
                                                           $displayval = '';
                                                           $output .= '<li>'.&Apache::lonhtmlcommon::confirm_success(&mt('Invitation to be co-owner declined')).'</li>';
                                                   } elsif ($env{'form.remove_coowoner'}) {
                                                       $displayval = &mt('off');
                                                   }
                                                   if ($displayval) {
                                                       $displayname = &mt('Your co-ownership status');
                                                       $output .= '<li>'.&Apache::lonhtmlcommon::confirm_success(&mt('[_1] set to [_2]',
                                                      '<i>'.$displayname.'</i>',
                                                      "'<b>$displayval</b>'")).'</li>';
                                                   }
                                               }
                                           }
                                       } elsif ($changes->{$item}{$key} eq '') {
                                         push(@delkeys,$key);                                          push(@delkeys,$key);
                                         $output .= '<li>'.&mt('Deleted setting for [_1]',                                          $output .= '<li>'.&Apache::lonhtmlcommon::confirm_success(&mt('Deleted setting for [_1]',
                                                    '<i>'.$displayname.'</i>').'</li>';                                                     '<i>'.$displayname.'</i>')).'</li>';
                                     } else {                                      } else {
                                         $output .= '<li>'.&mt('[_1] set to [_2]',                                          $output .= '<li>'.&Apache::lonhtmlcommon::confirm_success(&mt('[_1] set to [_2]',
                                                    '<i>'.$displayname.'</i>',                                                     '<i>'.$displayname.'</i>',
                                                    "'<b>$displayval</b>'");                                                     "'<b>$displayval</b>'"));
                                         if ($key eq 'url') {                                          if ($key eq 'url') {
                                             my $bkuptime=time;                                              my $bkuptime=time;
                                             $output .= ('&nbsp;'x2).&mt('(Previous URL backed up)').': '.                                              $output .= ('&nbsp;'x2).&mt('(Previous URL backed up)').': '.
                                             $storehash{'top level map backup '.$bkuptime} => $values->{$key};                                              $storehash{'top level map backup '.$bkuptime} = $values->{$key};
                                         }                                          }
                                         $output .= '</li>';                                          $output .= '</li>';
                                     }                                      }
                                     $storehash{$key} = $changes->{$item}{$key};                                      if ($key eq 'co-owners') {
                                           if (ref($changes->{$item}{$key}) eq 'HASH') {
                                               if (ref($changes->{$item}{$key}{'changed'}) eq 'ARRAY') {
                                                   foreach my $type ('co-owners','pendingco-owners') {
                                                       next unless (grep(/^\Q$type\E$/,@{$changes->{$item}{$key}{'changed'}}));
                                                       $storehash{'internal.'.$type} = $changes->{$item}{$key}{$type};
                                                   }
                                               }
                                           }
                                       } else {
                                           unless ($key eq 'discussion_post_fonts') {
                                               $storehash{$key} = $changes->{$item}{$key};
                                           }
                                       }
                                 }                                  }
                                 if ($key eq 'cloners') {                                  if ($key eq 'cloners') {
                                     # Get existing cloners                                      # Get existing cloners
                                     my %clonenames =                                      my %clonenames = 
                                         &Apache::lonnet::dump('environment',$cdom,$cnum,'cloners');                                          &Apache::lonnet::dump('environment',$cdom,$cnum,'cloners');
                                     if ($clonenames{'cloners'} =~ /,/) {                                      if ($clonenames{'cloners'} =~ /,/) {
                                         @oldcloner = split(/\s*\,\s*/,$clonenames{'cloners'});                                          @oldcloner = split(/\s*\,\s*/,$clonenames{'cloners'});
Line 1206  sub store_changes { Line 1528  sub store_changes {
                                     }                                      }
                                 }                                  }
                                 if (($key eq 'description') || ($key eq 'cloners') ||                                  if (($key eq 'description') || ($key eq 'cloners') ||
                                     ($key eq 'hidefromcat') || ($key eq 'categories')) {                                      ($key eq 'hidefromcat') || ($key eq 'categories') ||
                                       ($key eq 'co-owners')) {
                                     push(@need_env_update,$key);                                      push(@need_env_update,$key);
                                 }                                  }
                             }                              }
Line 1215  sub store_changes { Line 1538  sub store_changes {
                     $output .= '</ul>';                      $output .= '</ul>';
                 } else {                  } else {
                     if ($crstype eq 'Community') {                      if ($crstype eq 'Community') {
                         $output = &mt('No changes made to community settings.');                          $output .= &mt('No changes made to community settings.');
                     } else {                      } else {
                         $output = &mt('No changes made to course settings.');                          $output .= &mt('No changes made to course settings.');
                     }                      }
                 }                  }
             }              }
Line 1241  sub store_changes { Line 1564  sub store_changes {
                     $output .= &mt('An error occurred when removing course settings which are no longer in use.');                      $output .= &mt('An error occurred when removing course settings which are no longer in use.');
                 }                  }
                 $output .= '</span>';                  $output .= '</span>';
             }              } else {
         } else {                  foreach my $key (@delkeys) {
             foreach my $key (@delkeys) {                      &Apache::lonnet::delenv('course.'.$cdom.'_'.$cnum.'.'.$key);
                 &Apache::lonnet::delenv('course.'.$cdom.'_'.$cnum.'.'.$key);                  }
             }              }
         }          }
         if (@need_env_update) {          if (@need_env_update) {
Line 1280  sub update_env { Line 1603  sub update_env {
                     &Apache::lonnet::appenv({'course.'.$env{'request.course.id'}.'.'.$key => $storehash->{$key}});                      &Apache::lonnet::appenv({'course.'.$env{'request.course.id'}.'.'.$key => $storehash->{$key}});
                     $crsinfo{$env{'request.course.id'}}{$key} = $storehash->{$key};                      $crsinfo{$env{'request.course.id'}}{$key} = $storehash->{$key};
                     $count ++;                      $count ++;
                   } elsif ($key eq 'co-owners') {
                       if ($storehash->{'internal.co-owners'} ne '') {
                           &Apache::lonnet::appenv({'course.'.$env{'request.course.id'}.'.internal.co-owners' => $storehash->{'internal.co-owners'}});
                       }
                       if ($storehash->{'internal.pendingco-owners'} ne '') {
                           &Apache::lonnet::appenv({'course.'.$env{'request.course.id'}.'.internal.pendingco-owners' => $storehash->{'internal.pendingco-owners'}});
                       }
                       my @coowners = split(',',$storehash->{'internal.'.$key});
                       $crsinfo{$env{'request.course.id'}}{'co-owners'} = \@coowners;
                       $count ++;
                 }                  }
             }              }
             if ($count) {              if ($count) {
Line 1378  sub get_course { Line 1711  sub get_course {
     }      }
     my $cdom=$env{'course.'.$courseid.'.domain'};      my $cdom=$env{'course.'.$courseid.'.domain'};
     my $cnum=$env{'course.'.$courseid.'.num'};      my $cnum=$env{'course.'.$courseid.'.num'};
     return ($cnum,$cdom);      my $chome=$env{'course.'.$courseid.'.home'};
       return ($cnum,$cdom,$chome);
 }  }
   
 sub get_jscript {  sub get_jscript {
     my ($cdom,$phase,$crstype) = @_;      my ($cid,$cdom,$phase,$crstype,$settings) = @_;
     my ($can_toggle_cat,$can_categorize) = &can_modify_catsettings($cdom,$crstype);      my ($can_toggle_cat,$can_categorize) = &can_modify_catsettings($cdom,$crstype);
     my ($jscript,$categorize_js);      my ($jscript,$categorize_js,$loncaparev_js,$instcode_js);
     my $stubrowse_js = &Apache::loncommon::studentbrowser_javascript();      my $stubrowse_js = &Apache::loncommon::studentbrowser_javascript();
     my $browse_js = &Apache::loncommon::browser_and_searcher_javascript('parmset');      my $browse_js = &Apache::loncommon::browser_and_searcher_javascript('parmset');
     my $cloners_js = &cloners_javascript($phase);      my $cloners_js = &cloners_javascript($phase);
       my @code_order;
       if ($crstype ne 'Community') {
           if (ref($settings) eq 'HASH') {
               my %codedefaults;
               &Apache::lonnet::auto_instcode_defaults($cdom,\%codedefaults,
                                                       \@code_order);
               if (@code_order > 0) {
                   if ($phase eq 'display') {
                       my @actions = &Apache::loncommon::get_env_multiple('form.actions');
                       if (grep(/^courseinfo$/,@actions)) {
                           if ($settings->{'cloners'} ne '') {
                               unless ($settings->{'cloners'} eq '*') {
                                   my @cloners = split(/,/,$settings->{'cloners'});
                                   my @standardnames = &Apache::loncommon::get_standard_codeitems();
                                   my %local_to_standard;
                                   for (my $i=0; $i<@code_order; $i++) {
                                       $local_to_standard{$code_order[$i]} = $standardnames[$i];
                                   }
                                   foreach my $cloner (@cloners) {
                                       if (($cloner !~ /^\Q*:\E$match_domain$/) &&
                                           ($cloner !~ /^$match_username\:$match_domain$/)) {
                                           foreach my $item (split(/\&/,$cloner)) {
                                               my ($key,$val) = split(/\=/,$item);
                                               $val = &unescape($val);
                                               foreach my $code (@code_order) {
                                                   if ($key eq $local_to_standard{$code}) {
                                                       $env{'form.'.$key} = $val;
                                                   }
                                               }
                                           }
                                       }
                                   }
                               }
                           }
                       }
                   }
                   my @codetitles;
                   (undef,$instcode_js) =
                       &Apache::courseclassifier::instcode_selectors($cdom,'display',undef,
                                                                     \@codetitles);
                   $instcode_js .= <<ENDSCRIPT;
   function toggleCloners(callerradio) {
       if (document.getElementById('LC_cloners_instcode')) {
           if (callerradio.value == 1) {
               document.getElementById('LC_cloners_instcode').style.display = "block";
           } else {
               uncheckOfficialLists();
               document.getElementById('LC_cloners_instcode').style.display = "none";
           }
       }
   }
   
   if (!document.getElementsByClassName) {
       function getElementsByClassName(node, classname) {
           var a = [];
           var re = new RegExp('(^| )'+classname+'( |$)');
           var els = node.getElementsByTagName("*");
           for(var i=0,j=els.length; i<j; i++)
               if(re.test(els[i].className))a.push(els[i]);
           return a;
       }
   }
   
   function uncheckOfficialLists() {
       var codepicks;
       if (document.getElementsByClassName) {
           codepicks = document.getElementsByClassName('LC_cloners_instcodes');
       } else {
           codepicks = getElementsByClassName(document.body,'LC_cloners_instcodes');
       }
       if (codepicks.length) {
           for (var i=0; i<codepicks.length; i++) {
               codepicks[i].selectedIndex = 0;
           }
       }
   }
   
   ENDSCRIPT
               }
           }
       }
     if ($can_categorize) {      if ($can_categorize) {
         $categorize_js = <<ENDSCRIPT;          $categorize_js = <<ENDSCRIPT;
 function catsbrowser() {  function catsbrowser() {
Line 1401  function catsbrowser() { Line 1816  function catsbrowser() {
 }  }
 ENDSCRIPT  ENDSCRIPT
     }      }
       my $loncaparev = $env{'course.'.$cid.'.internal.releaserequired'};
       if ($loncaparev) {
           $loncaparev_js = <<ENDSCRIPT;
   function loncaparevinfo() {
       var lcrevwin = null;
       var url = '/adm/courseprefs?phase=releaseinfo';
       if (!lcrevwin || lcrevwin.closed) {
           lcrevwin=window.open(url,'releasewin','height=480,width=600,resizable=yes,scrollbars=yes,location=no,menubar=no,toolbar=no');
       } else {
           lcrevwin.focus();
       }
   }
   ENDSCRIPT
       }
       my $cnum = $env{'course.'.$cid.'.num'};
       my $syllabus_js = <<ENDSCRIPT;
   function syllabusinfo() {
       var syllwin = null;
       var url = '/public/$cdom/$cnum/syllabus?only_body=1';
       if (!syllwin || syllwin.closed) {
           syllwin=window.open(url,'syllabuswin','height=480,width=600,resizable=yes,scrollbars=yes,location=no,menubar=no,toolbar=no');
       } else {
           syllwin.focus();
       }
   }
   ENDSCRIPT
     $jscript = '<script type="text/javascript" language="Javascript">'."\n".      $jscript = '<script type="text/javascript" language="Javascript">'."\n".
                $browse_js."\n".$categorize_js."\n".$cloners_js."\n".'</script>'.                 '// <![CDATA['."\n".
                "\n".$stubrowse_js."\n";                 $browse_js."\n".$categorize_js."\n".$loncaparev_js."\n".
                  $cloners_js."\n".$instcode_js.
                  $syllabus_js."\n".'//]]>'."\n".
                  '</script>'."\n".$stubrowse_js."\n";
     return $jscript;      return $jscript;
 }  }
   
Line 1437  function update_cloners(caller,num) { Line 1881  function update_cloners(caller,num) {
                         if (document.$formname.cloners_activate[i].value == '0') {                          if (document.$formname.cloners_activate[i].value == '0') {
                             document.$formname.cloners_activate[i].checked = false;                              document.$formname.cloners_activate[i].checked = false;
                         }                          }
                         if (document.$formname.cloners_activate[i].value == '') {                          if (document.$formname.cloners_activate[i].value == '-1') {
                             document.$formname.cloners_activate[i].checked = true;                              document.$formname.cloners_activate[i].checked = true;
                         }                          }
                     }                      }
Line 1494  sub print_courseinfo { Line 1938  sub print_courseinfo {
     unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {      unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
         return;          return;
     }      }
     my ($cathash,$categoriesform);      my ($cathash,$categoriesform,$autocoowner,$clonedefaults);
     my %domconf =       my %domconf = 
         &Apache::lonnet::get_dom('configuration',['coursecategories'],$cdom);          &Apache::lonnet::get_dom('configuration',
                                    ['coursecategories','autoenroll','coursedefaults'],$cdom);
     if (ref($domconf{'coursecategories'}) eq 'HASH') {      if (ref($domconf{'coursecategories'}) eq 'HASH') {
         $cathash = $domconf{'coursecategories'}{'cats'};          $cathash = $domconf{'coursecategories'}{'cats'};
         if (ref($cathash) eq 'HASH') {          if (ref($cathash) eq 'HASH') {
Line 1505  sub print_courseinfo { Line 1950  sub print_courseinfo {
                                                 $settings->{'categories'},$crstype)."\n";                                                  $settings->{'categories'},$crstype)."\n";
         }          }
     }      }
       if (ref($domconf{'autoenroll'}) eq 'HASH') {
           $autocoowner = $domconf{'autoenroll'}{'co-owners'};
       }
       my ($currcanclone,@code_order,$cloner_instcode);
       my %codedefaults;
       &Apache::lonnet::auto_instcode_defaults($cdom,\%codedefaults,
                                               \@code_order);
       if ($settings->{'cloners'}) {
           unless ($settings->{'cloners'} eq '*') {
               my @currclone = split(/,/,$settings->{'cloners'});
               foreach my $item (@currclone) {
                   unless ($item eq '*') {
                       if (($item !~ /\:/) && ($item =~ /=/)) {
                           $cloner_instcode = 1;
                       }
                   }
               }
           }
       }
       if (ref($domconf{'coursedefaults'}) eq 'HASH') {
           my $canclone = $domconf{'coursedefaults'}{'canclone'};
           if (ref($canclone) eq 'HASH') {
               if (ref($canclone->{'instcode'}) eq 'ARRAY') {
                   if ($settings->{'internal.coursecode'}) {
                       my @posscodes;
                       if (@code_order > 0) {
                           $currcanclone = 'instcode';
                           foreach my $item (@{$canclone->{'instcode'}}) {
                               if (grep(/^\Q$item\E$/,@code_order)) {
                                   push(@posscodes,$item);
                               }
                           }
                           my $codestr = join(' + ',@posscodes);
                           $clonedefaults = &mt('Default for official courses is to also allow cloning if [_1] match in cloner and cloned.',
                                                '"<span class="LC_nobreak" style="font-style:italic">'.$codestr.'</span>"').'<br />';
                       }
                   }
               }
           } elsif ($canclone eq 'domain') {
               $clonedefaults = &mt('Default is for any course requester in [_1] domain to be able to clone.',
                                    '<span class="LC_nobreak" style="font-style:italic">'.$cdom.'</span>').'<br />';
               $currcanclone = 'domain';
           }
           if ($clonedefaults) {
               if ($settings->{'cloners'} ne '') {
                   $clonedefaults .= '<br />'.&mt('Default does [_1]not[_2] currently apply because values have been set in the course.','<b>','</b>');
               } else {
                   $clonedefaults .= &mt('Default is disregarded if [_1]any[_2] values are set here in the course.','<i>','</i>');
               }
               $clonedefaults = '<br /><br />'.$clonedefaults;
           }
       }
     if (!defined($categoriesform)) {      if (!defined($categoriesform)) {
         $categoriesform = &mt('No categories defined in this domain.');          $categoriesform = &mt('No categories defined in this domain.');
     }      }
   
     my ($can_toggle_cat,$can_categorize) = &can_modify_catsettings($cdom,$crstype);      my ($can_toggle_cat,$can_categorize) = &can_modify_catsettings($cdom,$crstype);
       my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
   
     my $replace;      my $replace;
     if ($crstype eq 'Community') {      if ($crstype eq 'Community') {
Line 1526  sub print_courseinfo { Line 2023  sub print_courseinfo {
                            &mt('Modification may make assessment data inaccessible!').                             &mt('Modification may make assessment data inaccessible!').
                            '</span>',                             '</span>',
                    input => 'textbox',                     input => 'textbox',
                    size  => '40',                     size  => '55',
                      advanced => 1
                  },                   },
         'description'  => {           'description'  => { 
                    text => '<b>'.&mt($itemtext->{'description'}).'</b>',                     text => '<b>'.&mt($itemtext->{'description'}).'</b>',
                    input => 'textbox',                     input => 'textbox',
                    size  => '25',                     size  => '55',
                           },                            },
         'owner'        => {          'owner'        => {
                    text => '<b>'.&mt($itemtext->{'owner'}).'</b>',                     text => '<b>'.&mt($itemtext->{'owner'}).'</b>',
                           },                            },
           'co-owners'    => {
                      text => '<b>'.&mt($itemtext->{'co-owners'}).'</b>',
                             },
           'clonedfrom'   => {
                      text => '<b>'.&mt($itemtext->{'clonedfrom'}).'</b>',
                             },
         'courseid'     => {           'courseid'     => { 
                    text => '<b>'.&mt($itemtext->{'courseid'}).'</b><br />'.'('.                     text => '<b>'.&mt($itemtext->{'courseid'}).'</b><br />'.'('.
                            &mt('internal, optional').')',                             &mt('internal, optional').')',
                    input => 'textbox',                     input => 'textbox',
                    size  => '25',                     size  => '25',
                           },                            },
           'uniquecode'   => {
                      text => '<b>'.&mt($itemtext->{'uniquecode'}).'</b>',
                             },
         'cloners'      => {           'cloners'      => { 
                    text => '<b>'.&mt($itemtext->{'cloners'}).'</b><br />'.                     text => '<b>'.&mt($itemtext->{'cloners'}).'</b><br />'.
                            &mt('Owner and Coordinators included automatically'),                             &mt('Owner and Coordinators included automatically').
                              $clonedefaults,
                    input => 'textbox',                     input => 'textbox',
                    size  => '40',                     size  => '40'
                          },                           },
         'rolenames'  => {           'rolenames'  => { 
                    text  => '<b>'.&mt($itemtext->{'rolenames'}).'</b><br />'.                     text  => '<b>'.&mt($itemtext->{'rolenames'}).'</b><br />'.
                             '('.$replace.')',                              '('.$replace.')',
                    input => 'textbox',                     input => 'textbox',
                    size  => '20',                     size  => '20',
                      advanced => 1
                         },                          },
         'externalsyllabus' => {          'externalsyllabus' => {
                    text => '<b>'.&mt($itemtext->{'externalsyllabus'}).'</b><br />('.                     text => '<b>'.&mt($itemtext->{'externalsyllabus'}).'</b><br />'.
                            &mt('not using syllabus template)'),                             &mt('(Syllabus type in use)').('&nbsp;' x2).
                    input => 'textbox',                             &mt('[_1]Edit[_2]','<a href="/public/'.$cdom.'/'.$cnum.'/syllabus?forceedit=1">',
                    size  => '40',                                 '</a>'),
                         },                          },
         'hidefromcat' => {          'hidefromcat' => {
                    text => '<b>'.&mt($itemtext->{'hidefromcat'}).'</b><br />'.                     text => '<b>'.&mt($itemtext->{'hidefromcat'}).'</b><br />'.
Line 1571  sub print_courseinfo { Line 2080  sub print_courseinfo {
                    input => 'textbox',                     input => 'textbox',
                    size  => '25',                     size  => '25',
                         },                          },
           'loncaparev' => {
                      text => '<b>'.&mt($itemtext->{'loncaparev'}).'</b>',
                           },
           'defaultcredits' => {
                      text => '<b>'.&mt($itemtext->{'defaultcredits'}).'</b>',
                           },
     );      );
     my $datatable;      my $datatable;
     my $count = 0;      my $count = 0;
     foreach my $item (@{$ordered}) {      foreach my $item (@{$ordered}) {
           my $colspan;
         if ($item eq 'hidefromcat') {          if ($item eq 'hidefromcat') {
             next if (!$can_toggle_cat);              next if (!$can_toggle_cat);
         } elsif ($item eq 'categories') {          } elsif ($item eq 'categories') {
             next if (!$can_categorize);              next if (!$can_categorize);
           } elsif ($item eq 'uniquecode') {
               next if (!$env{'course.'.$env{'request.course.id'}.'.internal.uniquecode'});
           }
           unless (($item eq 'cloners') || ($item eq 'rolenames')) {
               $colspan = 2;
         }          }
         $count ++;          $count ++;
         $datatable .= &item_table_row_start($items{$item}{text},$count);          if (exists $items{$item}{advanced} && $items{$item}{advanced} == 1) {
           $datatable .= &item_table_row_start($items{$item}{text},$count,"advanced",$colspan);
           } else {
           $datatable .= &item_table_row_start($items{$item}{text},$count,undef,$colspan);
           }
         if ($items{$item}{input} eq 'radio') {          if ($items{$item}{input} eq 'radio') {
             $datatable .= &yesno_radio($item,$settings);              $datatable .= &yesno_radio($item,$settings);
         } elsif ($item eq 'cloners') {          } elsif ($item eq 'cloners') {
             my $includeempty = 1;              my $includeempty = 1;
             my $num = 0;              my $num = 0;
             $datatable .= &Apache::loncommon::start_data_table().              $datatable .= '</td><td align="right">'.
                             &Apache::loncommon::start_data_table().
                           &Apache::loncommon::start_data_table_row().                            &Apache::loncommon::start_data_table_row().
                           '<td><span class="LC_nobreak"><label>'.                            '<td><span class="LC_nobreak"><label>'.
                           &mt('Any user in any domain:').                            &mt('Any user in any domain:').
Line 1597  sub print_courseinfo { Line 2123  sub print_courseinfo {
             }              }
             $datatable .= 'onchange="javascript:update_cloners('.              $datatable .= 'onchange="javascript:update_cloners('.
                           "'cloners_all'".');" />'.&mt('Yes').'</label>'.                            "'cloners_all'".');" />'.&mt('Yes').'</label>'.
                           ('&nbsp;'x2).'<input type="radio" name="cloners_all" value="0" ';                            ('&nbsp;'x2).'<label>'.
                             '<input type="radio" name="cloners_all" value="0" ';
             if ($settings->{$item} ne '*') {              if ($settings->{$item} ne '*') {
                 $datatable .= ' checked="checked" ';                  $datatable .= ' checked="checked" ';
             }              }
             $datatable .= ' onchange="javascript:update_cloners('.              $datatable .= ' onchange="javascript:update_cloners('.
                           "'cloners_all'".');"/>'.&mt('No').'</label></td>'.                            "'cloners_all'".');" />'.&mt('No').'</label></td>'.
                           &Apache::loncommon::end_data_table_row().                            &Apache::loncommon::end_data_table_row().
                           &Apache::loncommon::end_data_table().                            &Apache::loncommon::end_data_table().
                           '<table><tr><td align="left">'.&mt('Or').                            '<table><tr><td align="left"><b>'.&mt('Or').
                           '</td></tr></table>'.                            '</b></td></tr></table>'.
                           &Apache::loncommon::start_data_table();                            &Apache::loncommon::start_data_table();
             my @cloners;              my @cloners;
             if ($settings->{$item} eq '') {              if ($settings->{$item} eq '') {
                 $datatable .= &new_cloners_dom_row($cdom,'0');                  my $default;
                   if ($currcanclone eq 'domain') {
                       $default = '0';
                   }
                   $datatable .= &new_cloners_dom_row($cdom,'0',$default);
             } elsif ($settings->{$item} ne '*') {              } elsif ($settings->{$item} ne '*') {
                 my @entries = split(/,/,$settings->{$item});                  my @entries = split(/,/,$settings->{$item});
                 if (@entries > 0) {                  if (@entries > 0) {
                     foreach my $entry (@entries) {                      foreach my $entry (@entries) {
                         my ($uname,$udom) = split(/:/,$entry);                          my ($uname,$udom) = split(/:/,$entry);
                         my ($uname,$udom) = split(/:/,$entry);  
                         if ($udom =~ /^$match_domain$/) {                          if ($udom =~ /^$match_domain$/) {
                             unless (&Apache::lonnet::domain($udom)) {                              unless (&Apache::lonnet::domain($udom)) {
                                 next;                                  next;
Line 1659  sub print_courseinfo { Line 2189  sub print_courseinfo {
                           '<input type="hidden" name="cloners_total" value="'.$num.'" />'.                            '<input type="hidden" name="cloners_total" value="'.$num.'" />'.
                           '</td>'.&Apache::loncommon::end_data_table_row().                            '</td>'.&Apache::loncommon::end_data_table_row().
                           &Apache::loncommon::end_data_table().                            &Apache::loncommon::end_data_table().
                           '<table><tr><td align="left">'.&mt('And').                            '<table><tr><td align="left"><b>'.&mt('And').
                           '</td></tr></table>'.                            '</b></td></tr></table>'.
                           &Apache::loncommon::start_data_table().                            &Apache::loncommon::start_data_table().
                           &Apache::loncommon::start_data_table_row().                            &Apache::loncommon::start_data_table_row().
                           '<td align="left">'.                            '<td align="left">'.
Line 1670  sub print_courseinfo { Line 2200  sub print_courseinfo {
                                                           $items{$item}{'size'}).                                                            $items{$item}{'size'}).
                           '</td>'.&Apache::loncommon::end_data_table_row().                            '</td>'.&Apache::loncommon::end_data_table_row().
                           &Apache::loncommon::end_data_table();                            &Apache::loncommon::end_data_table();
               if (@code_order > 0) {
                   my (%cat_items,@codetitles,%cat_titles,%cat_order);
                   my ($jscript,$totcodes,$numtitles,$lasttitle) =
                       &Apache::courseclassifier::instcode_selectors_data($cdom,'display',
                                                                          \%cat_items,\@codetitles,
                                                                          \%cat_titles,\%cat_order);
                   my $showncodes = 'off';
                   my $checkedoff = ' checked="checked"';
                   my $checkedon = '';
                   if ($cloner_instcode) {
                       $checkedon = $checkedoff;
                       $checkedoff = '';
                       $showncodes = 'on';
                   }
                   $datatable .= '<table><tr><td align="left"><b>'.&mt('And').
                                 '</b></td></tr></table>'.
                                 &Apache::loncommon::start_data_table().
                                 &Apache::loncommon::start_data_table_row().
                                 '<td align="left"><span class="LC_nobreak">'.
                                 &mt('Cloning by official course(s) based on course category').('&nbsp;'x2).
                                 '<label>'.
                                 '<input type="radio" name="cloners_instcode" value="1" onclick="toggleCloners(this);"'.$checkedon.' />'.&mt('Yes').'</label>'.
                                 ('&nbsp;').
                                 '<label>'.
                                 '<input type="radio" name="cloners_instcode" value="0" onclick="toggleCloners(this);"'.$checkedoff.' />'.&mt('No').'</label>'.
                                 &Apache::courseclassifier::build_instcode_selectors($numtitles,
                                     $lasttitle,\%cat_items,\@codetitles,\%cat_titles,\%cat_order,
                                     $showncodes,'LC_cloners_instcodes','LC_cloners_instcode').
                                 '</td>'.&Apache::loncommon::end_data_table_row().
                                 &Apache::loncommon::end_data_table();
               }
         } elsif ($item eq 'rolenames') {          } elsif ($item eq 'rolenames') {
             $datatable .= &Apache::loncommon::start_data_table();              $datatable .= '</td><td align="right">'.
                             &Apache::loncommon::start_data_table();
             my @roles;              my @roles;
             if ($crstype eq 'Community') {              if ($crstype eq 'Community') {
                 @roles = ('co');                  @roles = ('co');
Line 1691  sub print_courseinfo { Line 2253  sub print_courseinfo {
             }              }
             $datatable .= &Apache::loncommon::end_data_table().'</td>';              $datatable .= &Apache::loncommon::end_data_table().'</td>';
         } elsif ($item eq 'categories') {          } elsif ($item eq 'categories') {
             my $launcher = 'onFocus="this.blur();javascript:catsbrowser();";';              my $launcher = 'onfocus="this.blur();javascript:catsbrowser();"';
             $datatable .= '<input type="hidden" name="categories" value="'.$settings->{$item}.'" />'.              $datatable .= '<input type="hidden" name="categories" value="'.$settings->{$item}.'" />'.
                           &Apache::lonhtmlcommon::textbox($item.'_display',$settings->{$item},                            &Apache::lonhtmlcommon::textbox($item.'_display',$settings->{$item},
                                                           $items{$item}{size},$launcher);                                                            $items{$item}{size},$launcher);
         } elsif ($item eq 'owner') {          } elsif ($item eq 'owner') {
             my $owner = $env{'course.'.$env{'request.course.id'}.'.internal.courseowner'};              my $owner = $env{'course.'.$env{'request.course.id'}.'.internal.courseowner'};
             if ($owner =~ /:/) {              if ($owner =~ /:/) {
                 my ($ownername,$ownerdom) = split(':',$owner);                  my ($ownername,$ownerdom) = split(':',$owner); 
                 $owner = &Apache::loncommon::plainname($ownername,$ownerdom);                  $owner = &Apache::loncommon::plainname($ownername,$ownerdom);
             } elsif ($owner ne '') {              } elsif ($owner ne '') {
                 $owner = &Apache::loncommon::plainname($owner,$cdom);                  $owner = &Apache::loncommon::plainname($owner,$cdom);
             } else {              } else {
                 $owner = &mt('None specified');                  $owner = &mt('None specified');
             }              }
             my $domdesc = &Apache::lonnet::domain($cdom,'description');  
             $datatable .= $owner;              $datatable .= $owner;
           } elsif ($item eq 'clonedfrom') {
               my $clonesrc = $env{'course.'.$env{'request.course.id'}.'.clonedfrom'};
               my $clonedfrom = &mt('None');
               if ($clonesrc =~ m{/$match_domain/$match_courseid}) {
                   my %clonesrcinfo = &Apache::lonnet::coursedescription($clonesrc);
                   if ($clonesrcinfo{'description'}) {
                       $clonedfrom = $clonesrcinfo{'description'}.' '.($clonesrc);
                   }
               }
               $datatable .= $clonedfrom;
           } elsif ($item eq 'uniquecode') {
               my $code = $env{'course.'.$env{'request.course.id'}.'.internal.uniquecode'};
               if ($code) {
                   $datatable .= $code;
               }
           } elsif ($item eq 'co-owners') {
               my $coowners = $env{'course.'.$env{'request.course.id'}.'.internal.co-owners'};
               my @currcoown;
               if ($coowners) {
                   @currcoown = split(',',$coowners);
               }
               if (&Apache::lonnet::is_course_owner($cdom,$cnum)) {
                   if (($crstype eq 'Course') && ($env{'course.'.$env{'request.course.id'}.'.internal.coursecode'}) && ($autocoowner)) {
                       $datatable .= &show_autocoowners(@currcoown);
                   } else {
                       $datatable .= &coowner_invitations($cnum,$cdom,@currcoown);
                   }
               } else {
                   if (($crstype eq 'Course') && ($env{'course.'.$env{'request.course.id'}.'.internal.coursecode'}) && ($autocoowner)) {
                       $datatable .= &show_autocoowners(@currcoown);
                   } else {
                       $datatable .= &manage_coownership($cnum,$cdom,@currcoown);
                   }
               }
           } elsif ($item eq 'externalsyllabus') {
               my $external = $env{'course.'.$env{'request.course.id'}.'.externalsyllabus'};
               my $uploaded = $env{'course.'.$env{'request.course.id'}.'.uploadedsyllabus'};
               my $minimal =  $env{'course.'.$env{'request.course.id'}.'.minimalsyllabus'};
               if (($minimal =~/\w/) || ($uploaded =~/\w/)) {
                   if ($minimal =~/\w/) {
                       if ($external =~ m{\Q$minimal\E$}) {
                           undef($external);
                       }
                   } elsif ($uploaded =~/\w/) {
                       if ($external =~ m{\Q$uploaded\E$}) {
                           undef($external);
                       }
                   }
               } elsif ($external!~/\w/) {
                   undef($external);
               }
               if ($external) {
                   $datatable .= &mt('External URL');
               } elsif ($minimal) {
                   $datatable .= &mt('Minimal template');
               } elsif ($uploaded) {
                   $datatable .= &mt('Uploaded file');
               } else {
                   $datatable .= &mt('Standard template');
               }
               $datatable .= ('&nbsp;' x 2).
                             &mt('[_1]View[_2]',
                                 '<a href="javascript:syllabusinfo();">',
                                 '</a>');
           } elsif ($item eq 'loncaparev') {
               my $loncaparev = $env{'course.'.$env{'request.course.id'}.'.internal.releaserequired'};
               my $showreqd;
               if ($loncaparev) {
                   $showreqd = &mt('[_1] or newer',$loncaparev).' <a href="javascript:loncaparevinfo()">'.
                               &mt('Details').'</a>';
               } else {
                   $showreqd = &mt('No specific version required');
               }
               $datatable .= $showreqd;
         } else {          } else {
             $datatable .= &Apache::lonhtmlcommon::textbox($item,$settings->{$item},$items{$item}{size});              $datatable .= &Apache::lonhtmlcommon::textbox($item,$settings->{$item},$items{$item}{size});
         }          }
Line 1717  sub print_courseinfo { Line 2352  sub print_courseinfo {
 }  }
   
 sub new_cloners_dom_row {  sub new_cloners_dom_row {
     my ($newdom,$num) = @_;      my ($newdom,$num,$default) = @_;
     my $output;      my ($output,$checkedon,$checkedoff);
     if ($newdom ne '') {      if ($newdom ne '') {
           if ($num eq $default) {
              $checkedon = 'checked="checked" ';
           } else {
              $checkedoff = 'checked="checked" ';
           }
         $output .= &Apache::loncommon::start_data_table_row().          $output .= &Apache::loncommon::start_data_table_row().
                    '<td valign="top"><span class="LC_nobreak">'.                     '<td valign="top"><span class="LC_nobreak">'.
                    &mt('Any user in domain:').'&nbsp;<b>'.$newdom.'</b>'.                     &mt('Any user in domain:').'&nbsp;<b>'.$newdom.'</b>'.
                    ('&nbsp;'x2).'<label><input type="radio" '.                     ('&nbsp;'x2).'<label><input type="radio" '.
                    'name="cloners_activate" value="'.$num.'" '.                     'name="cloners_activate" value="'.$num.'" '.$checkedon.
                    'onchange="javascript:update_cloners('.                     'onchange="javascript:update_cloners('.
                    "'cloners_activate','$num'".');" />'.                     "'cloners_activate','$num'".');" />'.
                    &mt('Yes').'</label>'.('&nbsp;'x2).                     &mt('Yes').'</label>'.('&nbsp;'x2).
                    '<label><input type="radio" '.                     '<label><input type="radio" '.
                    'name="cloners_activate" value="" checked="checked" '.                     'name="cloners_activate" value="-1" '.$checkedoff.
                    'onchange="javascript:update_cloners('.                     'onchange="javascript:update_cloners('.
                    "'cloners_activate','$num'".');" />'.                     "'cloners_activate','$num'".');" />'.
                    &mt('No').'</label><input type="hidden" name="cloners_dom_'.                     &mt('No').'</label><input type="hidden" name="cloners_dom_'.
Line 1864  ENDSCRIPT Line 2504  ENDSCRIPT
     return;      return;
 }  }
   
   sub display_loncaparev_constraints {
       my ($r,$navmap,$loncaparev,$crstype) = @_;
       my ($reqdmajor,$reqdminor);
       my $cid = $env{'request.course.id'};
       my $cdom = $env{'course.'.$cid.'.domain'};
       my $cnum = $env{'course.'.$cid.'.num'};
       my $output;
       my %lt = &Apache::lonlocal::texthash (
                                              'all'           => 'all',
                                              'section/group' =>  'section/group',
                                              'user'          => 'user',
                                            );
       &Apache::lonrelrequtils::init_global_hashes();
       if (defined($Apache::lonrelrequtils::checkcrstypes{$crstype})) {
           ($reqdmajor,$reqdminor) = split(/\./,$Apache::lonrelrequtils::checkcrstypes{$crstype});
           $output .= '<h4>'.&mt('Course type: [_1] requires [_2] or newer',$crstype,
                                 $Apache::lonrelrequtils::checkcrstypes{$crstype}).'</h4>';
       }
       my (%fromparam,%rowspan,%bymap,%byresource,@scopeorder,%toshow,%allmaps,
           %byresponsetype,%bysubmission,%fromblocks);
       @scopeorder = ('all','section/group','user');
       my $now = time;
       my $resourcedata = &Apache::lonparmset::readdata($cnum,$cdom);
       if (ref($resourcedata) eq 'HASH') {
           foreach my $key (keys(%{$resourcedata})) {
               foreach my $item (keys(%Apache::lonrelrequtils::checkparms)) {
                   if ($key =~ /(\Q$item\E)$/) {
                        if (ref($Apache::lonrelrequtils::checkparms{$item}) eq 'ARRAY') {
                            my $value = $resourcedata->{$key};
                            if ($item eq 'examcode') {
                                if (&Apache::lonnet::validCODE($value)) {
                                    $value = 'valid';
                                } else {
                                    $value = '';
                                }
                            } elsif ($item eq 'printstartdate') {
                                if ($value =~ /^\d+$/) {
                                    if ($value > $now) {
                                        $value = 'future';
                                    }
                                }
                            } elsif ($item eq 'printenddate') {
                                if ($value =~ /^\d+$/) {
                                    if ($value < $now) {
                                        $value = 'past';
                                    }
                                }
   
                            }
                            my ($middle,$scope,$which,$level,$map,$resource);
                            if (grep(/^\Q$value\E$/,@{$Apache::lonrelrequtils::checkparms{$item}})) {
                                my $stdtype = &Apache::lonparmset::standard_parameter_types($item);
                                my $stdname = &Apache::lonparmset::standard_parameter_names($item);
                                my $valname = &get_param_description($stdtype,$value);
                                my $rev = $Apache::lonnet::needsrelease{'parameter:'.$item.':'.$value};
                                my $start = $cid.'.';
                                if ($key =~ /^\Q$start\E(\[useropt\:($match_username\:$match_domain)\]\.)/) {
                                    $middle = $1;
                                    $which = $2;
                                    $scope = 'user'; 
                                } elsif ($key =~ /^\Q$start\E(\[(\w+)\]\.)/) {
                                    $middle = $1;
                                    $which = $2;
                                    $scope = 'section/group';
                                } else {
                                    $scope = 'all';
                                }
                                my $what="$stdname=$valname";
                                if ($key =~ /^\Q$start$middle\E\w+\.\Q$item\E$/) {
                                    $level = 'general';
                                    if ($scope eq 'all') {
                                        if (ref($fromparam{$rev}{$scope}) eq 'ARRAY') {
                                            unless(grep(/^\Q$what\E$/,@{$fromparam{$rev}{$scope}})) {
                                                push(@{$fromparam{$rev}{$scope}},$what);
                                            }
                                        } else {
                                            push(@{$fromparam{$rev}{$scope}},$what);
                                        }
                                    } else {
                                        if (ref($fromparam{$rev}{$scope}{$which}) eq 'ARRAY') {
                                            unless (grep(/^\Q$what\E$/,@{$fromparam{$rev}{$scope}{$which}})) {
                                                push(@{$fromparam{$rev}{$scope}{$which}},$what);
                                            }
                                        } else {
                                            push(@{$fromparam{$rev}{$scope}{$which}},$what);
                                        }
                                    }
                                    $rowspan{$rev} ++;
                                } elsif ($key =~ /^\Q$start$middle\E(.+)___\(all\).\w+\.\Q$item\E$/) {
                                    $level = 'folder';
                                    $map = $1;
                                    if ($scope eq 'all') {
                                        if (ref($bymap{$map}{$rev}{$scope}) eq 'ARRAY') {
                                            unless(grep(/^\Q$what\E$/,@{$bymap{$map}{$rev}{$scope}})) {
                                                push(@{$bymap{$map}{$rev}{$scope}},$what);
                                            }
                                        } else {
                                            push(@{$bymap{$map}{$rev}{$scope}},$what);
                                        }
                                    } else {
                                        if (ref($bymap{$map}{$rev}{$scope}{$which}) eq 'ARRAY') {
                                            unless(grep(/^\Q$what\E$/,@{$bymap{$map}{$rev}{$scope}{$which}})) {
                                                push(@{$bymap{$map}{$rev}{$scope}{$which}},$what);
                                            }
                                        } else {
                                            push(@{$bymap{$map}{$rev}{$scope}{$which}},$what);
                                        }
                                    }
                                } elsif ($key =~ /^\Q$start$middle\E(.+)\.\w+\.\Q$item\E$/) {
                                    $level = 'resource';
                                    $resource = $1;
                                    if ($scope eq 'all') {
                                        if (ref($byresource{$resource}{$rev}{$scope}) eq 'ARRAY') {
                                            unless(grep(/^\Q$what\E$/,@{$byresource{$resource}{$rev}{$scope}})) {
                                                push(@{$byresource{$resource}{$rev}{$scope}},$what);
                                            }
                                        } else {
                                            push(@{$byresource{$resource}{$rev}{$scope}},$what);
                                        }
                                    } else {
                                        if (ref($byresource{$resource}{$rev}{$scope}{$which}) eq 'ARRAY') {
                                            unless (grep(/^\Q$what\E$/,@{$byresource{$resource}{$rev}{$scope}{$which}})) {
                                                push(@{$byresource{$resource}{$rev}{$scope}{$which}},$what);
                                            }
                                        } else {
                                            push(@{$byresource{$resource}{$rev}{$scope}{$which}},$what);
                                        }
                                    }
                                }
                           }
                       }
                   }
               }
           }
           if (keys(%fromparam)) {
               $output .= '<h4>'.&mt('Requirements from general settings').'</h4>'.
                          &Apache::loncommon::start_data_table().
                          &Apache::loncommon::start_data_table_header_row().
                          '<th>'.&mt('Release').'</th><th>'.&mt('Scope').'</th>'.
                          '<th>'.&mt('Extent').'</th><th>'.&mt('Setting').'</th>'.
                          &Apache::loncommon::end_data_table_header_row();
               foreach my $rev (keys(%fromparam)) {
                   my ($major,$minor) = split(/\./,$rev);
                   ($reqdmajor,$reqdminor) =
                       &Apache::lonrelrequtils::update_reqd_loncaparev($major,$minor,$reqdmajor,$reqdminor);
                   $output .=  &Apache::loncommon::start_data_table_row().
                               '<td rowspan="'.$rowspan{$rev}.'">'.$rev.'</td>';
                   my $newrow;
                   foreach my $scope (@scopeorder) {
                       if (ref($fromparam{$rev}{$scope}) eq 'HASH') {
                            if ($newrow) {
                                $output .= &Apache::loncommon::continue_data_table_row();
                            }
                            $output .= '<td>'.$lt{$scope}.'</td>';
                            foreach my $which (sort(keys(%{$fromparam{$rev}{$scope}}))) {
                                $output .= '<td>'.$which.'</td><td>'.
                                           join('<br />',@{$fromparam{$rev}{$scope}{$which}}).'</td>';
                            }
                            $output .= &Apache::loncommon::end_data_table_row();
                            $newrow = 1;
                       } elsif (ref($fromparam{$rev}{$scope}) eq 'ARRAY') {
                            if ($newrow) {
                                $output .= &Apache::loncommon::continue_data_table_row();
                            }
                            $output .= '<td>'.$lt{$scope}.'</td><td>&nbsp;</td><td>'.
                                       join('<br />',@{$fromparam{$rev}{$scope}}).'</td>'.
                                       &Apache::loncommon::end_data_table_row();
                            $newrow = 1;
                       }
                   }
               }
               $output .= &Apache::loncommon::end_data_table().'<br />';
           }
       }
   
       my %comm_blocks =  &Apache::lonnet::dump('comm_block',$cdom,$cnum);
       my $now = time;
       if (keys(%comm_blocks) > 0) {
           foreach my $block (keys(%comm_blocks)) {
               if ($block =~ /^firstaccess____(.+)$/) {
                   my $rev = $Apache::lonnet::needsrelease{'course:commblock:timer'};
                   if (ref($comm_blocks{$block}) eq 'HASH') {
                       push(@{$fromblocks{'timer'}{$rev}},&unescape($comm_blocks{$block}{'event'}).
                            ' '.&mt('set by [_1]',
                                    &Apache::loncommon::plainname(split(/:/,$comm_blocks{$block}{'setter'}))));
                   }
                   next;
               } elsif ($block =~ /^(\d+)____(\d+)$/) {
                   my ($start,$end) = ($1,$2);
                   next if ($end < $now);
               }
               if (ref($comm_blocks{$block}) eq 'HASH') {
                   if (ref($comm_blocks{$block}{'blocks'}) eq 'HASH') {
                       if (ref($comm_blocks{$block}{'blocks'}{'docs'}) eq 'HASH') {
                           if (keys(%{$comm_blocks{$block}{'blocks'}{'docs'}}) > 0) {
                               my $rev = $Apache::lonnet::needsrelease{'course:commblock:docs'};
                               push(@{$fromblocks{'docs'}{$rev}},&unescape($comm_blocks{$block}{'event'}).
                                    ' '.
                                    &mt('set by [_1]',
                                        &Apache::loncommon::plainname(split(/:/,$comm_blocks{$block}{'setter'}))));
                           }
                       } elsif ($comm_blocks{$block}{'blocks'}{'printout'} eq 'on') {
                           my $rev = $Apache::lonnet::needsrelease{'course:commblock:printout'};
                           push(@{$fromblocks{'printout'}{$rev}},&unescape($comm_blocks{$block}{'event'}).
                                ' '.
                                &mt('set by [_1]',
                                    &Apache::loncommon::plainname(split(/:/,$comm_blocks{$block}{'setter'}))));
   
                       }
                   }
               }
           }
           if (keys(%fromblocks)) {
               my %lt = (
                          docs     => 'Content blocking',
                          printout => 'Printout generation',
                          timer    => 'Timed quiz trigger',
                        );
               $output .= '<h4>'.&mt('Requirements from exam blocking').'</h4>'.
                          &Apache::loncommon::start_data_table().
                          &Apache::loncommon::start_data_table_header_row().
                          '<th>'.&mt('Release').'</th><th>'.&mt('Setting').'</th>'.
                          '<th>'.&mt('Event(s)').'</th>'.
                          &Apache::loncommon::end_data_table_header_row();
               foreach my $type ('docs','printout','timer') {
                   if (ref($fromblocks{$type}) eq 'HASH') {
                       foreach my $rev (keys(%{$fromblocks{$type}})) {
                           my ($major,$minor) = split(/\./,$rev);
                           ($reqdmajor,$reqdminor) =
                               &Apache::lonrelrequtils::update_reqd_loncaparev($major,$minor,$reqdmajor,$reqdminor);
                           $output .= &Apache::loncommon::start_data_table_row().
                                      '<td>'.$rev.'</td><td>'.$lt{$type}.'</td><td>';
                           foreach my $event (sort(@{$fromblocks{$type}{$rev}})) {
                               $output .= $event.'<br />';
                           }
                           $output =~ s{\Q<br />\E$}{};
                           $output .= '</td>'.&Apache::loncommon::end_data_table_row();
                       }
                   }
               }
               $output .= &Apache::loncommon::end_data_table().'<br />';
           }
       }
   
       if (defined($navmap)) {
           my %anonsubms=&Apache::lonnet::dump('nohist_anonsurveys',$cdom,$cnum);
           my $rev_anonsurv=$Apache::lonnet::needsrelease{'parameter:type:anonsurvey'};
           my %randtrysubms=&Apache::lonnet::dump('nohist_randomizetry',$cdom,$cnum);
           my $rev_randtry=$Apache::lonnet::needsrelease{'parameter:type:randomizetry'};
           my $stdtype=&Apache::lonparmset::standard_parameter_types('type');
           my $stdname=&Apache::lonparmset::standard_parameter_names('type');
           my $valanon=&get_param_description($stdtype,'anonsurvey');
           my $valrandtry=&get_param_description($stdtype,'randomizetry');
           my %checkedrev;
           foreach my $res ($navmap->retrieveResources(undef,sub { $_[0]->is_problem() },1,0)) {
               my @parts = @{$res->parts()};
               my $symb = $res->symb();
               my $enclosing_map = &Apache::lonnet::declutter($res->enclosing_map_src());
               foreach my $part (@parts) {
                   if (exists($anonsubms{$symb."\0".$part})) {
                       my $rev = $rev_anonsurv;
                       my $what="$stdname=$valanon";
                       if (ref($bysubmission{$symb}{$rev}) eq 'ARRAY') {
                           unless (grep(/^\Q$what\E/,@{$bysubmission{$symb}{$rev}})) {
                               push(@{$bysubmission{$symb}{$rev}},$what);
                           }
                       } else {
                           push(@{$bysubmission{$symb}{$rev}},$what);
                       }
                       $allmaps{$enclosing_map} = 1;
                       unless ($checkedrev{'anonsurvey'}) {
                           my ($major,$minor) = split(/\./,$rev);
                           ($reqdmajor,$reqdminor) =
                               &Apache::lonrelrequtils::update_reqd_loncaparev($major,$minor,
                                                                               $reqdmajor,$reqdminor);
                           $checkedrev{'anonsurvey'} = 1;
                       }
                   }
                   if (exists($randtrysubms{$symb."\0".$part})) {
                       my $rev = $rev_randtry;
                       my $what="$stdname=$valrandtry";
                       if (ref($bysubmission{$symb}{$rev}) eq 'ARRAY') {
                           unless (grep(/^\Q$what\E/,@{$bysubmission{$symb}{$rev}})) {
                               push(@{$bysubmission{$symb}{$rev}},$what);
                           }
                       } else {
                           push(@{$bysubmission{$symb}{$rev}},$what);
                       }
                       $allmaps{$enclosing_map} = 1;
                       unless ($checkedrev{'randomizetry'}) {
                           my ($major,$minor) = split(/\./,$rev);
                           ($reqdmajor,$reqdminor) =
                               &Apache::lonrelrequtils::update_reqd_loncaparev($major,$minor,
                                                                               $reqdmajor,$reqdminor);
                           $checkedrev{'randomizetry'} = 1;
                       }
                   }
               }
               my %responses = $res->responseTypes();
               foreach my $key (keys(%responses)) {
                   if (exists($Apache::lonrelrequtils::checkresponsetypes{$key})) {
                       my $rev = $Apache::lonrelrequtils::checkresponsetypes{$key};
                       unless ($checkedrev{$key}) {
                           my ($major,$minor) = split(/\./,$rev);
                           ($reqdmajor,$reqdminor) =
                               &Apache::lonrelrequtils::update_reqd_loncaparev($major,$minor,
                                                                               $reqdmajor,$reqdminor);
                           $checkedrev{$key} = 1;
                       }
                       push(@{$byresponsetype{$symb}{$rev}},$key);
                       $allmaps{$enclosing_map} = 1;
                   }
               }
           }
           if (keys(%byresource) > 0) {
               foreach my $symb (keys(%byresource)) {
                   my ($map,$resid,$resurl)=&Apache::lonnet::decode_symb($symb);
                   $allmaps{$map} = 1;
               }
           }
           if (keys(%bymap) > 0) {
               foreach my $map (keys(%bymap)) {
                   $allmaps{$map} = 1;
               }
           }
           foreach my $map (keys(%allmaps)) {
               my $mapres = $navmap->getResourceByUrl($map);
               if (ref($mapres)) {
                   my $mapsymb = $mapres->symb();
                   $toshow{$mapsymb} = 1;
                   my $pcslist = $mapres->map_hierarchy();
                   if ($pcslist ne '') {
                       foreach my $pc (split(/,/,$pcslist)) {
                           my $res = $navmap->getByMapPc($pc);
                           if (ref($res)) {
                               my $symb = $res->symb();
                               unless ($symb eq '______') {
                                   $toshow{$symb} = 1;
                               }
                           }
                       }
                   }
               }
           }
       }
       my $mapres_header = '<h4>'.
                           &mt('Requirements for specific folders or resources').
                           '</h4>';
       if ((keys(%toshow) > 0) || (keys(%byresource) > 0) || 
           (keys(%bysubmission) > 0) || (keys(%byresponsetype))) {
           $output .= $mapres_header;
       }
       my $top_header = '<h3>'.&mt('LON-CAPA version dependencies').'</h3>';
       my $title = 'Version Constraints';
       my $start_page =
           &Apache::loncommon::start_page($title,undef,{'only_body' => 1,});
       $r->print($start_page.$top_header);
       if ($output) {
           $r->print($output);
           if (defined($navmap)) {
               &show_contents_view($r,$navmap,$cid,\%toshow,\%bymap,\%byresource,\%bysubmission,
                                   \%byresponsetype,\@scopeorder,\%lt);
           }
           $r->print('<br /><br />'); 
       } else {
           $r->print('<p class="LC_info">'.
                     &mt('No version requirements from resource content or settings.').
                     '</p>'); 
       }
       $r->print(&Apache::loncommon::end_page());
       my ($currmajor,$currminor) = split(/\./,$loncaparev);
       if (($currmajor != $reqdmajor) || ($currminor != $reqdminor)) {
           return 1;
       }
       return;
   }
   
   sub show_contents_view {
       my ($r,$navmap,$cid,$toshow,$bymap,$byresource,$bysubmission,$byresponsetype,
           $scopeorder,$lt) = @_;
       if ((keys(%{$toshow}) > 0) || (keys(%{$byresource}) > 0) || 
           (keys(%{$bysubmission}) > 0) || (keys(%{$byresponsetype}) > 0)) {
           my $location=&Apache::loncommon::lonhttpdurl("/adm/lonIcons");
           my $whitespace = '<img src="'.$location.'/whitespace_21.gif" alt="" />';
           my $icon =  '<img src="'.$location.'/navmap.folder.open.gif" alt="" />';
           my $topmap = $env{'course.'.$cid.'.url'};
           $r->print(&Apache::loncommon::start_data_table().
                     &Apache::loncommon::start_data_table_header_row().
                     '<th>'.&mt('Location').'</th><th>'.&mt('Release').'</th>'.
                     '<th>'.&mt('Attribute/Setting').'</th>'.
                     &Apache::loncommon::end_data_table_header_row().
                     &Apache::loncommon::start_data_table_row().
                     '<td>&nbsp;'.$icon.'&nbsp;'.&mt('Main Content').'</td>');
                     &releases_by_map($r,$bymap,$topmap,$scopeorder,$lt);
                     $r->print(&Apache::loncommon::end_data_table_row());
           my $it=$navmap->getIterator(undef,undef,undef,1,1,undef);
           my $curRes;
           my $depth = 0;
           my %parent = ();
           my $startcount = 5;
           my $lastcontainer = $startcount;
           while ($curRes = $it->next()) {
               if ($curRes == $it->BEGIN_MAP()) {
                   $depth++;
                   $parent{$depth}= $lastcontainer;
               }
               if ($curRes == $it->END_MAP()) {
                   $depth--;
                   $lastcontainer = $parent{$depth};
               }
               my $indent;
               for (my $i=0; $i<$depth; $i++) {
                   $indent.= $whitespace;
               }
               if (ref($curRes)) {
                   my $symb = $curRes->symb();
                   my $ressymb = $symb;
                   my $srcf = $curRes->src();
                   my $title = &Apache::lonnet::gettitle($srcf);
                   if (($curRes->is_sequence()) || ($curRes->is_page())) {
                       next unless($toshow->{$symb});
                       my ($parent,$ind,$url) = &Apache::lonnet::decode_symb($symb);
                       $icon =  '<img src="'.$location.'/navmap.folder.open.gif" alt="" />';
                       if ($curRes->is_page()) {
                           $icon = '<img src="'.$location.'/navmap.page.open.gif" alt="" />';
                       }
                       my $rowspan = 1;
                       if (ref($bymap->{$url}) eq 'HASH') {
                           $rowspan = scalar(keys(%{$bymap->{$url}}));
                       }
                       $r->print(&Apache::loncommon::start_data_table_row().
                                 '<td rowspan="'.$rowspan.'">'.$indent.$icon.'&nbsp;'.$title.'</td>');
                       &releases_by_map($r,$bymap,$url,$scopeorder,$lt);
                       $r->print(&Apache::loncommon::end_data_table_row());
                   } else {
                       my $rowspan;
                       if (ref($byresource->{$symb}) eq 'HASH') {
                           $rowspan += scalar(keys(%{$byresource->{$symb}}));
                       }
                       if (ref($bysubmission->{$symb}) eq 'HASH') {
                           $rowspan += scalar(keys(%{$bysubmission->{$symb}}));
                       }
                       if (ref($byresponsetype->{$symb}) eq 'HASH') {
                           $rowspan += scalar(keys(%{$byresponsetype->{$symb}}));
                       }
                       next if (!$rowspan);
                       $icon = '<img class="LC_contentImage" src="'.$location.'/problem.gif" alt="'.
                               &mt('Problem').'" />';
                       $r->print(&Apache::loncommon::start_data_table_row().
                                 '<td rowspan="'.$rowspan.'">'.$indent.$icon.'&nbsp;'.$title.'</td>');
                       my $newrow;
                       if (ref($byresource->{$symb}) eq 'HASH') {
                           foreach my $rev (sort(keys(%{$byresource->{$symb}}))) {
                               if ($newrow) {
                                   $r->print(&Apache::loncommon::continue_data_table_row());
                               }
                               $r->print('<td valign="middle">'.$rev.'</td><td>');
                               if (ref($byresource->{$symb}{$rev}) eq 'HASH') {
                                   $r->print('<table border="0">');
                                   foreach my $scope (@{$scopeorder}) {
                                       if (ref($byresource->{$symb}{$rev}{$scope}) eq 'HASH') {
                                           $r->print('<tr><td>'.&mt('Setting - scope: [_1]',$lt->{$scope}).'</td>');
                                           foreach my $which (sort(keys(%{$byresource->{$symb}{$rev}{$scope}}))) {
                                               $r->print('<td>'.$which.'</td><td>'.
                                                   join('<br />',@{$byresource->{$symb}{$rev}{$scope}{$which}}).
                                                         '</td>');
                                           }
                                           $r->print('</tr>');
                                       } elsif (ref($byresource->{$symb}{$rev}{$scope}) eq 'ARRAY') {
                                           $r->print('<tr><td>'.&mt('Setting - scope: [_1]',$lt->{$scope}).'</td>'.
                                                     '<td>&nbsp;</td><td>'.
                                                     join('<br />',@{$byresource->{$symb}{$rev}{$scope}}).'</td></tr>');
                                       }
                                   }
                                   $r->print('</table>');
                               }
                               $r->print('</td>');
                               $r->print(&Apache::loncommon::end_data_table_row());
                               $newrow = 1;
                           }
                       }
                       if (ref($bysubmission->{$symb}) eq 'HASH') {
                           foreach my $rev (sort(keys(%{$bysubmission->{$symb}}))) {
                               if ($newrow) {
                                   $r->print(&Apache::loncommon::continue_data_table_row());
                               }
                               $r->print('<td>'.$rev.'</td><td>');
                               if (ref($bysubmission->{$symb}{$rev}) eq 'ARRAY') {
                                   $r->print(&mt('Submissions to: ').' '.
                                            join(', ',@{$bysubmission->{$symb}{$rev}}));
                               }
                               $r->print('</td>');
                               $r->print(&Apache::loncommon::end_data_table_row());
                               $newrow = 1;
                           }
                       }
                       if (ref($byresponsetype->{$symb}) eq 'HASH') {
                           foreach my $rev (sort(keys(%{$byresponsetype->{$symb}}))) {
                               if ($newrow) {
                                   $r->print(&Apache::loncommon::continue_data_table_row());
                               }
                               $r->print('<td>'.$rev.'</td><td>');
                               if (ref($byresponsetype->{$symb}{$rev}) eq 'ARRAY') {
                                   $r->print(&mt('Response Type(s): ').' '.
                                            join('<br />',@{$byresponsetype->{$symb}{$rev}}));
                               }
                               $r->print('</td>');
                           }
                           $r->print(&Apache::loncommon::end_data_table_row());
                       }
                   }
               }
           }
           $r->print(&Apache::loncommon::end_data_table());
       }
       return;
   }
   
   sub releases_by_map {
       my ($r,$bymap,$url,$scopeorder,$lt) = @_;
       return unless ((ref($bymap) eq 'HASH') && (ref($scopeorder) eq 'ARRAY'));
       if (ref($bymap->{$url}) eq 'HASH') {
           foreach my $rev (sort(keys(%{$bymap->{$url}}))) {
               $r->print('<td valign="middle">'.$rev.'</td><td>');
               if (ref($bymap->{$url}{$rev}) eq 'HASH') {
                   $r->print('<table border="0">');
                   foreach my $scope (@{$scopeorder}) {
                       if (ref($bymap->{$url}{$rev}{$scope}) eq 'HASH') {
                           $r->print('<tr><td>'.&mt('Setting - scope: [_1]',$lt->{$scope}).'</td>');
                           foreach my $which (sort(keys(%{$bymap->{$url}{$rev}{$scope}}))) {
                               $r->print('<td>'.$which.'</td><td>'.
                                         join('<br />',@{$bymap->{$url}{$rev}{$scope}{$which}}).
                                         '</td>');
                           }
                           $r->print('</tr>');
                       } elsif (ref($bymap->{$url}{$rev}{$scope}) eq 'ARRAY') {
                           $r->print('<tr><td>'.&mt('Setting - scope: [_1]',$lt->{$scope}).
                                     '</td><td>&nbsp;</td><td>'.
                                     join('<br />',@{$bymap->{$url}{$rev}{$scope}}).'</td></tr>');
                       }
                   }
                   $r->print('</table>');
               }
               $r->print('</td>');
           }
       } else {
           $r->print('<td colspan="2">&nbsp;</td>');
       }
       return;
   }
   
   sub get_param_description {
       my ($stdtype,$value) = @_;
       my $name = $value;
       my $paramstrings = &Apache::lonparmset::standard_string_options($stdtype);
       unless (ref($paramstrings) eq 'ARRAY') {
           return $name;
       }
       foreach my $possibilities (@{$paramstrings}) {
           next unless (ref($possibilities) eq 'ARRAY');
           my ($thing, $description) = @{ $possibilities };
           if ($thing eq $value) {
               $name = $description;
               last;
           }
       }
       return $name;
   }
   
   sub update_releasereq {
       my $readmap = 1;
       my $getrelreq = 1;
       if (ref($modified_courses) eq 'ARRAY') {
           foreach my $item (@{$modified_courses}) {
               if (ref($item) eq 'ARRAY') {
                   my ($cdom,$cnum,$chome,$crstype) = @{$item};
                   &Apache::lonrelrequtils::modify_course_relreq(undef,undef,$cnum,$cdom,
                                                                 $chome,$crstype,$cdom.'_'.$cnum,
                                                                 $readmap,$getrelreq);
               }
           }
           $modified_courses = [];
       }
       undef($registered_cleanup);
       return;
   }
   
   sub show_autocoowners {
       my (@currcoown) = @_;
       my $output = '<i><span class="LC_nobreak">'.&mt('Co-ownership is set automatically when a Course Coordinator role[_1] is assigned to official course personnel (from institutional data).','</span><br /><span class="LC_nobreak">').'</span></i>';
       if (@currcoown > 0) { 
           $output .= '<br />'.&mt('Current co-owners are:').'&nbsp;'.
                      join(', ',map { &Apache::loncommon::plainname(split(':',$_)); } (@currcoown));
       } else {
           $output .= '<br />'.&mt('Currently no co-owners.');
       } 
       return $output;
   }
   
   sub coowner_invitations {
       my ($cnum,$cdom,@currcoown) = @_;
       my ($output,@pendingcoown,@othercoords);
       my $pendingcoowners =
           $env{'course.'.$env{'request.course.id'}.'.internal.pendingco-owners'};
       if ($pendingcoowners) {
           @pendingcoown = split(',',$pendingcoowners);
       }
       my $ccrole = 'cc';
       my %ccroles = &Apache::lonnet::get_my_roles($cnum,$cdom,undef,undef,[$ccrole]);
       foreach my $key (sort(keys(%ccroles))) {
           my ($ccname,$ccdom,$role) = split(':',$key);
           next if ($key eq $env{'user.name'}.':'.$env{'user.domain'}.':'.$ccrole);
           unless (grep(/^\Q$ccname\E:\Q$ccdom\E$/,@currcoown,@pendingcoown)) {
               push(@othercoords,$ccname.':'.$ccdom);
           }
       }
       my $coowner_rows = @currcoown + @pendingcoown + @othercoords;
       if ($coowner_rows) {
           $output .= &Apache::loncommon::start_data_table();
           if (@currcoown) {
               $output .= &Apache::loncommon::start_data_table_row().
                             '<td><i>'.&mt('Current co-owners').'</i></td><td>';
               foreach my $person (@currcoown) {
                   my ($co_uname,$co_dom) = split(':',$person);
                   $output .= '<span class="LC_nobreak"><label><input type="checkbox" name="coowners" checked="checked" value="'.$person.'" />'.&Apache::loncommon::plainname($co_uname,$co_dom).'</label></span>'.('&nbsp;'x2).' ';
               }
               $output .= '</td>'.
                             &Apache::loncommon::end_data_table_row();
           }
           if ($pendingcoowners) {
               $output .= &Apache::loncommon::start_data_table_row().
                             '<td><i>'.&mt('Invited as co-owners [_1](agreement pending)','<br />').'</i></td><td>';
               foreach my $person (@pendingcoown) {
                   my ($co_uname,$co_dom) = split(':',$person);
                   $output .= '<span class="LC_nobreak"><label><input type="checkbox" name="pendingcoowners" checked="checked" value="'.$person.'" />'.&Apache::loncommon::plainname($co_uname,$co_dom).'</label></span>'.('&nbsp;'x2).' ';
               }
               $output .= '</td>'.
                          &Apache::loncommon::end_data_table_row();
           }
           if (@othercoords) {
               $output .= &Apache::loncommon::start_data_table_row().
                             '<td><i>'.&mt('Invite other Coordinators [_1]to become co-owners','<br />').'</i></td><td>';
               foreach my $person (@othercoords) {
                   my ($co_uname,$co_dom) = split(':',$person);
                   $output .= '<span class="LC_nobreak"><label><input type="checkbox" name="invitecoowners" value="'.$person.'" />'.&Apache::loncommon::plainname($co_uname,$co_dom).'</label></span>'.('&nbsp;'x2).' ';
               }
               $output .= '</td>'.
                             &Apache::loncommon::end_data_table_row();
           }
           $output .= &Apache::loncommon::end_data_table();
       } else {
           $output = &mt('There are no coordinators to select as co-owners');
       }
       return $output;
   }
   
   sub manage_coownership  {
       my ($cnum,$cdom,@currcoown) = @_;
       my (@pendingcoown);
       my $pendingcoowners =
           $env{'course.'.$env{'request.course.id'}.'.internal.pendingco-owners'};
       if ($pendingcoowners) {
           @pendingcoown = split(',',$pendingcoowners);
       }
       my ($is_coowner,$is_pending,$output);
       my $uname = $env{'user.name'};
       my $udom = $env{'user.domain'};
       if (grep(/^\Q$uname\E:\Q$udom\E$/,@currcoown)) {
           $is_coowner = 1;
       }
       if (grep(/^\Q$uname\E:\Q$udom\E$/,@pendingcoown)) {
           $is_pending = 1;
       }
       if (@currcoown && ($is_coowner || $is_pending)) {
           $output = &Apache::loncommon::start_data_table();
       }
       if (@currcoown) {
           if ($is_coowner || $is_pending) { 
               $output .= &Apache::loncommon::start_data_table().
                          &Apache::loncommon::start_data_table_row().'<td>';
           }
           $output .= &mt('Current co-owners are:').'&nbsp;'.
                      join(', ', map { &Apache::loncommon::plainname(split(':',$_)); } (@currcoown));  
           if ($is_coowner || $is_pending) {
               $output .= '</td>'.&Apache::loncommon::end_data_table_row(); 
           }
       }
       if ($is_coowner || $is_pending) {
           if (@currcoown) { 
               $output .= &Apache::loncommon::start_data_table_row().'<td>';
           }
           $output .= '<span class="LC_nobreak">';
           if ($is_coowner) {
               $output .= &mt('You are currently a co-owner:').'&nbsp;<label><input type="checkbox" name="remove_coowoner" value="'.$uname.':'.$udom.'" />'.&mt('Discontinue?').'</label>';
           } else {
               $output .= &mt('The course owner has invited you to become a co-owner:').'&nbsp;<label><input type="radio" name="pending_coowoner" value="accept" />'.&mt('Accept?').'</label>'.('&nbsp;'x2).
                          '<label><input type="radio" name=pending_coowoner" value="decline" />'.&mt('Decline?').'</label>';
           }
           $output .= '</span>';
           if (@currcoown) {
               $output .= '</td>'.&Apache::loncommon::end_data_table_row();
           }
       }
       if (@currcoown && ($is_coowner || $is_pending)) {
           $output .= &Apache::loncommon::end_data_table();
       }
       return $output;
   }
   
 sub print_localization {  sub print_localization {
     my ($cdom,$settings,$ordered,$itemtext,$rowtotal) = @_;      my ($cdom,$settings,$ordered,$itemtext,$rowtotal) = @_;
     unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {      unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
Line 1871  sub print_localization { Line 3220  sub print_localization {
     }      }
     my %items = (      my %items = (
         languages => {          languages => {
                         text => &mt($itemtext->{'languages'}).'<br />'.                          text => '<b>'.&mt($itemtext->{'languages'}).'</b><br />'.
                                 &mt("(will override user's preference)"),                                  &mt("(overrides individual user preference)"),
                         input => 'selectbox',                          input => 'selectbox',
                      },                        }, 
         timezone => {          timezone => {
                         text  => &mt($itemtext->{'timezone'}),                          text  => '<b>'.&mt($itemtext->{'timezone'}).'</b>',
                         input => 'selectbox',                          input => 'selectbox',
                     },                      },
         datelocale  => {           datelocale  => { 
                          text => &mt($itemtext->{'datelocale'}),                           text => '<b>'.&mt($itemtext->{'datelocale'}).'</b>',
                          input => 'selectbox',                           input => 'selectbox',
                        },                         },
     );      );
Line 1888  sub print_localization { Line 3237  sub print_localization {
     my $count = 0;      my $count = 0;
     foreach my $item (@{$ordered}) {      foreach my $item (@{$ordered}) {
         $count ++;          $count ++;
         $datatable .= &item_table_row_start($items{$item}{text},$count);          my $colspan;
           unless ($item eq 'languages') {
               $colspan = 2;
           }
           $datatable .= &item_table_row_start($items{$item}{text},$count,undef,$colspan);
         if ($item eq 'timezone') {          if ($item eq 'timezone') {
             my $includeempty = 1;              my $includeempty = 1;
             my $timezone = &Apache::lonlocal::gettimezone();              my $timezone = &Apache::lonlocal::gettimezone();
Line 1907  sub print_localization { Line 3260  sub print_localization {
                                                       undef,$includeempty);                                                        undef,$includeempty);
         } else {          } else {
             if ($settings->{$item} eq '') {              if ($settings->{$item} eq '') {
                 $datatable .=                   $datatable .= '</td><td align="right">'.
                     &Apache::loncommon::select_language('languages_0','',1);                      &Apache::loncommon::select_language('languages_0','',1);
             } else {              } else {
                 my $num = 0;                  my $num = 0;
                 my @languages = split(/\s*[,;:]\s*/,$settings->{$item});                  my @languages = split(/\s*[,;:]\s*/,$settings->{$item});
                 $datatable .= &Apache::loncommon::start_data_table();                  $datatable .= '</td><td align="right"><br />'.
                                 &Apache::loncommon::start_data_table();
                 if (@languages > 0) {                  if (@languages > 0) {
                     my %langchoices = &get_lang_choices();                      my %langchoices = &get_lang_choices();
                     foreach my $lang (@languages) {                      foreach my $lang (@languages) {
Line 1939  sub print_localization { Line 3293  sub print_localization {
                               &Apache::loncommon::select_language('languages_'.$num,'',1).                                &Apache::loncommon::select_language('languages_'.$num,'',1).
                               '<input type="hidden" name="languages_total" value="'.$num.'" />'.                                '<input type="hidden" name="languages_total" value="'.$num.'" />'.
                               '</td>'.&Apache::loncommon::end_data_table_row().                                '</td>'.&Apache::loncommon::end_data_table_row().
                               &Apache::loncommon::end_data_table();                                &Apache::loncommon::end_data_table().'<br />';
             }              }
         }          }
         $datatable .= &item_table_row_end();          $datatable .= &item_table_row_end();
Line 1998  sub print_feedback { Line 3352  sub print_feedback {
   
     foreach my $item (@{$ordered}) {      foreach my $item (@{$ordered}) {
         $count ++;          $count ++;
         $datatable .= &item_table_row_start($items{$item}{text},$count);          if ($position eq 'top') {
           $datatable .= &item_table_row_start($items{$item}{text},$count);
           } else {
           $datatable .= &item_table_row_start($items{$item}{text}."<br/>(Custom text)",$count, "advanced",2);
           }
         if ($position eq 'top') {          if ($position eq 'top') {
             my $includeempty = 0;              my $includeempty = 0;
             $datatable .= &user_table($cdom,$item,\@sections,              $datatable .= '</td><td align="right">'.
                             &user_table($cdom,$item,\@sections,
                                       $settings->{$item},\%lt);                                        $settings->{$item},\%lt);
         } else {          } else {
             $datatable .= &Apache::lonhtmlcommon::textbox($item.'.text',              $datatable .= &Apache::lonhtmlcommon::textbox($item.'.text',
Line 2021  sub user_table { Line 3380  sub user_table {
     } else {      } else {
         my $num = 0;          my $num = 0;
         my @curr = split(/,/,$currvalue);          my @curr = split(/,/,$currvalue);
         $output .= '<table class="LC_nested_outer">';          $output .= '<table class="LC_data_table">';
         my ($currusers);          my ($currusers);
         foreach my $val (@curr) {          foreach my $val (@curr) {
             next if ($val eq '');              next if ($val eq '');
Line 2167  sub print_discussion { Line 3526  sub print_discussion {
                    text => '<b>'.&mt($itemtext->{'allow_discussion_post_editing'}).'</b>',                     text => '<b>'.&mt($itemtext->{'allow_discussion_post_editing'}).'</b>',
                    input => 'checkbox',                     input => 'checkbox',
                  },                   },
           'discussion_post_fonts' => {
                      text => '<b>'.&mt($itemtext->{'discussion_post_fonts'}).'</b>',
                      input => 'textbox',
                      size  => '20',
                    },
     );      );
     my $datatable;      my $datatable;
     my $count;      my $count;
Line 2180  sub print_discussion { Line 3544  sub print_discussion {
                                           del      => 'Delete?',                                            del      => 'Delete?',
                                           sec      => 'Sections:',                                            sec      => 'Sections:',
                                          );                                           );
   
     foreach my $item (@{$ordered}) {      foreach my $item (@{$ordered}) {
         $count ++;          $count ++;
         $datatable .= &item_table_row_start($items{$item}{text},$count);          my $colspan;
           if ($item eq 'allow_limited_html_in_feedback') {
               $colspan = 2;
           }
           $datatable .= &item_table_row_start($items{$item}{text},$count,undef,$colspan);
         if ($item eq 'plc.roles.denied') {          if ($item eq 'plc.roles.denied') {
             $datatable .= '<table>'.&role_checkboxes($cdom,$cnum,$item,$settings).              $datatable .= '</td><td align="right">'.
                             '<table>'.&role_checkboxes($cdom,$cnum,$item,$settings).
                           '</table>';                            '</table>';
         } elsif ($item eq 'plc.users.denied') {          } elsif ($item eq 'plc.users.denied') {
             $datatable .= &user_table($cdom,$item,undef,              $datatable .= '</td><td align="right">'.
                             &user_table($cdom,$item,undef,
                                       $settings->{$item},\%lt);                                        $settings->{$item},\%lt);
         } elsif ($item eq 'pch.roles.denied') {          } elsif ($item eq 'pch.roles.denied') {
             $datatable .= '<table>'.&role_checkboxes($cdom,$cnum,$item,$settings).              $datatable .= '</td><td align="right">'.
                             '<table>'.&role_checkboxes($cdom,$cnum,$item,$settings).
                           '</table>';                            '</table>';
         } elsif ($item eq 'pch.users.denied') {          } elsif ($item eq 'pch.users.denied') {
             $datatable .= &user_table($cdom,$item,undef,              $datatable .= '</td><td align="right">'.
                             &user_table($cdom,$item,undef,
                                       $settings->{$item},\%lt);                                        $settings->{$item},\%lt);
         } elsif ($item eq 'allow_limited_html_in_feedback') {          } elsif ($item eq 'allow_limited_html_in_feedback') {
             $datatable .= &yesno_radio($item,$settings);              $datatable .= &yesno_radio($item,$settings);
         } elsif ($item eq 'allow_discussion_post_editing') {          } elsif ($item eq 'allow_discussion_post_editing') {
             $datatable .= &Apache::loncommon::start_data_table().              $datatable .= '</td><td align="right"><br />'.
                             &Apache::loncommon::start_data_table().
                           &Apache::loncommon::start_data_table_row().                            &Apache::loncommon::start_data_table_row().
                           '<th align="left">'.&mt('Role').'</th><th>'.                            '<th align="left">'.&mt('Role').'</th><th>'.
                           &mt('Sections').'</th>'.                            &mt('Sections').'</th>'.
                           &Apache::loncommon::end_data_table_row().                            &Apache::loncommon::end_data_table_row().
                           &role_checkboxes($cdom,$cnum,$item,$settings,1).                            &role_checkboxes($cdom,$cnum,$item,$settings,1).
                           &Apache::loncommon::end_data_table();                            &Apache::loncommon::end_data_table().'<br />';
           } elsif ($item eq 'discussion_post_fonts') {
               $datatable .= '</td><td align="right"><br />'.
                             &Apache::loncommon::start_data_table().
                             &Apache::loncommon::start_data_table_row().
                             '<th align="center">'.&mt('Sum of likes/dislikes').'</th>'.
                             '<th align="center">'.&mt('font-size').'</th>'.
                             '<th align="center">'.&mt('font-weight').'</th>'.
                             '<th align="center">'.&mt('font-style').'</th>'.
                             '<th align="center">'.&mt('Other css').'</th>'.
                             &Apache::loncommon::end_data_table_row().
                             &set_discussion_fonts($cdom,$cnum,$item,$settings).
                             &Apache::loncommon::end_data_table().'<br />';
         }          }
         $datatable .= &item_table_row_end();          $datatable .= &item_table_row_end();
     }      }
Line 2269  sub role_checkboxes { Line 3653  sub role_checkboxes {
                 $output .= '<tr>';                  $output .= '<tr>';
             }              }
         }          }
         $output .= '<td align="left"><span class="LC_nobreak"><label><input type="checkbox" name='.          $output .= '<td align="left"><span class="LC_nobreak"><label><input type="checkbox" name="'.
                    $item.'" value="'.$role.'"'.$checked.'/>&nbsp;'.                     $item.'" value="'.$role.'"'.$checked.'/>&nbsp;'.
                    $plrole.'</label></span></td>';                     $plrole.'</label></span></td>';
         if ($showsections) {          if ($showsections) {
Line 2301  sub role_checkboxes { Line 3685  sub role_checkboxes {
                     $output .= '<tr>';                      $output .= '<tr>';
                 }                  }
             }              }
             $output .= '<td><span class="LC_nobreak"><label><input type="checkbox" name='.              $output .= '<td><span class="LC_nobreak"><label><input type="checkbox" name="'.
                        $item.'" value="'.$value.'"'.$checked.' />&nbsp;'.$rolename.                         $item.'" value="'.$value.'"'.$checked.' />&nbsp;'.$rolename.
                        '</label></span></td>';                         '</label></span></td>';
             if ($showsections) {              if ($showsections) {
Line 2327  sub role_checkboxes { Line 3711  sub role_checkboxes {
     return $output;      return $output;
 }  }
   
   sub set_discussion_fonts {
       my ($cdom,$cnum,$item,$settings) = @_;
       my ($classorder,$classtitles) = &discussion_vote_classes();
       my ($styleorder,$styleitems) = &discussion_vote_styles();
       my $output;
       if (ref($classorder) eq 'ARRAY') {
           foreach my $cat (@{$classorder}) {
               my %curr = ();
               ($curr{'size'},$curr{'weight'},$curr{'style'},$curr{'other'}) =
                   split(/,/,$settings->{'discussion_post_fonts_'.$cat});
               $output .= &Apache::loncommon::start_data_table_row().
                          '<td>'.$classtitles->{$cat}.'</td>';
               if (ref($styleorder) eq 'ARRAY') {
                   foreach my $item (@{$styleorder}) {
                       $output .= '<td><span class="LC_nobreak">';
                       my $selitem = $item;
                       if ($item eq 'size') {
                           my ($currsize,$currunit);
                           if ($curr{'size'} =~ /^(\d+)(px|%)$/) {
                               ($currsize,$currunit) = ($1,$2);
                               $curr{'size'} = $currunit;
                           }
                           $output .= '<input type="textbox" name="discussion_post_fonts_'.$cat.'_'.$item.'" value="'.$currsize.'" size="5">'.
                                      '&nbsp;';
                           $selitem = 'unit';
                       }
                       if ((ref($styleitems) eq 'HASH') && (ref($styleitems->{$item}) eq 'ARRAY')) {
                           $output .= '<select name="discussion_post_fonts_'.$cat.'_'.$selitem.'">';
                           foreach my $val (@{$styleitems->{$item}}) {
                               my $sel;
                               if ($val eq $curr{$item}) {
                                   $sel = ' selected="selected"';
                               }
                               $output .= '<option value="'.$val.'"'.$sel.'>'.$val.'</option>';
                           }
                       }
                   }
               }
               $output .= '</span></td><td><input type="textbox" size="10" name="discussion_post_fonts_'.$cat.'_other" value="'.$curr{'other'}.'" /></td>';
          }
          $output .= &Apache::loncommon::end_data_table_row();
       }
       return $output;
   }
   
   sub discussion_vote_classes {
       my $classorder = ['twoplus','oneplus','zero','oneminus','twominus'];
       my %classtitles = &Apache::lonlocal::texthash(
                           'twoplus'  => 'Two sigma above mean',
                           'oneplus'  => 'One sigma above mean',
                           'zero'     => 'Within one sigma of mean',
                           'oneminus' => 'One sigma below mean',
                           'twominus' => 'Two sigma below mean',
                         );
       return ($classorder,\%classtitles);
   }
   
   sub discussion_vote_styles {
       my $styleorder = ['size','weight','style'];
       my $styleitems = {
                            size => ['','px','%','xx-small','x-small','small','medium','large',
                                     'x-large','xx-large','smaller','larger'],
                            weight => ['','normal','bold','bolder','lighter','100','200','300','400',
                                       '500','600','700','800','900'],
                            style => ['','normal','italic','oblique'],
                        };
       return ($styleorder,$styleitems);
   }
   
 sub print_classlists {  sub print_classlists {
     my ($position,$cdom,$settings,$itemtext,$rowtotal,$crstype) = @_;      my ($position,$cdom,$settings,$itemtext,$rowtotal,$crstype) = @_;
     my @ordered;      my @ordered;
     if ($position eq 'top') {      if ($position eq 'top') {
         @ordered = ('default_enrollment_start_date',          @ordered = ('default_enrollment_start_date',
                     'default_enrollment_end_date');                      'default_enrollment_end_date');
           if ($crstype eq 'Course') {
               push(@ordered,'defaultcredits');
           }
     } elsif ($position eq 'middle') {      } elsif ($position eq 'middle') {
         @ordered = ('nothideprivileged');          @ordered = ('nothideprivileged','checkforpriv');
     } else {      } else {
         @ordered = ('student_classlist_view',          @ordered = ('student_classlist_view',
                     'student_opt_in','student_classlist_portfiles');                      'student_classlist_opt_in',
                        'student_classlist_portfiles');
     }      }
     my %lt;      my %lt;
   
Line 2364  sub print_classlists { Line 3821  sub print_classlists {
                    text => '<b>'.&mt($itemtext->{'default_enrollment_end_date'}).'</b>',                     text => '<b>'.&mt($itemtext->{'default_enrollment_end_date'}).'</b>',
                    input => 'dates',                     input => 'dates',
                  },                   },
           'defaultcredits' => {
                      text => '<b>'.&mt($itemtext->{'defaultcredits'}).'</b>',
                    },
   
         'nothideprivileged'   => {          'nothideprivileged'   => {
                    text => '<b>'.&mt($itemtext->{'nothideprivileged'}).'</b>',                     text => '<b>'.&mt($itemtext->{'nothideprivileged'}).'</b>',
                    input => 'checkbox',                     input => 'checkbox',
                  },                   },
   
           'checkforpriv' => {
                      text => '<b>'.&mt($itemtext->{'checkforpriv'}).'</b>',
                      input => 'selectbox',
                    },
   
         'student_classlist_view'   => {          'student_classlist_view'   => {
                    text => '<b>'.&mt($itemtext->{'student_classlist_view'}).'</b>',                     text => '<b>'.&mt($itemtext->{'student_classlist_view'}).'</b>',
                    input => 'selectbox',                     input => 'selectbox',
                    options => \%lt,                     options => \%lt,
                    order => ['disabled','all','section'],                     order => ['disabled','all','section'],
                  },                   },
         'student_opt_in' => {          'student_classlist_opt_in' => {
                    text => '<b>'.&mt($itemtext->{'student_opt_in'}).'</b>',                     text => '<b>'.&mt($itemtext->{'student_classlist_opt_in'}).'</b>',
                    input => 'radio',                     input => 'radio',
                  },                   },
   
Line 2390  sub print_classlists { Line 3855  sub print_classlists {
             ($settings->{'student_classlist_view'} eq 'section')) {               ($settings->{'student_classlist_view'} eq 'section')) { 
         $settings->{'student_classlist_view'} = 'disabled';          $settings->{'student_classlist_view'} = 'disabled';
     }      }
     return &make_item_rows($cdom,\%items,\@ordered,$settings,$rowtotal,$crstype);      return &make_item_rows($cdom,\%items,\@ordered,$settings,$rowtotal,$crstype,'classlists');
 }  }
   
 sub print_appearance {  sub print_appearance {
Line 2426  sub print_appearance { Line 3891  sub print_appearance {
                    text => '<b>'.&mt($itemtext->{'texengine'}).'</b>',                     text => '<b>'.&mt($itemtext->{'texengine'}).'</b>',
                    input => 'selectbox',                     input => 'selectbox',
                    options => {                     options => {
                                   MathJax  => 'MathJax',
                                 jsMath   => 'jsMath',                                  jsMath   => 'jsMath',
                                 mimetex => &mt('Convert to Images'),                                  mimetex => &mt('Convert to Images'),
                                 tth      => &mt('TeX to HTML'),                                  tth      => &mt('TeX to HTML'),
                               },                                },
                    order  => ['jsMath','mimetex','tth'],                     order  => ['MathJax','jsMath','mimetex','tth'],
                    nullval => $mathdef,                     nullval => $mathdef,
                  },                   },
         'tthoptions' => {          'tthoptions' => {
Line 2438  sub print_appearance { Line 3904  sub print_appearance {
                    input => 'textbox',                     input => 'textbox',
                    size => 40,                     size => 40,
                  },                   },
            'uselcmath' => {
                      text => '<b>'.&mt($itemtext->{'uselcmath'}).'</b>',
                      input => 'radio',
                    },
            'usejsme'  => {
                      text => '<b>'.&mt($itemtext->{'usejsme'}).'</b>',
                      input => 'radio',
                    },
     );      );
     return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype);      return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype,'appearance');
 }  }
   
 sub print_grading {  sub print_grading {
Line 2462  sub print_grading { Line 3936  sub print_grading {
                  },                   },
         'rndseed' => {          'rndseed' => {
                    text => '<b>'.&mt($itemtext->{'rndseed'}).'</b>'.                     text => '<b>'.&mt($itemtext->{'rndseed'}).'</b>'.
                            '<span class="LC_error">'.'<br />'.                             '<span class="LC_warning">'.'<br />'.
                            &mt('Modifying this will make problems have different numbers and answers!').                             &mt('Modifying this will make problems have different numbers and answers!').
                            '</span>',                             '</span>',
                    input => 'selectbox',                     input => 'selectbox',
Line 2475  sub print_grading { Line 3949  sub print_grading {
                                 '64bit5' => '64bit5',                                  '64bit5' => '64bit5',
                               },                                },
                    order => ['32bit','64bit','64bit2','64bit3','64bit4','64bit5'],                     order => ['32bit','64bit','64bit2','64bit3','64bit4','64bit5'],
                      advanced => 1
                  },                   },
         'receiptalg'  => {          'receiptalg'  => {
                    text => '<b>'.&mt($itemtext->{'receiptalg'}).'</b><br />'.                     text => '<b>'.&mt($itemtext->{'receiptalg'}).'</b><br />'.
Line 2486  sub print_grading { Line 3961  sub print_grading {
                                 receipt3 => 'receipt3',                                  receipt3 => 'receipt3',
                               },                                },
                    order => ['receipt','receipt2','receipt3'],                     order => ['receipt','receipt2','receipt3'],
                      advanced => 1
                  },                   },
         'disablesigfigs' => {          'disablesigfigs' => {
                    text => '<b>'.&mt($itemtext->{'disablesigfigs'}).'</b>',                     text => '<b>'.&mt($itemtext->{'disablesigfigs'}).'</b>',
                    input => 'radio',                     input => 'radio',
                  },                   },
     );      );
     return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype);      return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype,'grading');
 }  }
   
 sub print_printouts {  sub print_printouts {
Line 2524  sub print_printouts { Line 4000  sub print_printouts {
                          A6        => &mt('A6').' [105x148 mm]',                           A6        => &mt('A6').' [105x148 mm]',
                        },                         },
             order => ['Letter','Legal','Tabloid','Executive','A2','A3','A4','A5','A6'],              order => ['Letter','Legal','Tabloid','Executive','A2','A3','A4','A5','A6'],
             nullval => 'None specified',              nullval => &mt('None specified'),
                               },                                },
         print_header_format => {          print_header_format => {
             text => '<b>'.&mt($itemtext->{'print_header_format'}).'</b>',              text => '<b>'.&mt($itemtext->{'print_header_format'}).'</b>',
Line 2534  sub print_printouts { Line 4010  sub print_printouts {
             text => '<b>'.&mt($itemtext->{'disableexampointprint'}).'</b>',              text => '<b>'.&mt($itemtext->{'disableexampointprint'}).'</b>',
             input => 'radio',              input => 'radio',
                                  },                                   },
           canuse_pdfforms => {
               text  => '<b>'.&mt($itemtext->{'canuse_pdfforms'}).'</b>',
               input => 'selectbox',
               options => {
                            1    => &mt('Yes'),
                            0    => &mt('No'),
                          },
               order => ['1','0'],
               nullval => &mt('None specified - use domain default'),
                       }
     );      );
     return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype);      return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype,'printouts');
 }  }
   
 sub print_spreadsheet {  sub print_spreadsheet {
Line 2571  sub print_spreadsheet { Line 4057  sub print_spreadsheet {
             input => 'radio',              input => 'radio',
                          },                           },
                 );                  );
     return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype);      return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype,'spreadsheet');
 }  }
   
 sub print_bridgetasks {  sub print_bridgetasks {
Line 2613  sub print_bridgetasks { Line 4099  sub print_bridgetasks {
              input => 'radio',               input => 'radio',
                                   },                                    },
                 );                  );
     return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype);      return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype,'bridgetasks');
 }  }
   
 sub print_other {  sub print_other {
Line 2638  sub print_other { Line 4124  sub print_other {
                             input => 'textbox',                              input => 'textbox',
                             size  => '30',                              size  => '30',
                            };                             };
     my $output = &make_item_rows($cdom,\%items,\@ordered,$settings,$rowtotal,$crstype);      my $output = &make_item_rows($cdom,\%items,\@ordered,$settings,$rowtotal,$crstype,'other');
 }  }
   
 sub get_other_items {  sub get_other_items {
Line 2655  sub get_other_items { Line 4141  sub get_other_items {
             unless (($parameter =~ m/^internal\./)||($parameter =~ m/^metadata\./) ||              unless (($parameter =~ m/^internal\./)||($parameter =~ m/^metadata\./) ||
                     ($parameter =~ m/^selfenroll_/) || ($parameter =~ /_selfenroll$/)                      ($parameter =~ m/^selfenroll_/) || ($parameter =~ /_selfenroll$/)
                     || ($parameter eq 'type') ||                      || ($parameter eq 'type') ||
                     ($parameter =~ m/^(cc|co|in|ta|ep|ad|st)\.plaintext$/)) {                      ($parameter =~ m/^(cc|co|in|ta|ep|ad|st)\.plaintext$/)
                       || ($parameter =~ m/^discussion_post_fonts/) ||
                       ($parameter =~ m{^(minimal|updated|uploaded|external)syllabus$}) ||
                       ($parameter eq 'clonedfrom')) {
                 push(@ordered,$parameter);                  push(@ordered,$parameter);
             }              }
         }          }
Line 2664  sub get_other_items { Line 4153  sub get_other_items {
 }  }
   
 sub item_table_row_start {  sub item_table_row_start {
     my ($text,$count) = @_;      my ($text,$count,$add_class,$colspan) = @_;
     my $output;      my $output;
     if ($count%2) {      my $css_class = ($count % 2) ? 'LC_odd_row' : 'LC_even_row';
         $output .= '<tr class="LC_odd_row">';      $css_class = (join(' ',$css_class,$add_class)) unless ($add_class eq '');
       $output .= '<tr class="'.$css_class.'">'."\n".
                  '<td class="LC_left_item">'.$text.
                  '</td>';
       if ($colspan) {
           $output .= '<td class="LC_right_item" colspan="'.$colspan.'">';
     } else {      } else {
         $output .= '<tr>';          $output .= '<td class="LC_right_item">';
     }      }
     $output .= '<td class="LC_left_item">'.$text.  
                '</td><td class="LC_right_item" align="right">';  
     return $output;      return $output;
 }  }
   
Line 2681  sub item_table_row_end { Line 4173  sub item_table_row_end {
 }  }
   
 sub yesno_radio {  sub yesno_radio {
     my ($item,$settings) = @_;      my ($item,$settings,$unsetdefault,$valueyes,$valueno) = @_;
     my $itemon = ' ';      my $itemon = ' ';
     my $itemoff = ' checked="checked" ';      my $itemoff = ' checked="checked" ';
       if (($valueyes eq '') && ($valueno eq '')) {
           $valueyes = 'yes';
           $valueno = '';
       }
     if (ref($settings) eq 'HASH') {      if (ref($settings) eq 'HASH') {
         if ($settings->{$item} eq 'yes') {          if ($settings->{$item} eq $valueyes) {
             $itemon = $itemoff;              $itemon = $itemoff;
             $itemoff = ' ';              $itemoff = ' ';
         }          }
           unless (exists($settings->{$item})) {
               if ($unsetdefault eq $valueyes) {
                   $itemon = $itemoff;
                   $itemoff = ' ';
               }
           }
     }      }
     return '<span class="LC_nobreak"><label>'.      return '<span class="LC_nobreak"><label>'.
            '<input type="radio" name="'.$item.'"'.             '<input type="radio" name="'.$item.'"'.
            $itemon.' value="yes" />'.&mt('Yes').'</label>&nbsp;'.             $itemon.' value="'.$valueyes.'" />'.&mt('Yes').'</label>&nbsp;'.
            '<label><input type="radio" name="'.$item.'"'.             '<label><input type="radio" name="'.$item.'"'.
            $itemoff.' value="" />'.&mt('No').'</label></span>';             $itemoff.' value="'.$valueno.'" />'.&mt('No').'</label></span>';
 }  }
   
 sub select_from_options {  sub select_from_options {
Line 2743  sub select_from_options { Line 4245  sub select_from_options {
 }  }
   
 sub make_item_rows {  sub make_item_rows {
     my ($cdom,$items,$ordered,$settings,$rowtotal,$crstype) = @_;      my ($cdom,$items,$ordered,$settings,$rowtotal,$crstype,$caller) = @_;
     my $datatable;      my $datatable;
     if ((ref($items) eq 'HASH') && (ref($ordered) eq 'ARRAY')) {      if ((ref($items) eq 'HASH') && (ref($ordered) eq 'ARRAY')) {
         my $count = 0;          my $count = 0;
         foreach my $item (@{$ordered}) {          foreach my $item (@{$ordered}) {
             $count ++;              $count ++;
             $datatable .= &item_table_row_start($items->{$item}{text},$count);              my $colspan;
             if ($item eq 'nothideprivileged') {              if ((($caller eq 'classlists') && ($item eq 'nothideprivileged')) ||
                   (($caller eq 'printouts') && ($item ne 'print_header_format'))) {
                   $colspan = 2;
               }
               if (exists $items->{$item}{advanced} && $items->{$item}{advanced} == 1) {
                   $datatable .= &item_table_row_start($items->{$item}{text},$count,"advanced",$colspan);
               } else {
                   $datatable .= &item_table_row_start($items->{$item}{text},$count,undef,$colspan);
               }
               if ($item eq 'defaultcredits') {
                   my $defaultcredits = $env{'course.'.$env{'request.course.id'}.'.internal.defaultcredits'};
                   my $showcredits;
                   if ($defaultcredits ne '') {
                       $showcredits = &mt('Default is [quant,_1,credit]',$defaultcredits);
                   } else {
                       $showcredits = &mt('No default set');
                   }
                   $datatable .= $showcredits;
               } elsif ($item eq 'nothideprivileged') {
                 $datatable .= &nothidepriv_row($cdom,$item,$settings,$crstype);                  $datatable .= &nothidepriv_row($cdom,$item,$settings,$crstype);
               } elsif ($item eq 'checkforpriv') {
                   $datatable .= &checkforpriv_row($cdom,$item,$settings,$crstype);
             } elsif ($item eq 'print_header_format') {              } elsif ($item eq 'print_header_format') {
                 $datatable .= &print_hdrfmt_row($item,$settings);                  $datatable .= &print_hdrfmt_row($item,$settings);
             } elsif ($items->{$item}{input} eq 'dates') {              } elsif ($items->{$item}{input} eq 'dates') {
Line 2759  sub make_item_rows { Line 4281  sub make_item_rows {
                    &Apache::lonhtmlcommon::date_setter('display',$item,                     &Apache::lonhtmlcommon::date_setter('display',$item,
                                                        $settings->{$item});                                                         $settings->{$item});
             } elsif ($items->{$item}{input} eq 'radio') {              } elsif ($items->{$item}{input} eq 'radio') {
                 $datatable .= &yesno_radio($item,$settings);                  my ($unsetdefault,$valueyes,$valueno);
                   if (($item eq 'usejsme') || ($item eq 'uselcmath')) {
                        my %domdefs = &Apache::lonnet::get_domain_defaults($cdom);
                        unless ($domdefs{$item} eq '0') {
                            $unsetdefault = 1;
                        }
                        $valueyes = "1";
                        $valueno = "0";
                   }
                   $datatable .= &yesno_radio($item,$settings,$unsetdefault,$valueyes,$valueno);
             } elsif ($items->{$item}{input} eq 'selectbox') {              } elsif ($items->{$item}{input} eq 'selectbox') {
                 my $curr = $settings->{$item};                  my $curr = $settings->{$item};
                 $datatable .=                  $datatable .=
Line 2783  sub make_item_rows { Line 4314  sub make_item_rows {
 sub nothidepriv_row {  sub nothidepriv_row {
     my ($cdom,$item,$settings,$crstype) = @_;      my ($cdom,$item,$settings,$crstype) = @_;
     my ($cnum) = &get_course();      my ($cnum) = &get_course();
     my %nothide;      my ($datatable,%nothide,@checkdoms);
     my $datatable;  
     if (ref($settings) eq 'HASH') {      if (ref($settings) eq 'HASH') {
         if ($settings->{$item} ne '') {          if ($settings->{$item} ne '') {
             foreach my $user (split(/\s*\,\s*/,$settings->{$item})) {              foreach my $user (split(/\s*\,\s*/,$settings->{$item})) {
Line 2795  sub nothidepriv_row { Line 4325  sub nothidepriv_row {
                 }                  }
             }              }
         }          }
           if ($settings->{'checkforpriv'}) {
               @checkdoms = split(/,/,$settings->{'checkforpriv'});
           }
     }      }
     my %coursepersonnel = &Apache::lonnet::dump('nohist_userroles',$cdom,$cnum);      push(@checkdoms,$cdom);
     my $now = time;      my %coursepersonnel =
           &Apache::lonnet::get_my_roles($cnum,$cdom,'',['previous','future','active']);
     my @privusers;      my @privusers;
     my %privileged;  
     foreach my $person (keys(%coursepersonnel)) {      foreach my $person (keys(%coursepersonnel)) {
         my ($role,$user,$usec) = ($person =~ /^([^:]*):([^:]+:[^:]+):([^:]*)/);          my ($uname,$udom,$role) = split(/:/,$person);
         $user =~ s/:$//;          my $user = $uname.':'.$udom;
         my ($end,$start) = split(/:/,$coursepersonnel{$person});          my ($start,$end) = split(/:/,$coursepersonnel{$person});
         if ($end == -1 || $start == -1) {          if ($end == -1 || $start == -1) {
             next;              next;
         }          }
         my ($uname,$udom) = split(':',$user);          foreach my $dom (@checkdoms) {
         unless (ref($privileged{$udom}) eq 'HASH') {              if (&Apache::lonnet::privileged($uname,$udom,\@checkdoms,['dc','su'])) {
             my %dompersonnel = &Apache::lonnet::get_domain_roles($udom,['dc'],undef,$now);                  unless (grep(/^\Q$user\E$/,@privusers)) {
             $privileged{$udom} = {};                      push(@privusers,$user);
             if (keys(%dompersonnel)) {  
                 foreach my $server (keys(%dompersonnel)) {  
                     foreach my $user (sort(keys(%{$dompersonnel{$server}}))) {  
                         my ($trole,$uname,$udom) = split(/:/,$user);   
                         $privileged{$udom}{$uname} = $trole;  
                     }  
                 }                  }
             }              }
         }          }
         if (exists($privileged{$udom}{$uname})) {  
             unless (grep(/^\Q$user\E$/,@privusers)) {  
                 push(@privusers,$user);  
             }  
         }  
     }      }
     if (@privusers) {      if (@privusers > 0) {
         $datatable .= '<table align="right">';          $datatable .= '<table align="right">';
         foreach my $user (sort(@privusers)) {          foreach my $user (sort(@privusers)) {
             my $hideon = ' checked="checked" ';              my $hideon = ' checked="checked" ';
Line 2844  sub nothidepriv_row { Line 4366  sub nothidepriv_row {
                           '<span class="LC_nobreak"><label>'.                            '<span class="LC_nobreak"><label>'.
                           '<input type="radio" name="'.$item.'_'.$user.'"'.                            '<input type="radio" name="'.$item.'_'.$user.'"'.
                           $hideon.' value="" />'.&mt('Hidden').'</label>&nbsp;'.                            $hideon.' value="" />'.&mt('Hidden').'</label>&nbsp;'.
                           '<label><input type="radio" name="'.$item.'_'.$user.'"'.                          $hideoff.' value="yes" />'.&mt('Shown').'</label></span></td>'.                            '<label><input type="radio" name="'.$item.'_'.$user.'"'.
                             $hideoff.' value="yes" />'.&mt('Shown').'</label></span></td>'.
                           '</tr>';                            '</tr>';
         }          }
         $datatable .= '</table>';          $datatable .= '</table>';
Line 2858  sub nothidepriv_row { Line 4381  sub nothidepriv_row {
     return $datatable;      return $datatable;
 }  }
   
   sub checkforpriv_row {
       my ($cdom,$item,$settings,$crstype) = @_;
       my $datatable;
       my %domains=map { $_ => 1; } &Apache::lonnet::all_domains();
       if (keys(%domains) == 1) {
           $datatable = '</td><td align="right">'.
                        &mt("Course's domain is only domain");
           return $datatable;
       }
       my @excdoms = ($cdom);
       my $num = 0;
       if ($settings->{$item} eq '') {
           $datatable = '</td><td align="right">'.
                        &Apache::loncommon::select_dom_form('','checkforpriv_'.$num,
                                                            1,1,undef,undef,\@excdoms);
       } else {
           my @privdoms = split(/,/,$settings->{$item});
           my %domains=map { $_ => 1; } &Apache::lonnet::all_domains();
           $datatable = '</td><td align="right"><br />'.
                        &Apache::loncommon::start_data_table();
           if (@privdoms > 0) {
               foreach my $currdom (@privdoms) {
                   next unless ($domains{$currdom});
                   my $domdesc = &Apache::lonnet::domain($currdom,'description');
                   if ($domdesc eq '') {
                       $domdesc = $currdom;
                   }
                   $datatable .=
                       &Apache::loncommon::start_data_table_row().
                       '<td align="left"><span class="LC_nobreak">'.
                       &mt('Domain:').'<b>&nbsp;'.$domdesc.
                       '</b><input type="hidden" name="checkforpriv_'.$num.
                       '" value="'.$currdom.'" /></span><br />'.
                       '<span class="LC_nobreak"><label><input type="checkbox" '.
                       'name="checkforpriv_delete" value="'.$num.'" />'.
                       &mt('Delete').'</label></span></td>'.
                       &Apache::loncommon::end_data_table_row();
                   $num ++;
                   unless (grep(/^\Q$currdom\E$/,@excdoms)) {
                       push(@excdoms,$currdom);
                   }
               }
           }
           if ((scalar(keys(%domains)) - scalar(@excdoms)) > 0) {
               $datatable .=
                   &Apache::loncommon::start_data_table_row().
                   '<td align="left"><span class="LC_nobreak">'.
                   &mt('Additional domain:'). '</span><br />'.
                   &Apache::loncommon::select_dom_form('','checkforpriv_'.$num,1,
                                                       1,undef,undef,\@excdoms).
                   '</td>'.&Apache::loncommon::end_data_table_row();
           }
           $datatable .= &Apache::loncommon::end_data_table().
                         '<input type="hidden" name="checkforpriv_total" value="'.$num.'" />'.
                         '<br />';
       }
       return $datatable;
   }
   
 sub print_hdrfmt_row {  sub print_hdrfmt_row {
     my ($item,$settings) = @_;      my ($item,$settings) = @_;
     my @curr;      my @curr;
Line 2930  function getIndexByName(item) { Line 4512  function getIndexByName(item) {
 </script>  </script>
   
 ENDJS  ENDJS
     $output .= $currstr.'<table class="LC_nested_outer">';      $output .= '</td><td align="right"><br />'.
                  $currstr.'<table class="LC_data_table">';
     if (@curr > 0) {      if (@curr > 0) {
         for (my $i=0; $i<@curr; $i++) {          for (my $i=0; $i<@curr; $i++) {
             my $pos = $i+1;              my $pos = $i+1;
Line 2970  ENDJS Line 4553  ENDJS
                '<input type="hidden" name="printfmthdr_maxnum" value="'.                 '<input type="hidden" name="printfmthdr_maxnum" value="'.
                 $maxnum.'" /></td>'.                  $maxnum.'" /></td>'.
                '</tr>'.                 '</tr>'.
                '</table>';                  '</table><br />';
     return $output;      return $output;
 }  }
   
Line 3005  sub substitution_selector { Line 4588  sub substitution_selector {
                     a => 'assignment note',                      a => 'assignment note',
              );               );
     my $output .= &mt('Substitution').'<br />'.      my $output .= &mt('Substitution').'<br />'.
                   '<select name=""printfmthdr_sub__'.$num.'">';                    '<select name="printfmthdr_sub_'.$num.'">';
     if ($subst eq '') {      if ($subst eq '') {
         $output .= '<option value="" selected="selected"> </option>';          $output .= '<option value="" selected="selected"> </option>';
     }      }
Line 3037  sub change_clone { Line 4620  sub change_clone {
         foreach my $currclone (@allowclone) {          foreach my $currclone (@allowclone) {
             if (!grep(/^$currclone$/,@$oldcloner)) {              if (!grep(/^$currclone$/,@$oldcloner)) {
                 if ($currclone ne '*') {                  if ($currclone ne '*') {
                     my ($uname,$udom) = split(/:/,$currclone);                      if ($currclone =~ /:/) {
                     if ($uname && $udom && $uname ne '*') {                          my ($uname,$udom) = split(/:/,$currclone);
                         if (&Apache::lonnet::homeserver($uname,$udom) ne 'no_host') {                          if ($uname && $udom && $uname ne '*') {
                             my %currclonecrs = &Apache::lonnet::dump('environment',$udom,$uname,'cloneable');                              if (&Apache::lonnet::homeserver($uname,$udom) ne 'no_host') {
                             if ($currclonecrs{'cloneable'} !~ /\Q$clone_crs\E/) {                                  my %currclonecrs = &Apache::lonnet::dump('environment',$udom,$uname,'cloneable');
                                 if ($currclonecrs{'cloneable'} eq '') {                                  if ($currclonecrs{'cloneable'} !~ /\Q$clone_crs\E/) {
                                     $currclonecrs{'cloneable'} = $clone_crs;                                      if ($currclonecrs{'cloneable'} eq '') {
                                 } else {                                          $currclonecrs{'cloneable'} = $clone_crs;
                                     $currclonecrs{'cloneable'} .= ','.$clone_crs;                                      } else {
                                           $currclonecrs{'cloneable'} .= ','.$clone_crs;
                                       }
                                       &Apache::lonnet::put('environment',\%currclonecrs,$udom,$uname);
                                 }                                  }
                                 &Apache::lonnet::put('environment',\%currclonecrs,$udom,$uname);  
                             }                              }
                         }                          }
                     }                      }
Line 3057  sub change_clone { Line 4642  sub change_clone {
         foreach my $oldclone (@$oldcloner) {          foreach my $oldclone (@$oldcloner) {
             if (!grep(/^\Q$oldclone\E$/,@allowclone)) {              if (!grep(/^\Q$oldclone\E$/,@allowclone)) {
                 if ($oldclone ne '*') {                  if ($oldclone ne '*') {
                     my ($uname,$udom) = split(/:/,$oldclone);                      if ($oldclone =~ /:/) {
                     if ($uname && $udom && $uname ne '*' ) {                          my ($uname,$udom) = split(/:/,$oldclone);
                         if (&Apache::lonnet::homeserver($uname,$udom) ne 'no_host') {                          if ($uname && $udom && $uname ne '*' ) {
                             my %currclonecrs = &Apache::lonnet::dump('environment',$udom,$uname,'cloneable');                              if (&Apache::lonnet::homeserver($uname,$udom) ne 'no_host') {
                             my %newclonecrs = ();                                  my %currclonecrs = &Apache::lonnet::dump('environment',$udom,$uname,'cloneable');
                             if ($currclonecrs{'cloneable'} =~ /\Q$clone_crs\E/) {                                  my %newclonecrs = ();
                                 if ($currclonecrs{'cloneable'} =~ /,/) {                                  if ($currclonecrs{'cloneable'} =~ /\Q$clone_crs\E/) {
                                     my @currclonecrs = split/,/,$currclonecrs{'cloneable'};                                      if ($currclonecrs{'cloneable'} =~ /,/) {
                                     foreach my $crs (@currclonecrs) {                                          my @currclonecrs = split/,/,$currclonecrs{'cloneable'};
                                         if ($crs ne $clone_crs) {                                          foreach my $crs (@currclonecrs) {
                                             $newclonecrs{'cloneable'} .= $crs.',';                                              if ($crs ne $clone_crs) {
                                                   $newclonecrs{'cloneable'} .= $crs.',';
                                               }
                                         }                                          }
                                           $newclonecrs{'cloneable'} =~ s/,$//;
                                       } else {
                                           $newclonecrs{'cloneable'} = '';
                                     }                                      }
                                     $newclonecrs{'cloneable'} =~ s/,$//;                                      &Apache::lonnet::put('environment',\%newclonecrs,$udom,$uname);
                                 } else {  
                                     $newclonecrs{'cloneable'} = '';  
                                 }                                  }
                                 &Apache::lonnet::put('environment',\%newclonecrs,$udom,$uname);  
                             }                              }
                         }                          }
                     }                      }

Removed from v.1.8.2.8  
changed lines
  Added in v.1.49.2.18


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