--- loncom/interface/lonmodifycourse.pm	2007/10/03 19:57:29	1.33
+++ loncom/interface/lonmodifycourse.pm	2009/05/08 17:22:17	1.44
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # handler for DC-only modifiable course settings
 #
-# $Id: lonmodifycourse.pm,v 1.33 2007/10/03 19:57:29 raeburn Exp $
+# $Id: lonmodifycourse.pm,v 1.44 2009/05/08 17:22:17 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -33,7 +33,7 @@ use Apache::lonnet;
 use Apache::loncommon;
 use Apache::lonhtmlcommon;
 use Apache::lonlocal;
-use Apache::londropadd;
+use Apache::lonuserutils;
 use Apache::lonpickcourse;
 use LONCAPA::Enrollment;
 use lib '/home/httpd/lib/perl';
@@ -43,6 +43,22 @@ sub get_dc_settable {
     return ('courseowner','coursecode','authtype','autharg');
 }
 
+sub catalog_settable {
+    my ($confhash) = @_;
+    my @settable;
+    if (ref($confhash) eq 'HASH') {
+        if ($confhash->{'togglecats'} ne 'crs') {
+            push(@settable,'togglecats');
+        }
+        if ($confhash->{'categorize'} ne 'crs') {
+            push(@settable,'categorize');
+        }
+    } else {
+        push(@settable,('togglecats','categorize'));
+    }
+    return @settable;
+}
+
 sub get_enrollment_settings {
     my ($cdom,$cnum) = @_;
     my %settings = &Apache::lonnet::dump('environment',$cdom,$cnum);
@@ -102,30 +118,21 @@ sub print_course_search_page {
     &print_header($r);
     my $filterlist = ['descriptfilter',
                       'instcodefilter','ownerfilter',
-                      'ownerdomfilter','coursefilter'];
+                      'coursefilter'];
     my $filter = {};
+    my $numtitles;
     my $type = 'Course';
     my $action = '/adm/modifycourse';
     my $cctitle = &Apache::lonnet::plaintext('cc',$type);
     my $dctitle = &Apache::lonnet::plaintext('dc');
-    my %lt=&Apache::lonlocal::texthash(
-                    'some' => "Certain settings which control auto-enrollment of students from your institution's student information system.",
-                    'crqo' => 'The total disk space allocated for storage of portfolio files in all groups in a course.',
-                    'tmod' => 'To view or modify these settings use the criteria below to select a course from this domain.',
-    );
-    $r->print('<h3>'.
-              &mt('Course settings which only a [_1] may modify.'
-                  ,$dctitle).'</h3>'.
-              &mt('Although almost all course settings can be modified by a [_1], a number of settings exist which only a [_2] may change:',$cctitle,$dctitle).'
-<ul>
-  <li>'.$lt{'some'}.'</li>
-  <li>'.$lt{'crqo'}.'</li>
-</ul>'.
-$lt{'tmod'}.' ('.$domdesc.')
-<br /><br />
-    ');
+    $r->print(
+        '<h3>'.&mt('Search for a course in the [_1] domain',$domdesc).'</h3>'.
+        &mt('Actions available after searching for a course:').'<ul>'.  
+        '<li>'.&mt('Enter the course with the role of [_1]',$cctitle).'</li>'."\n".
+        '<li>'.&mt('View or modify course settings which only a [_1] may modify.'
+                  ,$dctitle).'</li>'."\n".'</ul>');
     $r->print(&Apache::lonpickcourse::build_filters($filterlist,$type,
-                             undef,undef,$filter,$action,'modifycourse'));
+                             undef,undef,$filter,$action,\$numtitles,'modifycourse'));
 }
 
 sub print_course_selection_page {
@@ -149,21 +156,25 @@ sub print_course_selection_page {
     $filter{'domainfilter'} = $dom;
     my %courses = &Apache::lonpickcourse::search_courses($r,$type,0,
                                                          \%filter);
-    if (keys(%courses) > 0) {
-        $r->print(&mt("Click a 'Select' button to view or modify settings for a [_1] which may only be modified by a [_2] in this domain.",lc($type),$dctitle).'<br /><br />');
-    }
-
-    &Apache::lonpickcourse::display_matched_courses($r,$type,0,$action,
+    &Apache::lonpickcourse::display_matched_courses($r,$type,0,$action,undef,
                                                     %courses);
     return;
 }
 
 sub print_modification_menu {
-    my ($r,$cdesc) = @_;
+    my ($r,$cdesc,$domdesc,$dom) = @_;
     &print_header($r,$cdesc);
+    my $type = 'Course';
+    my $action = '/adm/modifycourse';
+    my $cctitle = &Apache::lonnet::plaintext('cc',$type);
+    my $dctitle = &Apache::lonnet::plaintext('dc');
+    my %lt=&Apache::lonlocal::texthash(
+                    'some' => "Certain settings which control auto-enrollment of students from your institution's student information system.",
+                    'crqo' => 'The total disk space allocated for storage of portfolio files in all groups in a course.',
+    );
     my @menu =
         (
-          { text  => 'Modify quota for group portfolio files',
+          { text  => 'Modify quota for group portfolio',
             phase => 'setquota',
             },
           { text  => 'Display current settings for automated enrollment',
@@ -171,11 +182,32 @@ sub print_modification_menu {
             },
           { text => 'Modify institutional code, course owner and/or default authentication',
             phase => 'setparms',
-            }
+          },
          );
+    my %domconf = &Apache::lonnet::get_dom('configuration',['coursecategories'],$dom);
+    my @additional_params = &catalog_settable($domconf{'coursecategories'});
+    if (@additional_params > 0) {
+        push (@menu, { text => 'Modify course catalog settings for course',
+                       phase => 'catsettings',
+                     });
+    }
     my $menu_html = '<h3>'.&mt('View/Modify settings for: ').$cdesc.'</h3>'."\n".
-                    '<form name="menu" method="post" action="/adm/modifycourse" />'."\n".
-                     &hidden_form_elements();
+              &mt('Although almost all course settings can be modified by a [_1], a number of settings exist which only a [_2] may change:',$cctitle,$dctitle).'
+<ul>
+  <li>'.$lt{'some'}.'</li>
+  <li>'.$lt{'crqo'}.'</li>'."\n";
+    foreach my $item (@additional_params) {
+        if ($item eq 'togglecats') {
+            $menu_html .= '  <li>'.&mt('Hiding a course from the course catalog (can be [_1]configured[_2] to be modifiable in course context)','<a href="/adm/domainprefs?actions=coursecategories&phase=display">','</a>').'</li>'."\n";
+        } elsif ($item eq 'categorize') {
+            $menu_html .= '  <li>'.&mt('Manual cataloging of a course (can be [_1]configured[_2] to be modifiable in course context)','<a href="/adm/domainprefs?actions=coursecategories&phase=display">','</a>').'</li>'."\n";
+
+        }
+    }
+    $menu_html .= ' </ul>
+<form name="menu" method="post" action="'.$action.'" />'."\n".
+    &hidden_form_elements();
+
     foreach my $menu_item (@menu) {
         $menu_html.='<p>';
         $menu_html.='<font size="+1">';
@@ -189,6 +221,16 @@ sub print_modification_menu {
     return;
 }
 
+sub print_ccrole_selected {
+    my ($r,$cdesc,$domdesc) = @_;
+    &print_header($r);
+    my ($cdom,$cnum) = split(/_/,$env{'form.pickedcourse'});
+    $r->print('<form name="ccrole" method="post" action="/adm/roles">
+<input type="hidden" name="selectrole" value="1" />
+<input type="hidden" name="newrole" value="cc./'.$cdom.'/'.$cnum.'" />
+</form>');
+}
+
 sub print_settings_display {
     my ($r,$cdom,$cnum,$cdesc,$type) = @_;
     my %enrollvar = &get_enrollment_settings($cdom,$cnum);
@@ -228,7 +270,7 @@ sub print_settings_display {
     $disp_table .= &Apache::loncommon::end_data_table()."\n";
     &print_header($r,$cdesc);
     $r->print('
-<h3>'.$lt{'caes'}.'</h3>
+<h3>'.$lt{'caes'}.$cdesc.'</h3>
 <p>
 <form action="/adm/modifycourse" method="post" name="viewparms">
 '.$lt{'cose'}.'<ul><li>'.&mt('Settings that can be modified by a [_1] using the <a href="/adm/populate">Automated Enrollment Manager</a>.',$cctitle).'</li><li>'.&mt('Settings that may only be modified by a [_1] from this menu.',$dctitle).'</li></ul>
@@ -239,7 +281,7 @@ sub print_settings_display {
 </p><p>
 <a href="javascript:changePage(document.viewparms,'."'menu'".')">'.$lt{'back'}.'</a>&nbsp;&nbsp;&nbsp;&nbsp;
 <a href="javascript:changePage(document.viewparms,'."'setparms'".')">'.&mt('Modify [_1]-only settings',$dctitle).'</a>'."\n".
-&hidden_form_elements().    
+&hidden_form_elements().
 '</form>');
 }
 
@@ -249,10 +291,10 @@ sub print_setquota {
     my $cctitle = &Apache::lonnet::plaintext('cc',$type);
     my $subdiv = &mt('Although a [_1] will assign the disk quota for each individual group, the size of the quota is constrained by the total disk space allocated by the [_2] for portfolio files in a course.',$cctitle,$dctitle);
     my %lt = &Apache::lonlocal::texthash(
-                'cquo' => 'Disk space for storage of group portfolio files',
+                'cquo' => 'Disk space for storage of group portfolio',
                 'gpqu' => 'Course portfolio files disk space',
                 'each' => 'Each course group can be assigned a quota for portfolio files uploaded to the group.',
-                'modi' => 'Modify quota',
+                'modi' => 'Save',
                 'back' => "Back to options page",
     );
     my %settings = &Apache::lonnet::get('environment',['internal.coursequota'],$cdom,$cnum);
@@ -279,6 +321,59 @@ ENDDOCUMENT
     return;
 }
 
+sub print_catsettings {
+    my ($r,$cdom,$cnum,$cdesc) = @_;
+    &print_header($r,$cdesc);
+    my %lt = &Apache::lonlocal::texthash(
+                                         'back' => 'Back to options page',
+                                        );
+    $r->print('<form action="/adm/modifycourse" method="post" name="catsettings">'.
+              '<h3>'.&mt('Catalog Settings for Course').'</h3>');
+    my %domconf = &Apache::lonnet::get_dom('configuration',['coursecategories'],$cdom);
+    my @cat_params = &catalog_settable($domconf{'coursecategories'});
+    if (@cat_params > 0) {
+        my %currsettings = 
+            &Apache::lonnet::get('environment',['hidefromcat','categories'],$cdom,$cnum);
+        if (grep(/^togglecats$/,@cat_params)) {
+            my $excludeon = '';
+            my $excludeoff = ' checked="checked" ';
+            if ($currsettings{'hidefromcat'} eq 'yes') {
+                $excludeon = $excludeoff;
+                $excludeoff = ''; 
+            }
+            $r->print('<h4>'.&mt('Visibility in Course Catalog').'</h4>'.
+                      &mt("Unless excluded, a course is listed in this domain's publicly accessible course catalog, if at least one of the following applies").':<ul>'.
+                      '<li>'.&mt('Auto-cataloging is enabled and the course is assigned an institutional code').'</li>'.
+                      '<li>'.&mt('The course has been categorized into at least one of the course categories defined for the domain.').'</li></ul>'.
+                      &mt('Exclude from course catalog').'&nbsp;<label><input name="hidefromcat" type="radio" value="yes" '.$excludeon.' />'.&mt('Yes').'</label>&nbsp;&nbsp;&nbsp;<label><input name="hidefromcat" type="radio" value="" '.$excludeoff.' />'.&mt('No').'</label><br />'); 
+        }
+        if (grep(/^categorize$/,@cat_params)) {
+            $r->print('<h4>'.&mt('Categorize Course').'</h4>');
+            if (ref($domconf{'coursecategories'}) eq 'HASH') {
+                my $cathash = $domconf{'coursecategories'}{'cats'};
+                if (ref($cathash) eq 'HASH') {
+                    $r->print(&mt('Assign one or more categories to this course.').'<br /><br />'.
+                              &Apache::loncommon::assign_categories_table($cathash,
+                                                     $currsettings{'categories'}));
+                } else {
+                    $r->print(&mt('No categories defined for this domain'));
+                }
+            } else {
+                $r->print(&mt('No categories defined for this domain'));
+            }
+            $r->print('<p>'.&mt('If auto-cataloging based on institutional code is enabled in the domain, a course will continue to be listed in the catalog of official courses, in addition to receiving a listing under any manually assigned categor(ies).').'</p>');
+        }
+        $r->print('<input type="button" name="chgcatsettings" value="'.
+                  &mt('Save').'" onclick="javascript:changePage(document.catsettings,'."'processcat'".');" />');
+    } else {
+        $r->print('<span class="LC_warning">'.&mt('Catalog settings in this domain are set in course context via "Set Course Environment".').'</span><br /><br />'."\n".
+                  '<a href="javascript:changePage(document.catsettings,'."'menu'".');">'.
+                  $lt{'back'}.'</a>');
+    }
+    $r->print(&hidden_form_elements().'</form>'."\n");
+    return;
+}
+
 sub print_course_modification_page {
     my ($r,$cdom,$cnum,$cdesc,$domdesc) = @_;
     my %longtype = &course_settings_descrip();
@@ -293,7 +388,7 @@ sub print_course_modification_page {
             'name' => "Name",
             'unme' => "Username:Domain",
             'stus' => "Status",
-            'cquo' => "Disk space for storage of group portfolio files",
+            'cquo' => "Disk space for storage of group portfolio",
             'gpqu' => "Course portfolio files disk space",
             'each' => "Each course group can be assigned a quota for portfolio files uploaded to the group.",
             'cose' => "Course settings for LON-CAPA courses that control automated student enrollment based on classlist data available from your institution's student information system fall into two groups: (a) settings that can be modified by a Course Coordinator using the ",
@@ -369,8 +464,8 @@ all settings except course code, course
     unless ($curr_authtype eq '') {
         $curr_authfield = $curr_authtype.'arg';
     }
-    my $javascript_validations=&Apache::londropadd::javascript_validations('modifycourse',$krbdefdom,$curr_authtype,$curr_authfield);
-    my %param = ( formname => 'document.cmod',
+    my $javascript_validations=&Apache::lonuserutils::javascript_validations('modifycourse',$krbdefdom,$curr_authtype,$curr_authfield);
+    my %param = ( formname => 'document.'.$env{'form.phase'},
 	   kerb_def_dom => $krbdefdom,
 	   kerb_def_auth => $krbdef,
            mode => 'modifycourse',
@@ -437,7 +532,7 @@ all settings except course code, course
     my $mainheader = &mt('Course settings modifiable by [_1] only.',$dctitle);
     my $hidden_elements = &hidden_form_elements();
     $r->print(<<ENDDOCUMENT);
-<form action="/adm/modifycourse" method="post" name="cmod">
+<form action="/adm/modifycourse" method="post" name="$env{'form.phase'}">
 <h3>$mainheader</h3>
 </p><p>
 <table width="100%" cellspacing="6" cellpadding="6">
@@ -498,8 +593,9 @@ sub modify_course {
     my @nochanges = ();
     my @sections = ();
     my @xlists = ();
-    my $changecode = 0;
-    my $changeowner = 0;
+    my %changed = ( code       => 0,
+                    owner      => 0,
+                  );
     unless ($settings{'internal.sectionnums'} eq '') {
         if ($settings{'internal.sectionnums'} =~ m/,/) {
             @sections = split/,/,$settings{'internal.sectionnums'};
@@ -522,7 +618,6 @@ sub modify_course {
     }
 
     my $description = $settings{'description'};
-    my %cenv = ();
 
     if ($env{'form.login'} eq 'krb') {
         $newattr{'authtype'} = $env{'form.login'};
@@ -549,28 +644,25 @@ sub modify_course {
     if ( exists($env{'form.courseowner'}) ) {
         $newattr{'courseowner'}=$env{'form.courseowner'};
         unless ( $newattr{'courseowner'} eq $currattr{'courseowner'} ) {
-            $changeowner = 1;
+            $changed{'owner'} = 1;
         } 
     }
 													      
     if ( exists($env{'form.coursecode'}) ) {
         $newattr{'coursecode'}=$env{'form.coursecode'};
         unless ( $newattr{'coursecode'} eq $currattr{'coursecode'} ) {
-            $changecode = 1;
+            $changed{'code'} = 1;
         }
     }
-    if ($changeowner == 1 || $changecode == 1) {
-        my $courseid_entry = &escape($cdom.'_'.$cnum).'='.&escape($description).':'.&escape($env{'form.coursecode'}).':'.&escape($env{'form.courseowner'}).':'.&escape($type);
-        my %courseid_entry = (
-             $cdom.'_'.$cnum => {
-                                description => &escape($description),
-                                inst_code   => &escape($env{'form.coursecode'}),
-                                owner       => &escape($env{'form.courseowner'}),
-                                type        => &escape($type),
-                               },
-        );
-        &Apache::lonnet::courseidput($cdom,\%courseid_entry,
-                                     &Apache::lonnet::homeserver($cnum,$cdom));
+    if ($changed{'owner'} || $changed{'code'}) { 
+        my %crsinfo = &Apache::lonnet::courseiddump($cdom,'.',1,'.','.',$cnum,
+                                                    undef,undef,'.');
+        if (ref($crsinfo{$env{'form.pickedcourse'}}) eq 'HASH') {
+            $crsinfo{$env{'form.pickedcourse'}}{'inst_code'} = $env{'form.coursecode'};
+            $crsinfo{$env{'form.pickedcourse'}}{'owner'} = $env{'form.courseowner'};
+            my $chome = &Apache::lonnet::homeserver($cnum,$cdom);
+            my $putres = &Apache::lonnet::courseidput($cdom,\%crsinfo,$chome,'notime');
+        }
     }
     foreach my $param (@modifiable_params) {
         if ($currattr{$param} eq $newattr{$param}) {
@@ -599,12 +691,12 @@ sub modify_course {
 	            $nochgresponse .= "<li>$longtype{$attr} ".&mt("still set to \"").$currattr{$attr}."\".</li>";
                 }
             }
-            if ($changecode || $changeowner) {
+            if ($changed{'code'} || $changed{'owner'}) {
                 if ( $newattr{'courseowner'} eq '') {
 	            $warning .= &mt("There is no owner associated with this LON-CAPA course.  If automated enrollment in LON-CAPA courses at your institution requires validation of course owners, automated enrollment will fail for this course.<br/>");
                 } else {
 	            if (@sections > 0) {
-                        if ($changecode) {
+                        if ($changed{'code'}) {
 	                    foreach my $sec (@sections) {
 		                if ($sec =~ m/^(.+):/) {
 		                    my $inst_course_id = $newattr{'coursecode'}.$1;
@@ -621,7 +713,7 @@ sub modify_course {
 			            $warning .= &mt("If automatic enrollment is enabled for LON-CAPA course: ").$description.&mt(", automated enrollment may fail for ").$newattr{'coursecode'}.&mt(" - section $sec because this is not a valid section entry.<br/>");
 		                }
 		            }
-	                } elsif ($changeowner) {
+	                } elsif ($changed{'owner'}) {
                             foreach my $sec (@sections) {
                                 if ($sec =~ m/^(.+):/) {
                                     my $inst_course_id = $newattr{'coursecode'}.$1;
@@ -637,7 +729,7 @@ sub modify_course {
 	            } else {
 	                $warning .= &mt("As no section numbers are currently listed for LON-CAPA course: ").$description.&mt(", automated enrollment will not occur for any sections of coursecode: ").$newattr{'coursecode'}."<br/>";
 	            }
-	            if ( (@xlists > 0) && ($changeowner) ) {
+	            if ( (@xlists > 0) && ($changed{'owner'}) ) {
 	                foreach my $xlist (@xlists) {
 		            if ($xlist =~ m/^(.+):/) {
                                 my $outcome = &Apache::lonnet::auto_new_course($cnum,$cdom,$1,$newattr{'courseowner'});
@@ -692,7 +784,7 @@ sub modify_quota {
                                         );
     $r->print('
 <form action="/adm/modifycourse" method="post" name="processquota">
-<h3>'.&mt('Disk space for storage of group portfolio files for [_1]',$cdesc).
+<h3>'.&mt('Disk space for storage of group portfolio for [_1]',$cdesc).
              '</h3>');
     my %oldsettings = &Apache::lonnet::get('environment',['internal.coursequota'],$cdom,$cnum);
     my $defaultquota = 20;
@@ -701,7 +793,7 @@ sub modify_quota {
         if ($newquota =~ /^\s*(\d+\.?\d*|\.\d+)\s*$/) {
             $newquota = $1;
             if ($oldsettings{'internal.coursequota'} eq $env{'form.coursequota'}) {
-                $r->print(&mt('The disk space allocated for group portfolio files remains unchanged as ').$env{'form.coursequota'}.' Mb');
+                $r->print(&mt('The disk space allocated for group portfolio remains unchanged as ').$env{'form.coursequota'}.' Mb');
             } else {
                 my %cenv = (
                            'internal.coursequota' => $env{'form.coursequota'},
@@ -710,11 +802,11 @@ sub modify_quota {
                                                     $cnum);
                 if (($oldsettings{'internal.coursequota'} eq '') && 
                     ($env{'form.coursequota'} == $defaultquota)) {
-                    $r->print(&mt('The disk space allocated for group portfolio files in this course is the default quota for this domain:').' '.$defaultquota.' Mb');
+                    $r->print(&mt('The disk space allocated for group portfolio in this course is the default quota for this domain:').' '.$defaultquota.' Mb');
                 } else {
                     if ($putreply eq 'ok') {
                         my %updatedsettings = &Apache::lonnet::get('environment',['internal.coursequota'],$cdom,$cnum);
-                        $r->print(&mt('The disk space allocated for group portfolio files is now:').' '.$updatedsettings{'internal.coursequota'}.' Mb.');
+                        $r->print(&mt('The disk space allocated for group portfolio is now:').' '.$updatedsettings{'internal.coursequota'}.' Mb.');
                         my $usage = &Apache::longroup::sum_quotas($cdom.'_'.$cnum);
                         if ($usage >= $updatedsettings{'internal.coursequota'}) {
                             my $newoverquota;
@@ -740,6 +832,126 @@ sub modify_quota {
     return;
 }
 
+sub modify_catsettings {
+    my ($r,$cdom,$cnum,$cdesc,$domdesc) = @_;
+    &print_header($r,$cdesc);
+    my %lt = &Apache::lonlocal::texthash(
+                                         'back' => 'Back to options page',
+                                        );
+    my %desc = &Apache::lonlocal::texthash(
+                                           'hidefromcat' => 'Excluded from course catalog',
+                                           'categories' => 'Assigned categories for this course',
+                                          );
+    $r->print('
+<form action="/adm/modifycourse" method="post" name="processcat">
+<h3>'.&mt('Category settings').'</h3>');
+    my %domconf = &Apache::lonnet::get_dom('configuration',['coursecategories'],$cdom);
+    my @cat_params = &catalog_settable($domconf{'coursecategories'});
+    if (@cat_params > 0) {
+        my (%cenv,@changes,@nochanges);
+        my %currsettings =
+            &Apache::lonnet::get('environment',['hidefromcat','categories'],$cdom,$cnum);
+        my (@newcategories,%showitem); 
+        if (grep(/^togglecats$/,@cat_params)) {
+            if ($currsettings{'hidefromcat'} ne $env{'form.hidefromcat'}) {
+                push(@changes,'hidefromcat');
+                $cenv{'hidefromcat'} = $env{'form.hidefromcat'};
+            } else {
+                push(@nochanges,'hidefromcat');
+            }
+            if ($env{'form.hidefromcat'} eq 'yes') {
+                $showitem{'hidefromcat'} = '"'.&mt('Yes')."'";
+            } else {
+                $showitem{'hidefromcat'} = '"'.&mt('No').'"';
+            }
+        }
+        if (grep(/^categorize$/,@cat_params)) {
+            my (@cats,@trails,%allitems,%idx,@jsarray);
+            if (ref($domconf{'coursecategories'}) eq 'HASH') {
+                my $cathash = $domconf{'coursecategories'}{'cats'};
+                if (ref($cathash) eq 'HASH') {
+                    &Apache::loncommon::extract_categories($cathash,\@cats,\@trails,
+                                                           \%allitems,\%idx,\@jsarray);
+                }
+            }
+            @newcategories =  &Apache::loncommon::get_env_multiple('form.usecategory');
+            if (@newcategories == 0) {
+                $showitem{'categories'} = '"'.&mt('None').'"';
+            } else {
+                $showitem{'categories'} = '<ul>';
+                foreach my $item (@newcategories) {
+                    $showitem{'categories'} .= '<li>'.$trails[$allitems{$item}].'</li>';
+                }
+                $showitem{'categories'} .= '</ul>';
+            }
+            my $catchg = 0;
+            if ($currsettings{'categories'} ne '') {
+                my @currcategories = split('&',$currsettings{'categories'});
+                foreach my $cat (@currcategories) {
+                    if (!grep(/^\Q$cat\E$/,@newcategories)) {
+                        $catchg = 1;
+                        last;
+                    }
+                }
+                if (!$catchg) {
+                    foreach my $cat (@newcategories) {
+                        if (!grep(/^\Q$cat\E$/,@currcategories)) {
+                            $catchg = 1;
+                            last;                     
+                        } 
+                    } 
+                }
+            } else {
+                if (@newcategories > 0) {
+                    $catchg = 1;
+                }
+            }
+            if ($catchg) {
+                $cenv{'categories'} = join('&',@newcategories);
+                push(@changes,'categories');
+            } else {
+                push(@nochanges,'categories');
+            }
+            if (@changes > 0) {
+                my $putreply = &Apache::lonnet::put('environment',\%cenv,$cdom,$cnum);
+                if ($putreply eq 'ok') {
+                    my %crsinfo = &Apache::lonnet::courseiddump($cdom,'.',1,'.','.',
+                                                                $cnum,undef,undef,'.');
+                    if (ref($crsinfo{$env{'form.pickedcourse'}}) eq 'HASH') {
+                        if (grep(/^hidefromcat$/,@changes)) {
+                            $crsinfo{$env{'form.pickedcourse'}}{'hidefromcat'} = $env{'form.hidefromcat'};
+                        }
+                        if (grep(/^categories$/,@changes)) {
+                            $crsinfo{$env{'form.pickedcourse'}}{'categories'} = $cenv{'categories'};
+                        }
+                        my $chome = &Apache::lonnet::homeserver($cnum,$cdom);
+                        my $putres = &Apache::lonnet::courseidput($cdom,\%crsinfo,$chome,'notime');
+                    }
+                    $r->print(&mt('The following changes occurred').'<ul>');
+                    foreach my $item (@changes) {
+                        $r->print('<li>'.&mt('[_1] now set to [_2]',$desc{$item},$showitem{$item}).'</li>');
+                    }
+                    $r->print('</ul><br />');
+                }
+            }
+            if (@nochanges > 0) {
+                $r->print(&mt('The following were unchanged').'<ul>');
+                foreach my $item (@nochanges) {
+                    $r->print('<li>'.&mt('[_1] still set to [_2]',$desc{$item},$showitem{$item}).'</li>');
+                }
+                $r->print('</ul>');
+            }
+        }
+    } else {
+        $r->print(&mt('Category settings for courses in this domain should be modified in course context (via "Set Course Environment").').'<br />');
+    }
+    $r->print('<br />'."\n".
+              '<a href="javascript:changePage(document.processcat,'."'menu'".')">'.
+              $lt{'back'}.'</a>');
+    $r->print(&hidden_form_elements().'</form>');
+    return;
+}
+
 sub print_header {
     my ($r,$cdesc,$javascript_validations) = @_;
     my $phase = "start";
@@ -788,13 +1000,23 @@ function verify_quota(formname) {
 </script>
 ENDSCRIPT
     }
+    my $starthash;
+    if ($env{'form.phase'} eq 'ccrole') {
+        $starthash = {
+           add_entries => {'onload' => "javascript:document.ccrole.submit();"},
+                     };
+    }
     $r->print(&Apache::loncommon::start_page('View/Modify Course Settings',
-					     $js));
+					     $js,$starthash));
     my $bread_text = "View/Modify Courses";
     if ($cdesc ne '') {
-        $bread_text = "Course Settings: $cdesc"; 
-    } 
-    $r->print(&Apache::lonhtmlcommon::breadcrumbs($bread_text));
+        $bread_text = &mt('Course Settings: [_1]',$cdesc);
+        my $no_mt = 1;
+        $r->print(&Apache::lonhtmlcommon::breadcrumbs($bread_text,undef,undef,
+                                                      undef,undef,$no_mt));
+    } else {
+        $r->print(&Apache::lonhtmlcommon::breadcrumbs($bread_text));
+    }
     return;
 }
 
@@ -807,31 +1029,36 @@ sub print_footer {
 sub check_course {
     my ($r,$dom,$domdesc) = @_;
     my ($ok_course,$description,$instcode,$owner);
-    if (defined($env{'form.pickedcourse'})) {
-        my ($cdom,$cnum) = split(/_/,$env{'form.pickedcourse'});
-        if ($cdom eq $dom) {
-            my %courseIDs = &Apache::lonnet::courseiddump($cdom,'.',1,'.','.',
-                                               $cnum,undef,undef,'.');
-            if (keys(%courseIDs) > 0) {
-                $ok_course = 'ok';
-                my ($description,$instcode,$owner);
-                if (ref($courseIDs{$cdom.'_'.$cnum}) eq 'HASH') {
-                    $description = $courseIDs{$cdom.'_'.$cnum}{'description'};
-                    $instcode = $courseIDs{$cdom.'_'.$cnum}{'inst_code'};
-                    $owner = $courseIDs{$cdom.'_'.$cnum}{'owner'};          
-                } else {
-                    ($description,$instcode,$owner) = 
-                                       split(/:/,$courseIDs{$cdom.'_'.$cnum});
-                }
-                $description = &unescape($description);
-                $instcode = &unescape($instcode);
-                if ($instcode) {
-                    $description .= " ($instcode)";
-                } 
+    my %args = (
+                 one_time => 1,
+               );
+    my %coursehash = 
+        &Apache::lonnet::coursedescription($env{'form.pickedcourse'},\%args);
+    my $cnum = $coursehash{'num'};
+    my $cdom = $coursehash{'domain'};
+    if ($cdom eq $dom) {
+        my $description;
+        my %courseIDs = &Apache::lonnet::courseiddump($cdom,'.',1,'.','.',
+                                                      $cnum,undef,undef,'.');
+        if (keys(%courseIDs) > 0) {
+            $ok_course = 'ok';
+            my ($instcode,$owner);
+            if (ref($courseIDs{$cdom.'_'.$cnum}) eq 'HASH') {
+                $description = $courseIDs{$cdom.'_'.$cnum}{'description'};
+                $instcode = $courseIDs{$cdom.'_'.$cnum}{'inst_code'};
+                $owner = $courseIDs{$cdom.'_'.$cnum}{'owner'};          
+            } else {
+                ($description,$instcode,$owner) = 
+                                   split(/:/,$courseIDs{$cdom.'_'.$cnum});
             }
+            $description = &unescape($description);
+            $instcode = &unescape($instcode);
+            if ($instcode) {
+                $description .= " ($instcode)";
+            }
+            return ($ok_course,$description);
         }
     }
-    return ($ok_course,$description);
 }
 
 sub course_settings_descrip {
@@ -856,8 +1083,9 @@ sub course_settings_descrip {
 sub hidden_form_elements {
     my $hidden_elements = 
       &Apache::lonhtmlcommon::echo_form_input(['gosearch','coursecode',
-                                               'numlocalcc','courseowner',
-                                               'login','coursequota','intarg',                                               'locarg','krbarg','krbver']);
+          'prevphase','numlocalcc','courseowner','login','coursequota','intarg',
+          'locarg','krbarg','krbver','counter','hidefromcat','usecategory'])."\n".
+          '<input type="hidden" name="prevphase" value="'.$env{'form.phase'}.'" />';
     return $hidden_elements;
 }
 
@@ -877,21 +1105,24 @@ sub handler {
         &Apache::lonhtmlcommon::clear_breadcrumbs();
 
         my $phase = $env{'form.phase'};
-        &Apache::lonhtmlcommon::add_breadcrumb
+        if ($phase eq '') {
+            &Apache::lonhtmlcommon::add_breadcrumb
             ({href=>"/adm/modifycourse",
               text=>"Course search"});
-        if ($phase eq '') {
             &print_course_search_page($r,$dom,$domdesc);
         } else {
+            my $firstform = $phase;
+            if ($phase eq 'courselist') {
+                $firstform = 'filterpicker';
+            } 
             &Apache::lonhtmlcommon::add_breadcrumb
-            ({href=>"javascript:changePage(document.$phase,'courselist')",
+            ({href=>"javascript:changePage(document.$firstform,'')",
+              text=>"Course search"},
+              {href=>"javascript:changePage(document.$phase,'courselist')",
               text=>"Choose a course"});
             if ($phase eq 'courselist') {
                 &print_course_selection_page($r,$dom,$domdesc);
             } else {
-                &Apache::lonhtmlcommon::add_breadcrumb
-                ({href=>"javascript:changePage(document.$phase,'menu')",
-                  text=>"Pick action"});
                 my ($checked,$cdesc) = &check_course($r,$dom,$domdesc);
                 my $type = $env{'form.type'};
                 if ($type eq '') {
@@ -899,14 +1130,25 @@ sub handler {
                 }
                 if ($checked eq 'ok') {
                     if ($phase eq 'menu') {
-                        &print_modification_menu($r,$cdesc);
+                        &Apache::lonhtmlcommon::add_breadcrumb
+                        ({href=>"javascript:changePage(document.$phase,'menu')",
+                          text=>"Pick action"});
+                        &print_modification_menu($r,$cdesc,$domdesc,$dom);
+                    } elsif ($phase eq 'ccrole') {
+                        &Apache::lonhtmlcommon::add_breadcrumb
+                         ({href=>"javascript:changePage(document.$phase,'ccrole')",
+                           text=>"Enter course"});
+                        &print_ccrole_selected($r,$cdesc,$domdesc);
                     } else {
+                        &Apache::lonhtmlcommon::add_breadcrumb
+                        ({href=>"javascript:changePage(document.$phase,'menu')",
+                          text=>"Pick action"});
                         my ($cdom,$cnum) = split(/_/,$env{'form.pickedcourse'});
                         if ($phase eq 'setquota') {
                             &Apache::lonhtmlcommon::add_breadcrumb
                             ({href=>"javascript:changePage(document.$phase,'$phase')",
                               text=>"Set quota"});
-                            &print_setquota($r,$cdom,$cnum,$cdesc,$type)
+                            &print_setquota($r,$cdom,$cnum,$cdesc,$type);
                         } elsif ($phase eq 'processquota') { 
                             &Apache::lonhtmlcommon::add_breadcrumb
                             ({href=>"javascript:changePage(document.$phase,'setquota')",
@@ -933,6 +1175,19 @@ sub handler {
                             ({href=>"javascript:changePage(document.$phase,'$phase')",
                               text=>"Result"});
                             &modify_course($r,$cdom,$cnum,$cdesc,$domdesc,$type);
+                        } elsif ($phase eq 'catsettings') {
+                            &Apache::lonhtmlcommon::add_breadcrumb
+                            ({href=>"javascript:changePage(document.$phase,'$phase')",
+                              text=>"Catalog settings"});
+                            &print_catsettings($r,$cdom,$cnum,$cdesc,$type);
+                        } elsif ($phase eq 'processcat') {
+                            &Apache::lonhtmlcommon::add_breadcrumb
+                            ({href=>"javascript:changePage(document.$phase,'catsettings')",
+                              text=>"Catalog settings"});
+                            &Apache::lonhtmlcommon::add_breadcrumb
+                            ({href=>"javascript:changePage(document.$phase,'$phase')",
+                              text=>"Result"});
+                            &modify_catsettings($r,$cdom,$cnum,$cdesc,$domdesc);
                         }
                     }
                 } else {