--- loncom/interface/courseprefs.pm 2010/11/27 20:51:26 1.34 +++ loncom/interface/courseprefs.pm 2012/12/31 14:50:07 1.49.2.4 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler to set configuration settings for a course # -# $Id: courseprefs.pm,v 1.34 2010/11/27 20:51:26 www Exp $ +# $Id: courseprefs.pm,v 1.49.2.4 2012/12/31 14:50:07 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -215,6 +215,7 @@ use Apache::lonnet; use Apache::loncommon(); use Apache::lonhtmlcommon(); use Apache::lonconfigsettings; +use Apache::lonparmset; use Apache::lonlocal; use LONCAPA qw(:DEFAULT :match); @@ -267,8 +268,8 @@ sub handler { my %lt; if ($crstype eq 'Community') { %lt = ( - conf => 'Community Configuration', - edit => 'Edit Community Configuration', + conf => 'Community Settings', + edit => 'Edit Community Settings', gens => 'General community settings', idnu => 'Community ID or number', desc => 'Community Description', @@ -286,7 +287,7 @@ sub handler { defd => 'Default dates for member access', stuv => 'Member-viewable membership list options', 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', defc => 'Default Community Spreadsheet', defs => 'Default User Spreadsheet', @@ -294,8 +295,8 @@ sub handler { ); } else { %lt = ( - conf => 'Course Configuration', - edit => 'Edit Course Configuration', + conf => 'Course Settings', + edit => 'Edit Course Settings', gens => 'General course settings', idnu => 'Course ID or number', desc => 'Course Description', @@ -313,13 +314,14 @@ sub handler { defd => 'Default dates for student access', stuv => 'Student-viewable classlist options', 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', defc => 'Default Course Spreadsheet', defs => 'Default Student Spreadsheet', seme => 'Send message to student when clicking Done on Tasks', ); } + $lt{'lcrv'} = 'Required LON-CAPA version'; &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/courseprefs', text=>$lt{'conf'}}); my $breadcrumbs = @@ -335,6 +337,14 @@ sub handler { return OK; } + if ($phase eq 'releaseinfo') { + my $loncaparev = $env{'course.'.$cid.'.internal.releaserequired'}; + if ($loncaparev) { + &display_loncaparev_constraints($r,$navmap,$loncaparev,$crstype); + return OK; + } + } + my %values=&Apache::lonnet::dump('environment',$cdom,$cnum); my @prefs_order = ('courseinfo','localization','feedback','discussion', 'classlists','appearance','grading','printouts', @@ -343,10 +353,10 @@ sub handler { my %prefs = ( 'courseinfo' => { text => $lt{'gens'}, - help => 'Course_Environment', - ordered => ['owner','co-owners','description','courseid', - 'categories','hidefromcat','externalsyllabus', - 'cloners','url','rolenames'], + help => 'Course_Prefs_General', + ordered => ['owner','co-owners','loncaparev','description', + 'courseid','categories','hidefromcat', + 'externalsyllabus','cloners','url','rolenames'], itemtext => { 'owner' => $lt{'ownr'}, 'co-owners' => $lt{'cown'}, @@ -358,11 +368,12 @@ sub handler { 'externalsyllabus' => 'URL of Syllabus', 'url' => 'Top Level Map', 'rolenames' => $lt{'rept'}, + 'loncaparev' => $lt{'lcrv'}, }, }, 'localization' => - { text => 'Language and Time Localization', - help => 'Course_Environment', + { text => 'Language and time localization', + help => 'Course_Prefs_Language', ordered => ['languages','timezone','datelocale'], itemtext => { languages => 'Languages used', @@ -372,7 +383,7 @@ sub handler { }, 'feedback' => { text => 'Feedback messages', - help => 'Course_Environment', + help => 'Course_Prefs_Feedback', header => [{col1 => 'Questions about:', col2 => 'Recipients'}], ordered => ['question.email','comment.email','policy.email'], @@ -384,11 +395,12 @@ sub handler { }, 'discussion' => { text => 'Discussion and Chat', - help => 'Course_Environment', + help => 'Course_Prefs_Discussions', ordered => ['pch.roles.denied','pch.users.denied', 'plc.roles.denied','plc.users.denied', 'allow_limited_html_in_feedback', - 'allow_discussion_post_editing'], + 'allow_discussion_post_editing', + 'discussion_post_fonts'], itemtext => { 'pch.roles.denied' => 'No Resource Discussion', 'pch.users.denied' => 'No Resource Discussion', @@ -396,11 +408,12 @@ sub handler { 'plc.users.denied' => 'No Chat room use', allow_limited_html_in_feedback => 'Allow limited HTML in discussion', allow_discussion_post_editing => 'Users can edit/delete own discussion posts', + discussion_post_fonts => 'Discussion post fonts based on likes/unlikes', }, }, 'classlists' => { text => $lt{'clas'}, - help => 'Course_Environment', + help => 'Course_Prefs_Classlists', header => [{col1 => 'Type', col2 => $lt{'defd'}}, {col1 => 'Setting', @@ -422,7 +435,7 @@ sub handler { }, 'appearance' => { text => 'Display of resources ', - help => 'Course_Environment', + help => 'Course_Prefs_Display', ordered => ['default_xml_style','pageseparators', 'disable_receipt_display','texengine', 'tthoptions'], @@ -436,7 +449,7 @@ sub handler { }, 'grading' => { text => 'Grading', - help => 'Course_Environment', + help => 'Course_Prefs_Grading', ordered => ['grading','rndseed', 'receiptalg','disablesigfigs'], itemtext => { @@ -449,22 +462,22 @@ sub handler { }, 'printouts' => { text => 'Printout generation', - help => 'Course_Environment', + help => 'Course_Prefs_Printouts', ordered => ['problem_stream_switch','suppress_tries', 'default_paper_size','print_header_format', - 'disableexampointprint','canuse_pdfforms'], + 'disableexampointprint'], itemtext => { problem_stream_switch => 'Allow problems to be split over pages', suppress_tries => 'Suppress number of tries in printing', default_paper_size => 'Default paper type', 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' => { text => 'Spreadsheets', - help => 'Course_Environment', + help => 'Course_Prefs_Spreadsheet', ordered => ['spreadsheet_default_classcalc', 'spreadsheet_default_studentcalc', 'spreadsheet_default_assesscalc','hideemptyrows'], @@ -477,7 +490,7 @@ sub handler { }, 'bridgetasks' => { text => 'Bridge tasks', - help => 'Course_Environment', + help => 'Course_Prefs_Bridgetasks', ordered => ['task_messages','task_grading', 'suppress_embed_prompt'], itemtext => { @@ -488,7 +501,7 @@ sub handler { }, 'other' => { text => 'Other settings', - help => 'Course_Environment', + help => 'Course_Prefs_Other', header => [ {col1 => 'Item', col2 => 'Value', }], @@ -498,15 +511,15 @@ sub handler { my @allitems = &get_allitems(%prefs); &Apache::lonconfigsettings::make_changes($r,$cdom,$phase,$context, \@prefs_order,\%prefs,\%values, - $cnum,undef,\@allitems); + $cnum,undef,\@allitems,'coursepref'); } elsif ($phase eq 'display') { - my $jscript = &get_jscript($cdom,$phase,$crstype); + my $jscript = &get_jscript($cid,$cdom,$phase,$crstype); my @allitems = &get_allitems(%prefs); &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 { &Apache::lonconfigsettings::display_choices($r,$phase,$context, - \@prefs_order,\%prefs); + \@prefs_order,\%prefs,'coursepref'); } return OK; } @@ -533,11 +546,20 @@ sub print_config_box { my $itemtext = $item->{'itemtext'}; my $rowtotal = 0; my $output = - '
'. + &mt($item->{text}); + if ($item->{'help'}) { + $output .= ' '. + &Apache::loncommon::help_open_topic($item->{'help'}); + } + $output .= ' | '."\n". + '||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
+ ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
+ ||||||||||||||||||||||||||||||||||||||||||||||||||||
'; return ($output,$rowtotal); } @@ -637,7 +671,21 @@ sub process_changes { } } } 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')); + push(@ordered,$entry); + } + } else { + @ordered = @{$item->{'ordered'}}; + } } if (@ordered > 0) { if ($action eq 'feedback') { @@ -945,6 +993,35 @@ sub process_changes { } } $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') { my @curr_nothide; my @new_nothide; @@ -1048,7 +1125,7 @@ sub process_changes { } else { $newvalues{$entry} = $env{'form.'.$entry}; } - unless ($entry eq 'co-owners') { + unless (($entry eq 'co-owners') || ($entry eq 'discussion_post_fonts')) { if ($newvalues{$entry} ne $values->{$entry}) { $changes->{$entry} = $newvalues{$entry}; } @@ -1175,7 +1252,7 @@ sub store_changes { my ($displayname,$text); $text = $prefs->{$item}->{'itemtext'}{$key}; my $displayval; - unless ($key eq 'co-owners') { + unless (($key eq 'co-owners') || ($key eq 'discussion_post_fonts')) { $displayval = $changes->{$item}{$key}; } if ($item eq 'feedback') { @@ -1211,6 +1288,36 @@ sub store_changes { } $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 .= (' 'x2); + } + } } $displayname = &mt($text); } @@ -1310,7 +1417,9 @@ sub store_changes { } } } else { - $storehash{$key} = $changes->{$item}{$key}; + unless ($key eq 'discussion_post_fonts') { + $storehash{$key} = $changes->{$item}{$key}; + } } } if ($key eq 'cloners') { @@ -1334,9 +1443,9 @@ sub store_changes { $output .= ''; } else { if ($crstype eq 'Community') { - $output = &mt('No changes made to community settings.'); + $output .= &mt('No changes made to community settings.'); } else { - $output = &mt('No changes made to course settings.'); + $output .= &mt('No changes made to course settings.'); } } } @@ -1511,9 +1620,9 @@ sub get_course { } sub get_jscript { - my ($cdom,$phase,$crstype) = @_; + my ($cid,$cdom,$phase,$crstype) = @_; my ($can_toggle_cat,$can_categorize) = &can_modify_catsettings($cdom,$crstype); - my ($jscript,$categorize_js); + my ($jscript,$categorize_js,$loncaparev_js); my $stubrowse_js = &Apache::loncommon::studentbrowser_javascript(); my $browse_js = &Apache::loncommon::browser_and_searcher_javascript('parmset'); my $cloners_js = &cloners_javascript($phase); @@ -1530,9 +1639,23 @@ function catsbrowser() { } ENDSCRIPT } + my $loncaparev = $env{'course.'.$cid.'.internal.releaserequired'}; + if ($loncaparev) { + $loncaparev_js = < '. &mt('Owner and Coordinators included automatically'), input => 'textbox', - size => '40', - advanced => 1 + size => '40' }, 'rolenames' => { text => ''.&mt($itemtext->{'rolenames'}).' '. @@ -1709,6 +1831,9 @@ sub print_courseinfo { input => 'textbox', size => '25', }, + 'loncaparev' => { + text => ''.&mt($itemtext->{'loncaparev'}).'', + }, ); my $datatable; my $count = 0; @@ -1846,7 +1971,6 @@ sub print_courseinfo { } else { $owner = &mt('None specified'); } - my $domdesc = &Apache::lonnet::domain($cdom,'description'); $datatable .= $owner; } elsif ($item eq 'co-owners') { my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; @@ -1868,6 +1992,16 @@ sub print_courseinfo { $datatable .= &manage_coownership($cnum,$cdom,@currcoown); } } + } elsif ($item eq 'loncaparev') { + my $loncaparev = $env{'course.'.$env{'request.course.id'}.'.internal.releaserequired'}; + my $showreqd; + if ($loncaparev) { + $showreqd = &mt('[_1] or newer',$loncaparev).' '. + &mt('Details').''; + } else { + $showreqd = &mt('No specific version required'); + } + $datatable .= $showreqd; } else { $datatable .= &Apache::lonhtmlcommon::textbox($item,$settings->{$item},$items{$item}{size}); } @@ -2025,6 +2159,455 @@ ENDSCRIPT return; } +sub display_loncaparev_constraints { + my ($r,$navmap,$loncaparev,$crstype) = @_; + 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', + ); + my (%checkparms,%checkresponsetypes,%checkcrstypes,%anonsurvey,%randomizetry); + &Apache::loncommon::build_release_hashes(\%checkparms,\%checkresponsetypes, + \%checkcrstypes,\%anonsurvey,\%randomizetry); + if (defined($checkcrstypes{$crstype})) { + $output .= ' '.&mt('Course type: [_1] requires [_2] or newer',$crstype, + $checkcrstypes{$crstype}).''; + } + my (%fromparam,%rowspan,%bymap,%byresource,@scopeorder,%toshow,%allmaps, + %byresponsetype,%bysubmission); + @scopeorder = ('all','section/group','user'); + my $resourcedata = &Apache::lonparmset::readdata($cnum,$cdom); + if (ref($resourcedata) eq 'HASH') { + foreach my $key (keys(%{$resourcedata})) { + foreach my $item (keys(%checkparms)) { + if ($key =~ /(\Q$item\E)$/) { + if (ref($checkparms{$item}) eq 'ARRAY') { + my $value = $resourcedata->{$key}; + my ($middle,$scope,$which,$level,$map,$resource); + if (grep(/^\Q$value\E$/,@{$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 .= ''.&mt('Requirements from general settings').''. + &Apache::loncommon::start_data_table(). + &Apache::loncommon::start_data_table_header_row(). + ''.&mt('Release').' | '.&mt('Scope').' | '.
+ ''.&mt('Extent').' | '.&mt('Setting').' | '.
+ &Apache::loncommon::end_data_table_header_row();
+ foreach my $rev (keys(%fromparam)) {
+ $output .= &Apache::loncommon::start_data_table_row().
+ ''.$rev.' | ';
+ my $newrow;
+ foreach my $scope (@scopeorder) {
+ if (ref($fromparam{$rev}{$scope}) eq 'HASH') {
+ if ($newrow) {
+ $output .= &Apache::loncommon::continue_data_table_row();
+ }
+ $output .= ''.$lt{$scope}.' | ';
+ foreach my $which (sort(keys(%{$fromparam{$rev}{$scope}}))) {
+ $output .= ''.$which.' | '.
+ join(' | ';
+ }
+ $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 .= '',@{$fromparam{$rev}{$scope}{$which}}).' '.$lt{$scope}.' | | '.
+ join(' | '.
+ &Apache::loncommon::end_data_table_row();
+ $newrow = 1;
+ }
+ }
+ }
+ $output .= &Apache::loncommon::end_data_table().'',@{$fromparam{$rev}{$scope}}).' '; + } + } + + 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'); + + 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; + } + 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; + } + } + my %responses = $res->responseTypes(); + foreach my $key (keys(%responses)) { + if (exists($checkresponsetypes{$key})) { + push(@{$byresponsetype{$symb}{$checkresponsetypes{$key}}},$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); + my $mapsymb = $mapres->symb(); + $toshow{$mapsymb} = 1; + if (ref($mapres)) { + 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 = ' '. + &mt('Requirements for specific folders or resources'). + ''; + if ((keys(%toshow) > 0) || (keys(%byresource) > 0) || + (keys(%bysubmission) > 0) || (keys(%byresponsetype))) { + $output .= $mapres_header; + } + my $top_header = ''.&mt('LON-CAPA version dependencies').''; + 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(''); + } else { + $r->print(' '. + &mt('No version requirements from resource content or settings.'). + ' '); + } + $r->print(&Apache::loncommon::end_page()); + 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 = '![]() ![]() '.&mt('Location').' | '.&mt('Release').' | '.
+ ''.&mt('Attribute/Setting').' | '.
+ &Apache::loncommon::end_data_table_header_row().
+ &Apache::loncommon::start_data_table_row().
+ ' '.$icon.' '.&mt('Main Course Documents').' | ');
+ &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 = '![]() ![]() '.$indent.$icon.' '.$title.' | ');
+ &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 = '![]() '.$indent.$icon.' '.$title.' | ');
+ 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(''.$rev.' | ');
+ if (ref($byresource->{$symb}{$rev}) eq 'HASH') {
+ $r->print(' | ');
+ $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('
'.$rev.' | ');
+ if (ref($bysubmission->{$symb}{$rev}) eq 'ARRAY') {
+ $r->print(&mt('Submissions to: ').' '.
+ join(', ',@{$bysubmission->{$symb}{$rev}}));
+ }
+ $r->print(' | ');
+ $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(''.$rev.' | ');
+ if (ref($byresponsetype->{$symb}{$rev}) eq 'ARRAY') {
+ $r->print(&mt('Response Type(s): ').' '.
+ join(' | ');
+ }
+ $r->print(&Apache::loncommon::end_data_table_row());
+ }
+ }
+ }
+ }
+ $r->print(&Apache::loncommon::end_data_table());
+ }
+}
+
+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('',@{$byresponsetype->{$symb}{$rev}})); + } + $r->print(' '.$rev.' | ');
+ if (ref($bymap->{$url}{$rev}) eq 'HASH') {
+ $r->print(' | ');
+ }
+ } else {
+ $r->print('
| ');
+ }
+ 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 show_autocoowners {
my (@currcoown) = @_;
my $output = ''.&mt('Co-ownership is set automatically when a Course Coordinator role is assigned to official course personnel (from institutional data).').'';
@@ -2454,6 +3037,11 @@ sub print_discussion {
text => ''.&mt($itemtext->{'allow_discussion_post_editing'}).'',
input => 'checkbox',
},
+ 'discussion_post_fonts' => {
+ text => ''.&mt($itemtext->{'discussion_post_fonts'}).'',
+ input => 'textbox',
+ size => '20',
+ },
);
my $datatable;
my $count;
@@ -2493,6 +3081,17 @@ sub print_discussion {
&Apache::loncommon::end_data_table_row().
&role_checkboxes($cdom,$cnum,$item,$settings,1).
&Apache::loncommon::end_data_table();
+ } elsif ($item eq 'discussion_post_fonts') {
+ $datatable .= &Apache::loncommon::start_data_table().
+ &Apache::loncommon::start_data_table_row().
+ ''.&mt('Sum of likes/dislikes').' | '.
+ ''.&mt('font-size').' | '.
+ ''.&mt('font-weight').' | '.
+ ''.&mt('font-style').' | '.
+ ''.&mt('Other css').' | '.
+ &Apache::loncommon::end_data_table_row().
+ &set_discussion_fonts($cdom,$cnum,$item,$settings).
+ &Apache::loncommon::end_data_table();
}
$datatable .= &item_table_row_end();
}
@@ -2614,6 +3213,75 @@ sub role_checkboxes {
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().
+ ''.$classtitles->{$cat}.' | ';
+ if (ref($styleorder) eq 'ARRAY') {
+ foreach my $item (@{$styleorder}) {
+ $output .= '';
+ my $selitem = $item;
+ if ($item eq 'size') {
+ my ($currsize,$currunit);
+ if ($curr{'size'} =~ /^(\d+)(px|%)$/) {
+ ($currsize,$currunit) = ($1,$2);
+ $curr{'size'} = $currunit;
+ }
+ $output .= ''.
+ ' ';
+ $selitem = 'unit';
+ }
+ if ((ref($styleitems) eq 'HASH') && (ref($styleitems->{$item}) eq 'ARRAY')) {
+ $output .= ' | ';
+ }
+ $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 {
my ($position,$cdom,$settings,$itemtext,$rowtotal,$crstype) = @_;
my @ordered;
@@ -2742,12 +3410,11 @@ sub print_grading {
input => 'selectbox',
options => {
standard => &mt('Standard: shows points'),
- categories => &mt('Categories: shows points according to categories'),
external => &mt('External: shows number of completed parts and totals'),
externalnototals => &mt('External: shows only number of completed parts'),
spreadsheet => &mt('Spreadsheet: (with link to detailed scores)'),
},
- order => ['standard','categories','external','externalnototals','spreadsheet'],
+ order => ['standard','external','externalnototals','spreadsheet'],
},
'rndseed' => {
text => ''.&mt($itemtext->{'rndseed'}).''.
@@ -2764,6 +3431,7 @@ sub print_grading {
'64bit5' => '64bit5',
},
order => ['32bit','64bit','64bit2','64bit3','64bit4','64bit5'],
+ advanced => 1
},
'receiptalg' => {
text => ''.&mt($itemtext->{'receiptalg'}).' | '. @@ -2775,6 +3443,7 @@ sub print_grading { receipt3 => 'receipt3', }, order => ['receipt','receipt2','receipt3'], + advanced => 1 }, 'disablesigfigs' => { text => ''.&mt($itemtext->{'disablesigfigs'}).'', @@ -2954,7 +3623,8 @@ sub get_other_items { unless (($parameter =~ m/^internal\./)||($parameter =~ m/^metadata\./) || ($parameter =~ m/^selfenroll_/) || ($parameter =~ /_selfenroll$/) || ($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/)) { push(@ordered,$parameter); } } @@ -3046,7 +3716,11 @@ sub make_item_rows { my $count = 0; foreach my $item (@{$ordered}) { $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"); + } else { + $datatable .= &item_table_row_start($items->{$item}{text},$count); + } if ($item eq 'nothideprivileged') { $datatable .= ¬hidepriv_row($cdom,$item,$settings,$crstype); } elsif ($item eq 'print_header_format') { |