Annotation of loncom/interface/courseprefs.pm, revision 1.20
1.1 raeburn 1: # The LearningOnline Network with CAPA
1.2 raeburn 2: # Handler to set configuration settings for a course
1.1 raeburn 3: #
1.16 faziophi 4: # $Id: courseprefs.pm,v 1.15 2010/01/03 01:58:15 raeburn Exp $
1.1 raeburn 5: #
6: # Copyright Michigan State University Board of Trustees
7: #
8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
9: #
10: # LON-CAPA is free software; you can redistribute it and/or modify
11: # it under the terms of the GNU General Public License as published by
12: # the Free Software Foundation; either version 2 of the License, or
13: # (at your option) any later version.
14: #
15: # LON-CAPA is distributed in the hope that it will be useful,
16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18: # GNU General Public License for more details.
19: #
20: # You should have received a copy of the GNU General Public License
21: # along with LON-CAPA; if not, write to the Free Software
22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA#
23: # /home/httpd/html/adm/gpl.txt
24: #
25: # http://www.lon-capa.org/
26: #
27: #
28: ###############################################################
29: ##############################################################
30:
31: package Apache::courseprefs;
32:
33: use strict;
34: use Apache::Constants qw(:common :http);
35: use Apache::lonnet;
36: use Apache::loncommon();
37: use Apache::lonhtmlcommon();
38: use Apache::lonconfigsettings;
39: use Apache::lonlocal;
40: use LONCAPA qw(:DEFAULT :match);
41:
42: sub handler {
43: my $r=shift;
44: if ($r->header_only) {
45: &Apache::loncommon::content_type($r,'text/html');
46: $r->send_http_header;
47: return OK;
48: }
49: my $context = 'course';
50: my $cid = $env{'request.course.id'};
51: my ($cnum,$cdom) = &get_course($cid);
52: my $crstype = &Apache::loncommon::course_type();
53: my $parm_permission = &Apache::lonnet::allowed('opa',$cid);
54: my $navmap = Apache::lonnavmaps::navmap->new();
55: if ($parm_permission && $navmap) {
56: &Apache::loncommon::content_type($r,'text/html');
57: $r->send_http_header;
58: } else {
59: if ($navmap) {
1.9 raeburn 60: if ($crstype eq 'Community') {
61: $env{'user.error.msg'}=
62: "/adm/courseprefs:opa:0:0:Cannot modify community settings";
63: } else {
64: $env{'user.error.msg'}=
65: "/adm/courseprefs:opa:0:0:Cannot modify course settings";
66: }
1.1 raeburn 67: } else {
1.9 raeburn 68: if ($crstype eq 'Community') {
69: $env{'user.error.msg'}=
70: "/adm/courseprefs::0:1:Course environment gone, reinitialize the community";
71: } else {
72: $env{'user.error.msg'}=
73: "/adm/courseprefs::0:1:Course environment gone, reinitialize the course";
74:
75: }
1.1 raeburn 76: }
77: return HTTP_NOT_ACCEPTABLE;
78: }
79:
1.4 raeburn 80: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
81: ['phase','actions','origin']);
1.1 raeburn 82: &Apache::lonhtmlcommon::clear_breadcrumbs();
1.4 raeburn 83: if ($env{'form.origin'} eq 'params') {
84: &Apache::lonhtmlcommon::add_breadcrumb({href=>"/adm/parmset",
85: text=>"Parameter Manager"});
86: }
1.9 raeburn 87: my ($brtext,$brtitle,$crsinfotext,$crsinfodesc,$crscateg,$crshide);
88: my %lt;
89: if ($crstype eq 'Community') {
90: %lt = (
91: conf => 'Community Configuration',
92: edit => 'Edit Community Configuration',
93: gens => 'General community settings',
94: idnu => 'Community ID or number',
95: desc => 'Community Description',
96: catg => 'Categorize community',
97: excc => 'Exclude from community catalog',
98: clon => 'Users allowed to clone community',
99: rept => 'Replacement titles for standard community roles',
100: time => 'Timezone where the community is located',
101: date => 'Locale used for community calendar',
102: coco => 'Community Content',
103: copo => 'Community Policy',
1.13 bisitz 104: priv => 'Domain Coordinators in community',
1.9 raeburn 105: defd => 'Default dates for member access',
106: stuv => 'Member-viewable membership list options',
107: stul => 'Member agreement needed to be listed',
108: clas => 'Membership and Facilitator Listing',
109: priv => 'Privileged users (Domain Coordinators) in facilitator listing',
110: defc => 'Default Community Spreadsheet',
111: defs => 'Default User Spreadsheet',
112: seme => 'Send message to member when clicking Done on Tasks'
113: );
114: } else {
115: %lt = (
116: conf => 'Course Configuration',
117: edit => 'Edit Course Configuration',
1.20 ! faziophi 118: gens => 'General course settings',
! 119: idnu => 'Course ID or number',
! 120: desc => 'Course Description',
1.9 raeburn 121: catg => 'Categorize course',
122: excc => 'Exclude from course catalog',
123: clon => 'Users allowed to clone course',
124: rept => 'Replacement titles for standard course roles',
1.20 ! faziophi 125: time => 'Timezone in which the course takes place',
! 126: date => 'Locale used for course calendar',
1.9 raeburn 127: coco => 'Course Content',
128: copo => 'Course Policy',
1.13 bisitz 129: priv => 'Domain Coordinators in course',
1.9 raeburn 130: defd => 'Default dates for student access',
131: stuv => 'Student-viewable classlist options',
132: stul => 'Student agreement needed to be listed',
133: clas => 'Classlists and Staff Listing',
134: priv => 'Privileged users (Domain Coordinators) in staff listing',
135: defc => 'Default Course Spreadsheet',
136: defs => 'Default Student Spreadsheet',
137: seme => 'Send message to student when clicking Done on Tasks',
138: );
139: }
1.1 raeburn 140: &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/courseprefs',
1.9 raeburn 141: text=>$lt{'conf'}});
1.1 raeburn 142: my $breadcrumbs =
1.9 raeburn 143: &Apache::lonhtmlcommon::breadcrumbs($lt{'edit'});
1.1 raeburn 144:
145: my $phase = 'pickactions';
146: if ( exists($env{'form.phase'}) ) {
147: $phase = $env{'form.phase'};
148: }
149:
150: if ($phase eq 'categorizecourse') {
1.9 raeburn 151: &assign_course_categories($r,$crstype);
1.1 raeburn 152: return OK;
153: }
154:
155: my %values=&Apache::lonnet::dump('environment',$cdom,$cnum);
156: my @prefs_order = ('courseinfo','localization','feedback','discussion',
157: 'classlists','appearance','grading','printouts',
158: 'spreadsheet','bridgetasks','other');
159:
160: my %prefs = (
161: 'courseinfo' =>
1.9 raeburn 162: { text => $lt{'gens'},
1.1 raeburn 163: help => 'Course_Environment',
164: ordered => ['description','courseid','categories',
1.17 faziophi 165: 'hidefromcat','externalsyllabus',
1.19 faziophi 166: 'cloners','url','rolenames'],
1.3 raeburn 167: itemtext => {
1.9 raeburn 168: description => $lt{'desc'},
169: courseid => $lt{'idnu'},
170: categories => $lt{'catg'},
171: hidefromcat => $lt{'excc'},
172: cloners => $lt{'clon'},
1.20 ! faziophi 173: externalsyllabus => 'URL of Syllabus',
1.3 raeburn 174: url => 'Top Level Map',
1.9 raeburn 175: rolenames => $lt{'rept'},
1.3 raeburn 176: },
1.1 raeburn 177: },
178: 'localization' =>
1.17 faziophi 179: { text => 'Language & Time Localization',
1.1 raeburn 180: help => 'Course_Environment',
181: ordered => ['languages','timezone','datelocale'],
1.3 raeburn 182: itemtext => {
1.20 ! faziophi 183: languages => 'Languages used',
1.9 raeburn 184: timezone => $lt{'time'},
185: datelocale => $lt{'date'},
1.3 raeburn 186: },
1.1 raeburn 187: },
188: 'feedback' =>
1.20 ! faziophi 189: { text => 'Feedback messages',
1.1 raeburn 190: help => 'Course_Environment',
191: header => [{col1 => 'Questions about:',
1.20 ! faziophi 192: col2 => 'Recipients'}],
1.3 raeburn 193: ordered => ['question.email','comment.email','policy.email'],
194: itemtext => {
195: 'question.email' => 'Resource Content',
1.9 raeburn 196: 'comment.email' => $lt{'coco'},
197: 'policy.email' => $lt{'copo'},
1.3 raeburn 198: },
1.1 raeburn 199: },
200: 'discussion' =>
201: { text => 'Discussion and Chat',
202: help => 'Course_Environment',
203: ordered => ['plc.roles.denied','plc.users.denied',
204: 'pch.roles.denied','pch.users.denied',
205: 'allow_limited_html_in_feedback',
206: 'allow_discussion_post_editing'],
1.3 raeburn 207: itemtext => {
1.20 ! faziophi 208: 'plc.roles.denied' => 'No Resource Discussion',
! 209: 'plc.users.denied' => 'No Resource Discussion',
! 210: 'pch.roles.denied' => 'No Chat room use',
! 211: 'pch.users.denied' => 'No Chat room use',
! 212: allow_limited_html_in_feedback => 'Allow limited HTML in discussion',
! 213: allow_discussion_post_editing => 'Users can edit/delete own discussion posts',
1.3 raeburn 214: },
1.1 raeburn 215: },
216: 'classlists' =>
1.9 raeburn 217: { text => $lt{'clas'},
1.1 raeburn 218: help => 'Course_Environment',
219: header => [{col1 => 'Type',
1.9 raeburn 220: col2 => $lt{'defd'}},
1.1 raeburn 221: {col1 => 'Setting',
1.9 raeburn 222: col2 => $lt{'priv'}},
1.1 raeburn 223: {col1 => 'Setting',
1.9 raeburn 224: col2 => $lt{'stuv'}}],
1.1 raeburn 225: ordered => ['default_enrollment_start_date',
226: 'default_enrollment_end_date',
227: 'nothideprivileged','student_classlist_view',
228: 'student_opt_in','student_classlist_portfiles'],
1.3 raeburn 229: itemtext => {
230: default_enrollment_start_date => 'Start date',
231: default_enrollment_end_date => 'End date',
1.9 raeburn 232: nothideprivileged => $lt{'priv'},
233: student_classlist_view => $lt{'stuv'},
234: student_opt_in => $lt{'stul'},
1.3 raeburn 235: student_classlist_portfiles => 'Include link to accessible portfolio files',
236: },
1.1 raeburn 237: },
238: 'appearance' =>
1.20 ! faziophi 239: { text => 'Display of resources ',
1.1 raeburn 240: help => 'Course_Environment',
241: ordered => ['default_xml_style','pageseparators',
242: 'disable_receipt_display','texengine',
243: 'tthoptions'],
1.3 raeburn 244: itemtext => {
1.17 faziophi 245: default_xml_style => 'Default XML style file',
1.20 ! faziophi 246: pageseparators => 'Visibly Separate Items on Pages',
! 247: disable_receipt_display => 'Disable display of problem receipts',
! 248: texengine => 'Force use of a specific math rendering engine',
1.3 raeburn 249: tthoptions => 'Default set of options to pass to tth/m when converting TeX',
250: },
1.1 raeburn 251: },
252: 'grading' =>
253: { text => 'Grading',
254: help => 'Course_Environment',
255: ordered => ['grading','rndseed',
256: 'receiptalg','disablesigfigs'],
1.3 raeburn 257: itemtext => {
1.20 ! faziophi 258: grading => 'Grading',
! 259: rndseed => 'Randomization algorithm used',
! 260: receiptalg => 'Receipt algorithm used',
! 261: disablesigfigs => 'Disable checking of Significant Figures',
1.3 raeburn 262: },
263:
1.1 raeburn 264: },
265: 'printouts' =>
1.20 ! faziophi 266: { text => 'Printout generation',
1.1 raeburn 267: help => 'Course_Environment',
268: ordered => ['problem_stream_switch','suppress_tries',
269: 'default_paper_size','print_header_format',
1.14 raeburn 270: 'disableexampointprint','canuse_pdfforms'],
1.3 raeburn 271: itemtext => {
272: problem_stream_switch => 'Allow problems to be split over pages',
273: suppress_tries => 'Suppress number of tries in printing',
274: default_paper_size => 'Default paper type',
275: print_header_format => 'Print header format',
276: disableexampointprint => 'Disable automatically printing point values on exams',
1.14 raeburn 277: canuse_pdfforms => 'Users can print problems as PDF forms and upload later for grading',
1.3 raeburn 278: },
1.1 raeburn 279: },
280: 'spreadsheet' =>
281: { text => 'Spreadsheets',
282: help => 'Course_Environment',
283: ordered => ['spreadsheet_default_classcalc',
284: 'spreadsheet_default_studentcalc',
285: 'spreadsheet_default_assesscalc','hideemptyrows'],
1.3 raeburn 286: itemtext => {
1.9 raeburn 287: spreadsheet_default_classcalc => $lt{'defc'},
288: spreadsheet_default_studentcalc => $lt{'defs'},
1.3 raeburn 289: spreadsheet_default_assesscalc => 'Default Assessment Spreadsheet',
290: hideemptyrows => 'Hide Empty Rows in Spreadsheets',
291: },
1.1 raeburn 292: },
293: 'bridgetasks' =>
294: { text => 'Bridge tasks',
295: help => 'Course_Environment',
296: ordered => ['task_messages','task_grading',
297: 'suppress_embed_prompt'],
1.3 raeburn 298: itemtext => {
1.9 raeburn 299: task_messages => $lt{'seme'},
1.3 raeburn 300: task_grading => 'Bridge Task grading by instructors and TAs in sections' ,
1.5 raeburn 301: suppress_embed_prompt => 'Hide upload references prompt if uploading file to portfolio',
1.3 raeburn 302: },
1.1 raeburn 303: },
304: 'other' =>
305: { text => 'Other settings',
306: help => 'Course_Environment',
307: header => [ {col1 => 'Item',
308: col2 => 'Value',
309: }],
310: },
311: );
312: if ($phase eq 'process') {
1.3 raeburn 313: my @allitems = &get_allitems(%prefs);
1.1 raeburn 314: &Apache::lonconfigsettings::make_changes($r,$cdom,$phase,$context,
1.3 raeburn 315: \@prefs_order,\%prefs,\%values,
316: $cnum,undef,\@allitems);
1.1 raeburn 317: } elsif ($phase eq 'display') {
1.12 raeburn 318: my $jscript = &get_jscript($cdom,$phase,$crstype);
1.3 raeburn 319: my @allitems = &get_allitems(%prefs);
1.1 raeburn 320: &Apache::lonconfigsettings::display_settings($r,$cdom,$phase,$context,
1.9 raeburn 321: \@prefs_order,\%prefs,\%values,undef,$jscript,\@allitems,$crstype);
1.1 raeburn 322: } else {
323: &Apache::lonconfigsettings::display_choices($r,$phase,$context,
324: \@prefs_order,\%prefs);
325: }
326: return OK;
327: }
328:
1.3 raeburn 329: sub get_allitems {
330: my (%prefs) = @_;
331: my @allitems;
332: foreach my $item (keys(%prefs)) {
333: if (ref($prefs{$item}) eq 'HASH') {
334: if (ref($prefs{$item}{'ordered'}) eq 'ARRAY') {
335: push(@allitems,@{$prefs{$item}{'ordered'}});
336: if ($item eq 'feedback') {
337: push(@allitems,(map { $_.'.text'; } @{$prefs{$item}{'ordered'}}));
338: }
339: }
340: }
341: }
342: return @allitems;
343: }
344:
1.1 raeburn 345: sub print_config_box {
1.9 raeburn 346: my ($r,$cdom,$phase,$action,$item,$settings,$allitems,$crstype) = @_;
1.1 raeburn 347: my $ordered = $item->{'ordered'};
1.3 raeburn 348: my $itemtext = $item->{'itemtext'};
1.1 raeburn 349: my $rowtotal = 0;
350: my $output =
1.16 faziophi 351: '<h3><a href="#">'.&mt($item->{text}).'</a></h3>
352: <div> <span style="float:right">'.
353: &Apache::loncommon::help_open_topic($item->{'help'}).'</span>';
1.1 raeburn 354: if (($action eq 'feedback') || ($action eq 'classlists')) {
355: $output .= '
1.18 faziophi 356: <table class="LC_nested">';
357: if (exists $item->{'header'}->[0]->{'col1'} ||
358: exists $item->{'header'}->[0]->{'col2'}) {
359: $output .= '
360: <tr class="LC_info_row">
1.1 raeburn 361: <td class="LC_left_item">'.&mt($item->{'header'}->[0]->{'col1'}).'</td>
362: <td class="LC_right_item">'.&mt($item->{'header'}->[0]->{'col2'}).'</td>
1.18 faziophi 363: </tr>';
364: }
1.1 raeburn 365: $rowtotal ++;
366: if ($action eq 'feedback') {
1.3 raeburn 367: $output .= &print_feedback('top',$cdom,$settings,$ordered,$itemtext,\$rowtotal);
1.1 raeburn 368: } elsif ($action eq 'classlists') {
1.9 raeburn 369: $output .= &print_classlists('top',$cdom,$settings,$itemtext,\$rowtotal,$crstype);
1.1 raeburn 370: }
371: $output .= '
372: </table>
373: <table class="LC_nested">
374: <tr class="LC_info_row">
375: <td class="LC_left_item">'.&mt($item->{'header'}->[1]->{'col1'}).'</td>';
376: $output .= '
377: <td class="LC_right_item">'.&mt($item->{'header'}->[1]->{'col2'}).'</td>
378: </tr>';
379: if ($action eq 'classlists') {
1.9 raeburn 380: $output .= &print_classlists('middle',$cdom,$settings,$itemtext,\$rowtotal,$crstype).
1.1 raeburn 381: '
382: </table>
1.18 faziophi 383: <table class="LC_nested">';
384: if (exists $item->{'header'}->[0]->{'col1'} ||
385: exists $item->{'header'}->[0]->{'col2'}) {
386: $output .= '
387: <tr class="LC_info_row">
388: <td class="LC_left_item">'.&mt($item->{'header'}->[0]->{'col1'}).'</td>
389: <td class="LC_right_item">'.&mt($item->{'header'}->[0]->{'col2'}).'</td>
390: </tr>';
391: }
1.1 raeburn 392: }
393: } else {
394: $output .= '
1.18 faziophi 395: <table class="LC_nested">';
396: if (exists $item->{'header'}->[0]->{'col1'} ||
397: exists $item->{'header'}->[0]->{'col2'}) {
398: $output .= '
399: <tr class="LC_info_row">
1.1 raeburn 400: <td class="LC_left_item" valign="top">'.&mt($item->{'header'}->[0]->{'col1'}).'</td>
401: <td class="LC_right_item" valign="top">'.&mt($item->{'header'}->[0]->{'col2'}).'</td>
1.18 faziophi 402: </tr>';
403: }
1.1 raeburn 404: }
405: $rowtotal ++;
406: if ($action eq 'courseinfo') {
1.9 raeburn 407: $output .= &print_courseinfo($cdom,$settings,$ordered,$itemtext,\$rowtotal,$crstype);
1.1 raeburn 408: } elsif ($action eq 'localization') {
1.3 raeburn 409: $output .= &print_localization($cdom,$settings,$ordered,$itemtext,\$rowtotal);
1.1 raeburn 410: } elsif ($action eq 'feedback') {
1.3 raeburn 411: $output .= &print_feedback('bottom',$cdom,$settings,$ordered,$itemtext,\$rowtotal);
1.1 raeburn 412: } elsif ($action eq 'discussion') {
1.3 raeburn 413: $output .= &print_discussion($cdom,$settings,$ordered,$itemtext,\$rowtotal);
1.1 raeburn 414: } elsif ($action eq 'classlists') {
1.9 raeburn 415: $output .= &print_classlists('bottom',$cdom,$settings,$itemtext,\$rowtotal,$crstype);
1.1 raeburn 416: } elsif ($action eq 'appearance') {
1.9 raeburn 417: $output .= &print_appearance($cdom,$settings,$ordered,$itemtext,\$rowtotal,$crstype);
1.1 raeburn 418: } elsif ($action eq 'grading') {
1.9 raeburn 419: $output .= &print_grading($cdom,$settings,$ordered,$itemtext,\$rowtotal,$crstype);
1.1 raeburn 420: } elsif ($action eq 'printouts') {
1.9 raeburn 421: $output .= &print_printouts($cdom,$settings,$ordered,$itemtext,\$rowtotal,$crstype);
1.1 raeburn 422: } elsif ($action eq 'spreadsheet') {
1.9 raeburn 423: $output .= &print_spreadsheet($cdom,$settings,$ordered,$itemtext,\$rowtotal,$crstype);
1.1 raeburn 424: } elsif ($action eq 'bridgetasks') {
1.9 raeburn 425: $output .= &print_bridgetasks($cdom,$settings,$ordered,$itemtext,\$rowtotal,$crstype);
1.1 raeburn 426: } elsif ($action eq 'other') {
1.9 raeburn 427: $output .= &print_other($cdom,$settings,$allitems,\$rowtotal,$crstype);
1.1 raeburn 428: }
429: $output .= '
430: </table>
1.16 faziophi 431: </div>';
1.1 raeburn 432: return ($output,$rowtotal);
433: }
434:
435: sub process_changes {
1.9 raeburn 436: my ($cdom,$action,$values,$item,$changes,$allitems,$disallowed,$crstype) = @_;
1.3 raeburn 437: my %newvalues;
438: if (ref($item) eq 'HASH') {
439: if (ref($changes) eq 'HASH') {
440: my @ordered;
441: if ($action eq 'other') {
442: @ordered = &get_other_items($cdom,$values,$allitems);
443: if ($env{'form.newp_name'} ne '') {
444: my $newp = $env{'form.newp_name'};
445: if ($env{'form.newp_value'} ne '') {
446: if (ref($allitems) eq 'ARRAY') {
447: unless ((grep(/^\Q$newp\E$/,@ordered)) ||
448: (grep(/^\Q$newp\E$/,@{$allitems}))) {
449: $changes->{$newp} = $env{'form.newp_value'};
450: }
451: }
452: }
453: }
454: } elsif (ref($item->{'ordered'}) eq 'ARRAY') {
455: @ordered = @{$item->{'ordered'}};
456: }
457: if (@ordered > 0) {
458: if ($action eq 'feedback') {
459: foreach my $entry (@ordered) {
460: my $userstr = '';
461: my $total = $env{'form.'.$entry.'_total'};
462: if ($total) {
463: my @deletes = &Apache::loncommon::get_env_multiple('form.'.$entry.'_delete');
464: for (my $i=0; $i<$total; $i++) {
465: unless (grep(/^$i$/,@deletes)) {
466: $userstr .= $env{'form.'.$entry.'_user_'.$i}.
467: &get_sec_str($entry,$i).',';
468: }
469: }
470: } else {
471: $total = 0;
472: }
473: if ($env{'form.'.$entry.'_uname_'.$total} ne '') {
474: my $uname = $env{'form.'.$entry.'_uname_'.$total};
475: my $udom = $env{'form.'.$entry.'_udom_'.$total};
476: if (&Apache::lonnet::homeserver($uname,$udom) eq 'no_host') {
477: $userstr =~ s/,$//;
478: $disallowed->{'feedback'}{$entry} = $uname.':'.$udom;
479: } else {
480: $userstr .= $uname.':'.$udom.&get_sec_str($entry,$total);
481: }
482: } else {
483: $userstr =~ s/,$//;
484: }
485: $newvalues{$entry} = $userstr;
486: if ($newvalues{$entry} ne $values->{$entry}) {
487: $changes->{$entry} = $newvalues{$entry};
488: }
489: my $ext_entry = $entry.'.text';
490: $newvalues{$ext_entry} = $env{'form.'.$ext_entry};
491: if ($newvalues{$ext_entry} ne $values->{$ext_entry}) {
492: $changes->{$ext_entry} = $newvalues{$ext_entry};
493: }
494: }
495: } else {
496: foreach my $entry (@ordered) {
497: if ($entry eq 'cloners') {
498: if ($env{'form.cloners_all'}) {
499: $newvalues{$entry} = '*';
500: } else {
501: my @clonedoms;
502: if (exists($env{'form.cloners_activate'})) {
503: my $actnum = $env{'form.cloners_activate'};
504: if ($actnum ne '') {
505: if ($env{'form.clonersdom_'.$actnum} ne '') {
506: my $clonedom = $env{'form.clonersdom_'.$actnum};
507: if (&check_clone($clonedom,$disallowed) eq 'ok') {
508: $newvalues{$entry} = '*:'.$clonedom;
509: push(@clonedoms,$newvalues{$entry});
510: }
511: }
512: }
513: } else {
514: my $num = $env{'form.cloners_total'};
515: my @deletes =
516: &Apache::loncommon::get_env_multiple('form.cloners_delete');
517: for (my $i=0; $i<$num; $i++) {
518: if (!grep(/^$i$/,@deletes)) {
519: my $clonedom = $env{'form.cloners_dom_'.$i};
520: if (&check_clone($clonedom,$disallowed) eq 'ok') {
521: if (!grep(/^\*:\Q$clonedom\E$/,@clonedoms)) {
522: push (@clonedoms,'*:'.$clonedom);
523: }
524: }
525: }
526: }
527: if (@clonedoms) {
528: $newvalues{$entry}=join(',',@clonedoms);
529: }
530: }
531: if ($env{'form.cloners_newdom'} ne '') {
532: my $clonedom = $env{'form.cloners_newdom'};
533: if (&check_clone($clonedom,$disallowed) eq 'ok') {
534: my $newdom = '*:'.$env{'form.cloners_newdom'};
535: if (@clonedoms) {
536: if (!grep(/^\Q$newdom\E$/,@clonedoms)) {
537: $newvalues{$entry} .= ','.$newdom;
538: }
539: } else {
540: $newvalues{$entry} = $newdom;
541: }
542: }
543: }
544: if ($env{'form.'.$entry} ne '') {
545: my @cloners = split(',',$env{'form.'.$entry});
546: my @okcloners;
547: foreach my $cloner (@cloners) {
548: my ($uname,$udom) = split(':',$cloner);
549: if (&check_clone($udom,$disallowed,$uname) eq 'ok') {
550: if (!grep(/^\Q$cloner\E$/,@okcloners)) {
551: push(@okcloners,$cloner);
552: }
553: }
554: }
555: if (@okcloners) {
556: my $okclonestr = join(',',@okcloners);
557: if ($newvalues{$entry} ne '') {
558: $newvalues{$entry} .= ','.$okclonestr;
559: } else {
560: $newvalues{$entry} = $okclonestr;
561: }
562: }
563: }
564: }
565: if (ref($disallowed) eq 'HASH') {
566: if (ref($disallowed->{'cloners'}) eq 'HASH') {
567: foreach my $key (keys(%{$disallowed->{'cloners'}})) {
568: $disallowed->{'cloners'}{$key} =~ s/,$//;
569: }
570: }
571: }
572: } elsif ($entry =~ /^default_enrollment_(start|end)_date$/) {
573: $newvalues{$entry}=&Apache::lonhtmlcommon::get_date_from_form($entry);
574: } elsif ($entry eq 'rolenames') {
575: my %adv_roles =
576: &Apache::lonnet::get_course_adv_roles($env{'request.course.id'},1);
1.9 raeburn 577: my @stds;
578: if ($crstype eq 'Community') {
579: @stds = ('co');
580: } else {
581: @stds = ('cc');
582: }
583: push(@stds,('in','ta','ep','ad','st'));
1.3 raeburn 584: my (@replacements,@regulars);
585: foreach my $role (@stds) {
586: if ($values->{$role.'.plaintext'} ne '') {
1.9 raeburn 587: push(@replacements,$role);
1.3 raeburn 588: } else {
589: push(@regulars,$role);
590: }
1.9 raeburn 591: }
1.3 raeburn 592: foreach my $stdrole (@stds) {
593: my $ext_entry = $entry.'_'.$stdrole;
594: my $stdname = &Apache::lonnet::plaintext($stdrole,$crstype,
595: $env{'request.course.id'},1);
596: if ($env{'form.'.$ext_entry} eq $stdname) {
597: $newvalues{$ext_entry} = '';
598: } else {
599: $newvalues{$ext_entry} = $env{'form.'.$ext_entry};
600: }
601: if ($newvalues{$ext_entry} ne $values->{$stdrole.'.plaintext'}) {
602: my $dupname = 0;
603: if ($newvalues{$ext_entry} ne '') {
604: if (grep(/^\Q$newvalues{$ext_entry}\E$/,@replacements)) {
605: $dupname = 1;
606: push(@{$disallowed->{'rolenames'}{'replacements'}},$newvalues{$ext_entry});
607: }
608: if (!$dupname) {
609: if (grep(/^\Q$newvalues{$ext_entry}\E$/,@regulars)) {
610: $dupname = 1;
611: push(@{$disallowed->{rolenames}{'regulars'}},$newvalues{$ext_entry});
612: }
613: }
614: if (!$dupname) {
615: foreach my $role (keys(%adv_roles)) {
616: if ($role =~ m{^cr/$match_domain/$match_name/\Q$newvalues{$ext_entry}\E$}) {
617: $dupname = 1;
618: push(@{$disallowed->{rolenames}{'customrole'}},$newvalues{$ext_entry});
619: last;
620: }
621: }
622: }
623: }
624: if (!$dupname) {
625: $changes->{$ext_entry} = $newvalues{$ext_entry};
626: }
627: }
628: }
629: } elsif (($entry eq 'plc.roles.denied') || ($entry eq 'pch.roles.denied')) {
630: my @denied = &Apache::loncommon::get_env_multiple('form.'.$entry);
631: @denied = sort(@denied);
632: my $deniedstr = '';
633: if (@denied > 0) {
634: $deniedstr = join(',',@denied);
635: }
636: $newvalues{$entry} = $deniedstr;
637: } elsif (($entry eq 'plc.users.denied') || ($entry eq 'pch.users.denied')) {
638: my $total = $env{'form.'.$entry.'_total'};
639: my $userstr = '';
640: my @denied;
641: if ($total > 0) {
642: my @deletes =
643: &Apache::loncommon::get_env_multiple('form.'.$entry.'_delete');
644: for (my $i=0; $i<$total; $i++) {
645: unless (grep(/^$i$/,@deletes)) {
646: $userstr .= $env{'form.'.$entry.'_user_'.$i}.',';
647: push(@denied,$env{'form.'.$entry.'_user_'.$i});
648: }
649: }
650: } else {
651: $total = 0;
652: }
653: if ($env{'form.'.$entry.'_uname_'.$total} ne '') {
654: my $uname = $env{'form.'.$entry.'_uname_'.$total};
655: my $udom = $env{'form.'.$entry.'_udom_'.$total};
656: if (&Apache::lonnet::homeserver($uname,$udom) eq 'no_host') {
657: $userstr =~ s/,$//;
658: $disallowed->{'discussion'}{$entry} = $uname.':'.$udom;
659: } else {
660: my $newuser .= $uname.':'.$udom;
661: if (grep(/^\Q$newuser\E$/,@denied)) {
662: $userstr =~ s/,$//;
663: } else {
664: $userstr .= $newuser;
665: }
666: }
667: } else {
668: $userstr =~ s/,$//;
669: }
670: $newvalues{$entry} = $userstr;
671: } elsif ($entry eq 'allow_discussion_post_editing') {
672: my @canedit = &Apache::loncommon::get_env_multiple('form.'.$entry);
673: @canedit = sort(@canedit);
674: foreach my $role (@canedit) {
675: my @secs = &Apache::loncommon::get_env_multiple('form.'.$entry.'_sections_'.$role);
676: if ((grep(/^\s*$/,@secs)) || (@secs == 0)) {
677: $newvalues{$entry} .= $role.',';
678: } else {
679: foreach my $sec (@secs) {
680: $newvalues{$entry} .= $role.':'.$sec.',';
681: }
682: }
683: }
684: $newvalues{$entry} =~ s/,$//;
685: } elsif ($entry eq 'nothideprivileged') {
686: my @curr_nothide;
687: my @new_nothide;
688: if ($values->{$entry} ne '') {
689: foreach my $user (split(/\s*\,\s*/,$values->{$entry})) {
690: my $nothide;
691: if ($user !~ /:/) {
692: $nothide = join(':',split(/[\@]/,$user));
693: } else {
694: $nothide = $user;
695: }
696: if ((defined($nothide)) &&
697: (!grep(/^\Q$nothide\E$/,@curr_nothide))) {
698: push(@curr_nothide,$nothide);
699: }
700: }
701: }
702: foreach my $key (keys(%env)) {
703: if ($key =~ /^form\.\Q$entry\E_($match_username:$match_domain)$/) {
1.7 raeburn 704: if ($env{$key}) {
1.3 raeburn 705: my $nothide = $1;
706: if (!grep(/^\Q$nothide\E$/,@new_nothide)) {
707: push(@new_nothide,$nothide);
708: }
709: }
710: }
711: }
712: @new_nothide = sort(@new_nothide);
713: my @differences =
714: &Apache::loncommon::compare_arrays(\@curr_nothide,
715: \@new_nothide);
716: if (@differences > 0) {
717: if (@new_nothide > 0) {
718: $newvalues{$entry} = join(',',@new_nothide);
719: } else {
720: $newvalues{$entry} = '';
721: }
722: } else {
723: $newvalues{$entry} = $values->{$entry};
724: }
725: } elsif ($entry eq 'print_header_format') {
726: my $maxnum = $env{'form.printfmthdr_maxnum'};
727: my @newhdr;
728: if ($maxnum > 2) {
729: for (my $i=0; $i<$maxnum-2; $i++) {
730: if ($env{'form.printfmthdr_del_'.$i}) {
731: $newhdr[$env{'form.printfmthdr_pos_'.$i}] = '';
732: } else {
733: my $hdr;
734: if ($env{'form.printfmthdr_sub_'.$i} =~ /^[nca]$/) {
735: $hdr = '%';
736: if ($env{'form.printfmthdr_limit_'.$i} =~ /^\d+$/) {
737: $hdr .= $env{'form.printfmthdr_limit_'.$i};
738: }
739: $hdr .= $env{'form.printfmthdr_sub_'.$i};
740: } elsif ($env{'form.printfmthdr_sub_'.$i} ne '') {
741: $hdr = $env{'form.printfmthdr_sub_'.$i};
742: }
743: $newhdr[$env{'form.printfmthdr_pos_'.$i}] = $hdr;
744: }
745: }
746: }
747: my $newsub = $maxnum-2;
748: if ($env{'form.printfmthdr_sub_'.$newsub} =~ /^[nca]$/) {
749: my $hdr = '%';
750: if ($env{'form.printfmthdr_limit_'.$newsub} =~ /^\d+$/) {
751: $hdr .= $env{'form.printfmthdr_limit_'.$newsub};
752: }
753: $hdr .= $env{'form.printfmthdr_sub_'.$newsub};
754: $newhdr[$env{'form.printfmthdr_pos_'.$newsub}] = $hdr;
755: }
756: my $newtext = $maxnum-1;
757: $newhdr[$env{'form.printfmthdr_pos_'.$newtext}] = $env{'form.printfmthdr_text_'.$newtext};
758: $newvalues{$entry} = join('',@newhdr);
759: } elsif ($entry eq 'languages') {
760: my $langstr;
761: my $total = $env{'form.'.$entry.'_total'};
762: if ($total) {
763: my @deletes = &Apache::loncommon::get_env_multiple('form.'.$entry.'_delete');
764: for (my $i=0; $i<$total; $i++) {
765: unless (grep(/^$i$/,@deletes)) {
766: $langstr .= $env{'form.'.$entry.'_'.$i}.',';
767: }
768: }
769: } else {
770: $total = 0;
771: }
772: if ($env{'form.'.$entry.'_'.$total} ne '') {
773: my $newlang = $env{'form.'.$entry.'_'.$total};
774: my %langchoices = &get_lang_choices();
775: if ($langchoices{$newlang}) {
776: $langstr .= $newlang;
777: } else {
778: $langstr =~ s/,$//;
779: $disallowed->{'localization'}{$entry} = $newlang;
780: }
781: } else {
782: $langstr =~ s/,$//;
783: }
784: $newvalues{$entry} = $langstr;
785: } else {
786: $newvalues{$entry} = $env{'form.'.$entry};
787: }
788: if ($newvalues{$entry} ne $values->{$entry}) {
789: $changes->{$entry} = $newvalues{$entry};
790: }
791: }
792: }
793: }
794: }
795: }
796: return;
797: }
798:
799: sub get_sec_str {
800: my ($entry,$num) = @_;
801: my @secs = &Apache::loncommon::get_env_multiple('form.'.$entry.'_sections_'.$num);
802: my $secstr;
803: if (grep(/^\s*$/,@secs)) {
804: $secstr = '';
805: } elsif (@secs > 0) {
806: $secstr = join(';',@secs);
807: }
808: if ($secstr ne '') {
809: return '('.$secstr.')';
810: }
811: return;
812: }
813:
814: sub check_clone {
815: my ($clonedom,$disallowed,$clonename) = @_;
816: return if (ref($disallowed) ne 'HASH');
817: if ($clonedom !~ /^$match_domain$/) {
818: $disallowed->{'cloners'}{'format'} .= $clonedom.',';
819: return;
820: } elsif (!&Apache::lonnet::domain($clonedom)) {
821: $disallowed->{'cloners'}{'domain'} .= $clonedom.',';
822: return;
823: }
824: if ($clonename ne '') {
825: if ($clonename !~ /^$match_username$/) {
826: $disallowed->{'cloners'}{'format'} .= $clonename.':'.$clonedom.',';
827: return;
828: } else {
829: if (&Apache::lonnet::homeserver($clonename,$clonedom) eq 'no_host') {
830: $disallowed->{'cloners'}{'newuser'} .= $clonename.':'.$clonedom.',';
831: return;
832: }
833: }
834: }
835: return 'ok';
836: }
837:
838: sub store_changes {
1.9 raeburn 839: my ($cdom,$cnum,$prefs_order,$actions,$prefs,$values,$changes,$crstype) = @_;
1.3 raeburn 840: my ($chome,$output);
841: my (%storehash,@delkeys,@need_env_update);
842: if ((ref($values) eq 'HASH') && (ref($changes) eq 'HASH')) {
843: %storehash = %{$values};
844: } else {
1.9 raeburn 845: if ($crstype eq 'Community') {
846: $output = &mt('No changes made to community settings.');
847: } else {
848: $output = &mt('No changes made to course settings.');
849: }
850: return $output;
1.3 raeburn 851: }
852: my %yesno = (
853: hidefromcat => '1',
854: problem_stream_switch => '1',
855: suppress_tries => '1',
856: disableexampointprint => '1',
857: hideemptyrows => '1',
858: suppress_embed_prompt => '1',
859: );
860: foreach my $item (@{$prefs_order}) {
861: if (grep(/^\Q$item\E$/,@{$actions})) {
862: $output .= '<h3>'.&mt($prefs->{$item}{'text'}).'</h3>';
863: if (ref($changes->{$item}) eq 'HASH') {
864: if (keys(%{$changes->{$item}}) > 0) {
865: $output .= &mt('Changes made:').'<ul>';
866: if ($item eq 'other') {
867: foreach my $key (sort(keys(%{$changes->{$item}}))) {
868: $storehash{$key} = $changes->{$item}{$key};
869: if ($changes->{$item}{$key} eq '') {
870: push(@delkeys,$key);
871: $output .= '<li>'.&mt('Deleted setting for [_1]','<i>'.$key.'</i>').'</li>';
872: } else {
873: $output .= '<li>'.&mt('[_1] set to [_2]','<i>'.$key.'</i>',
874: "'$storehash{$key}'").'</li>';
875: }
876: }
877: } else {
878: if (ref($prefs->{$item}->{'ordered'}) eq 'ARRAY') {
879: my @settings = @{$prefs->{$item}->{'ordered'}};
880: if ($item eq 'feedback') {
881: push(@settings,(map { $_.'.text'; } @settings));
882: }
883: foreach my $key (@settings) {
884: if ($key eq 'rolenames') {
885: my $displayname = $prefs->{$item}->{'itemtext'}{$key};
886: my $msg;
1.9 raeburn 887: my @roles;
888: if ($crstype eq 'Community') {
889: @roles = ('co');
890: } else {
891: @roles = ('cc');
892: }
893: push(@roles,('in','ta','ep','ad','st'));
894: foreach my $role (@roles) {
1.3 raeburn 895: next if (!exists($changes->{$item}{$key.'_'.$role}));
896: my $stdname = &Apache::lonnet::plaintext($role,$crstype,undef,1);
897: my $newname = $changes->{$item}{$key.'_'.$role};
898: $storehash{$role.'.plaintext'} = $newname;
899: if ($newname eq '') {
900: $newname = $stdname;
901: }
902: $msg .= '<li>'.&mt('[_1] set to [_2]','<i>'.$stdname.'</i>',
903: "'<b>".$newname."</b>'").'</li>';
904: }
905: if ($msg ne '') {
906: $output .= '<li>'.&mt($displayname).'<ul>'.$msg.'</ul></li>';
907: }
908: } else {
909: next if (!exists($changes->{$item}{$key}));
910: my ($displayname,$text);
911: $text = $prefs->{$item}->{'itemtext'}{$key};
912: my $displayval = $changes->{$item}{$key};
913: if ($item eq 'feedback') {
914: if ($key =~ /^(question|policy|comment)(\.email)\.text$/) {
915: $text = $prefs->{$item}->{'itemtext'}{$1.$2};
916: $displayname = &mt('Custom text for '.$text.' questions');
917: } else {
918: $displayname = &mt('Recipients of '.$text.' questions');
919: }
920: } elsif ($item eq 'discussion') {
921: if ($key =~ /^p(lc|ch)\.roles\.denied/) {
922: $displayname = &mt("$text (role-based)");
923: if ($displayval ne '') {
924: my @roles = split(',',$displayval);
925: @roles = map { &Apache::lonnet::plaintext($_); } @roles;
926: $displayval = join(', ',@roles);
927: }
928: } elsif ($key =~ /^p(lc|ch)\.users\.denied/) {
929: $displayname = &mt("$text (specific user(s))");
930: } else {
931: if ($key eq 'allow_discussion_post_editing') {
932: if ($displayval ne '') {
933: my @roles = split(',',$displayval);
934: my @longroles;
935: foreach my $role (@roles) {
936: my ($trole,$sec) = split(':',$role);
937: my $rolename =
938: &Apache::lonnet::plaintext($trole);
939: if ($sec ne '') {
940: $rolename .= ':'.$sec;
941: }
942: push(@longroles,$rolename);
943: }
944: $displayval = join(', ',@longroles);
945: }
946: }
947: $displayname = &mt($text);
948: }
949: } elsif ($item eq 'spreadsheet') {
950: if ($key =~ /^spreadsheet_default_(studentcalc|assesscalc)$/x) {
951: my $sheettype = $1;
952: if ($sheettype eq 'studentcalc') {
953: &Apache::lonnet::expirespread('','','studentcalc');
954: } else {
955: &Apache::lonnet::expirespread('','','assesscalc');
956: &Apache::lonnet::expirespread('','','studentcalc');
957: }
958: }
959: $displayname = &mt($text);
960: } else {
961: $displayname = &mt($text);
962: }
963: if (defined($yesno{$key})) {
1.14 raeburn 964: $displayval = &mt('No');
1.3 raeburn 965: if ($changes->{$item}{$key} eq 'yes') {
1.14 raeburn 966: $displayval = &mt('Yes');
1.3 raeburn 967: }
968: } elsif (($key =~ /^default_enrollment_(start|end)_date$/) && ($displayval)) {
969: $displayval = &Apache::lonlocal::locallocaltime($displayval);
970: } elsif ($key eq 'categories') {
971: $displayval = $env{'form.categories_display'};
1.14 raeburn 972: } elsif ($key eq 'canuse_pdfforms') {
973: if ($changes->{$item}{$key} eq '1') {
974: $displayval = &mt('Yes');
975: } elsif ($changes->{$item}{$key} eq '0') {
976: $displayval = &mt('No');
977: }
978: }
1.3 raeburn 979: if ($changes->{$item}{$key} eq '') {
980: push(@delkeys,$key);
981: $output .= '<li>'.&mt('Deleted setting for [_1]',
982: '<i>'.$displayname.'</i>').'</li>';
983: } else {
984: $output .= '<li>'.&mt('[_1] set to [_2]',
985: '<i>'.$displayname.'</i>',
986: "'<b>$displayval</b>'");
987: if ($key eq 'url') {
988: my $bkuptime=time;
989: $output .= (' 'x2).&mt('(Previous URL backed up)').': '.
990: $storehash{'top level map backup '.$bkuptime} => $values->{$key};
991: }
992: $output .= '</li>';
993: }
994: $storehash{$key} = $changes->{$item}{$key};
995: }
996: if (($key eq 'description') || ($key eq 'cloners') ||
997: ($key eq 'hidefromcat') || ($key eq 'categories')) {
998: push(@need_env_update,$key);
999: }
1000: }
1001: }
1002: }
1003: $output .= '</ul>';
1004: } else {
1.9 raeburn 1005: if ($crstype eq 'Community') {
1006: $output = &mt('No changes made to community settings.');
1007: } else {
1008: $output = &mt('No changes made to course settings.');
1009: }
1.3 raeburn 1010: }
1011: }
1012: }
1013: }
1014: if (&Apache::lonnet::put('environment',\%storehash,$cdom,$cnum) eq 'ok') {
1015: if (@delkeys) {
1016: if (&Apache::lonnet::del('environment',\@delkeys,$cdom,$cnum) ne 'ok') {
1.9 raeburn 1017: $output .= '<br /><span class="LC_error">';
1018: if ($crstype eq 'Community') {
1019: $output .= &mt('An error occurred when removing community settings which are no longer in use.');
1020: } else {
1021: $output .= &mt('An error occurred when removing course settings which are no longer in use.');
1022: }
1023: $output .= '</span>';
1.14 raeburn 1024: } else {
1025: foreach my $key (@delkeys) {
1026: &Apache::lonnet::delenv('course.'.$cdom.'_'.$cnum.'.'.$key);
1027: }
1.3 raeburn 1028: }
1029: }
1030: if (@need_env_update) {
1031: $chome = &Apache::lonnet::homeserver($cnum,$cdom);
1032: &update_env($cnum,$cdom,$chome,\@need_env_update,\%storehash);
1033: }
1034: &Apache::lonnet::coursedescription($env{'request.course.id'},
1035: {'freshen_cache' => 1});
1036: } else {
1.9 raeburn 1037: $output = '<span class="LC_error">';
1038: if ($crstype eq 'Community') {
1039: $output .= &mt('An error occurred when saving changes to community settings, which remain unchanged.');
1040: } else {
1041: $output .= &mt('An error occurred when saving changes to course settings, which remain unchanged.');
1042: }
1043: $output .= '</span>';
1.3 raeburn 1044: }
1045: return $output;
1046: }
1047:
1048: sub update_env {
1049: my ($cnum,$cdom,$chome,$need_env_update,$storehash) = @_;
1050: my $count = 0;
1051: if ((ref($need_env_update) eq 'ARRAY') && (ref($storehash) eq 'HASH')) {
1052: my %crsinfo = &Apache::lonnet::courseiddump($cdom,'.',1,'.','.',$cnum,undef,undef,'.');
1053: if (ref($crsinfo{$env{'request.course.id'}}) eq 'HASH') {
1054: foreach my $key (@{$need_env_update}) {
1055: if ($key eq 'description' && defined($storehash->{$key})) {
1056: &Apache::lonnet::appenv({'course.'.$env{'request.course.id'}.'.description' => $storehash->{$key}});
1057: $crsinfo{$env{'request.course.id'}}{'description'} = $storehash->{$key};
1058: $count ++;
1059: } elsif (($key eq 'cloners') || ($key eq 'hidefromcat') || ($key eq 'categories')) {
1060: &Apache::lonnet::appenv({'course.'.$env{'request.course.id'}.'.'.$key => $storehash->{$key}});
1061: $crsinfo{$env{'request.course.id'}}{$key} = $storehash->{$key};
1062: $count ++;
1063: }
1064: }
1065: if ($count) {
1066: my $putresult = &Apache::lonnet::courseidput($cdom,\%crsinfo,$chome,'notime');
1067: }
1068: }
1069: }
1070: return;
1071: }
1072:
1073: sub display_disallowed {
1.9 raeburn 1074: my ($item,$disallowed,$prefs,$crstype) = @_;
1.3 raeburn 1075: my $output;
1076: if ((ref($disallowed) eq 'HASH') && (ref($prefs) eq 'HASH')) {
1077: if (keys(%{$disallowed})) {
1078: if ($item eq 'cloners') {
1079: my @fails;
1080: my %lt = &Apache::lonlocal::texthash (
1081: format => 'Invalid format',
1082: domain => 'Domain does not exist',
1083: newuser => 'LON-CAPA user(s) do(es) not exist.',
1084: );
1085: foreach my $error ('format','domain','newuser') {
1086: if (defined($disallowed->{$error})) {
1087: my $msg = '<b>'.$disallowed->{$error}.'</b>, '.&mt('reason').' - '.
1088: $lt{$error};
1089: if ($error eq 'newuser') {
1.9 raeburn 1090: $msg .= '<br />'.&mt("Please [_1]add the user(s)[_2] before returning to the [_3]$crstype Configuration[_2] to add as potential cloners.",'<a href="/adm/createuser">','</a>','<a href="/adm/courseprefs">');
1.3 raeburn 1091: }
1092: push(@fails,$msg);
1093: }
1094: }
1095: if (@fails) {
1096: $output .= '<span class="LC_warning">'.&mt('Unable to add to allowed cloners: ').
1097: '</span>'.join('; ',@fails).'.<br />';
1098: }
1099: } elsif ($item eq 'rolenames') {
1100: my %lt = &Apache::lonlocal::texthash (
1101: replacements => 'Name already used to replace a different standard role name',
1102: regulars => 'Name already used as a standard role name',
1103: customrole => 'Name already used as the name of a custom role',
1104: );
1105: my @fails;
1106: foreach my $error ('replacements','regulars','customrole') {
1107: if (ref($disallowed->{$error}) eq 'ARRAY') {
1108: push(@fails,'<b>'.join(', ',@{$disallowed->{$error}}).
1109: '</b>, '.&mt('reason').' - '.$lt{'error'});
1110: }
1111: }
1112: if (@fails) {
1113: $output .= '<span class="LC_warning">'.
1114: &mt('Unable to include amongst replacements for role names: ').
1115: '</span>'.join('; ',@fails).'.<br />';
1116: }
1117:
1118: } elsif (($item eq 'feedback') || ($item eq 'discussion') || ($item eq 'localization')) {
1119: $output .= '<span class="LC_warning">';
1120: if ($item eq 'feedback') {
1.9 raeburn 1121: if ($crstype eq 'Community') {
1122: $output .= &mt('Unable to include as a recipient of community feedback for:');
1123: } else {
1124: $output .= &mt('Unable to include as a recipient of course feedback for:');
1125: }
1.3 raeburn 1126: } elsif ($item eq 'discussion') {
1127: $output .= &mt('Unable to include in user-based access control for:');
1128: } elsif ($item eq 'localization') {
1.9 raeburn 1129: if ($crstype eq 'Community') {
1130: $output .= &mt('Unable to include in community localization:');
1131: } else {
1132: $output .= &mt('Unable to include in course localization:');
1133: }
1.3 raeburn 1134: }
1135: $output .= '</span><ul>';
1136: foreach my $key (sort(keys(%{$disallowed}))) {
1137: my $itemtext = $prefs->{$item}{'itemtext'}{$key};
1138: $output .= '<li><i>'.$itemtext.'</i> - ';
1139: if ($item eq 'localization') {
1140: $output .= &mt('reason - unsupported language: [_1]',
1141: '<b>'.$disallowed->{$key}.'</b>');
1142: } else {
1143: $output .= &mt('reason - invalid user: [_1]',
1144: '<b>'.$disallowed->{$key}.'</b>').'</li>';
1145: }
1146: }
1147: $output .= '</ul><br />';
1148: }
1149: }
1.1 raeburn 1150: }
1.3 raeburn 1151: return $output;
1.1 raeburn 1152: }
1153:
1154: sub get_course {
1155: my ($courseid) = @_;
1156: if (!defined($courseid)) {
1157: $courseid = $env{'request.course.id'};
1158: }
1159: my $cdom=$env{'course.'.$courseid.'.domain'};
1160: my $cnum=$env{'course.'.$courseid.'.num'};
1161: return ($cnum,$cdom);
1162: }
1163:
1164: sub get_jscript {
1.12 raeburn 1165: my ($cdom,$phase,$crstype) = @_;
1166: my ($can_toggle_cat,$can_categorize) = &can_modify_catsettings($cdom,$crstype);
1.1 raeburn 1167: my ($jscript,$categorize_js);
1168: my $stubrowse_js = &Apache::loncommon::studentbrowser_javascript();
1169: my $browse_js = &Apache::loncommon::browser_and_searcher_javascript('parmset');
1.3 raeburn 1170: my $cloners_js = &cloners_javascript($phase);
1.1 raeburn 1171: if ($can_categorize) {
1172: $categorize_js = <<ENDSCRIPT;
1173: function catsbrowser() {
1174: var catswin = null;
1175: var url = '/adm/courseprefs?phase=categorizecourse';
1176: if (!catswin || catswin.closed) {
1177: catswin=window.open(url,'categorieswin','height=480,width=600,resizable=yes,scrollbars=yes,location=no,menubar=no,toolbar=no');
1178: } else {
1179: catswin.focus();
1180: }
1181: }
1182: ENDSCRIPT
1183: }
1184: $jscript = '<script type="text/javascript" language="Javascript">'."\n".
1.3 raeburn 1185: $browse_js."\n".$categorize_js."\n".$cloners_js."\n".'</script>'.
1186: "\n".$stubrowse_js."\n";
1.1 raeburn 1187: return $jscript;
1188: }
1189:
1.3 raeburn 1190: sub cloners_javascript {
1191: my ($formname) = @_;
1192: return <<"ENDSCRIPT";
1193:
1194: function update_cloners(caller,num) {
1195: var delidx = getIndexByName('cloners_delete');
1196: var actidx = getIndexByName('cloners_activate');
1197: if (caller == 'cloners_all') {
1198: var selall;
1199: for (var i=0; i<document.$formname.cloners_all.length; i++) {
1200: if (document.$formname.cloners_all[i].checked) {
1201: selall = document.$formname.cloners_all[i].value;
1202: }
1203: }
1204: if (selall == 1) {
1205: if (delidx != -1) {
1206: if (document.$formname.cloners_delete.length) {
1207: for (var j=0; j<document.$formname.cloners_delete.length; j++) {
1208: document.$formname.cloners_delete[j].checked = true;
1209: }
1210: } else {
1211: document.$formname.elements[delidx].checked = true;
1212: }
1213: }
1214: if (actidx != -1) {
1215: if (document.$formname.cloners_activate.length) {
1216: for (var i=0; i<document.$formname.cloners_activate.length; i++) {
1217: if (document.$formname.cloners_activate[i].value == '0') {
1218: document.$formname.cloners_activate[i].checked = false;
1219: }
1220: if (document.$formname.cloners_activate[i].value == '') {
1221: document.$formname.cloners_activate[i].checked = true;
1222: }
1223: }
1224: }
1225: }
1226: document.$formname.cloners_newdom.selectedIndex = 0;
1227: }
1228: }
1229: if (caller == 'cloners_activate') {
1230: if (document.$formname.cloners_activate.length) {
1231: for (var j=0; j<document.$formname.cloners_activate.length; j++) {
1232: if (document.$formname.cloners_activate[j].value == num) {
1233: if (document.$formname.cloners_activate[j].checked) {
1234: for (var i=0; i<document.$formname.cloners_all.length; i++) {
1235: if (document.$formname.cloners_all[i].value == '1') {
1236: document.$formname.cloners_all[i].checked = false;
1237: }
1238: if (document.$formname.cloners_all[i].value == '0') {
1239: document.$formname.cloners_all[i].checked = true;
1240: }
1241: }
1242: }
1243: }
1244: }
1245: } else {
1246: for (var i=0; i<document.$formname.cloners_all.length; i++) {
1247: if (document.$formname.cloners_all[i].value == '1') {
1248: document.$formname.cloners_all[i].checked = false;
1249: }
1250: if (document.$formname.cloners_all[i].value == '0') {
1251: document.$formname.cloners_all[i].checked = true;
1252: }
1253: }
1254: }
1255: }
1256: return;
1257: }
1258:
1259: function getIndexByName(item) {
1260: for (var i=0;i<document.$formname.elements.length;i++) {
1261: if (document.$formname.elements[i].name == item) {
1262: return i;
1263: }
1264: }
1265: return -1;
1266: }
1267:
1268: ENDSCRIPT
1269: }
1270:
1271:
1.1 raeburn 1272: sub print_courseinfo {
1.9 raeburn 1273: my ($cdom,$settings,$ordered,$itemtext,$rowtotal,$crstype) = @_;
1.3 raeburn 1274: unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
1.1 raeburn 1275: return;
1276: }
1277: my ($cathash,$categoriesform);
1278: my %domconf =
1279: &Apache::lonnet::get_dom('configuration',['coursecategories'],$cdom);
1280: if (ref($domconf{'coursecategories'}) eq 'HASH') {
1281: $cathash = $domconf{'coursecategories'}{'cats'};
1282: if (ref($cathash) eq 'HASH') {
1283: $categoriesform =
1284: &Apache::loncommon::assign_categories_table($cathash,
1.12 raeburn 1285: $settings->{'categories'},$crstype)."\n";
1.1 raeburn 1286: }
1287: }
1288: if (!defined($categoriesform)) {
1.15 raeburn 1289: $categoriesform = &mt('No categories defined in this domain.');
1.1 raeburn 1290: }
1291:
1.12 raeburn 1292: my ($can_toggle_cat,$can_categorize) = &can_modify_catsettings($cdom,$crstype);
1.1 raeburn 1293:
1.9 raeburn 1294: my $replace;
1295: if ($crstype eq 'Community') {
1296: $replace = &mt('To replace the standard title for a course role, enter a title, otherwise leave blank');
1297: } else {
1298: $replace = &mt('To replace the standard title for a course role, enter a title, otherwise leave blank');
1299: }
1.1 raeburn 1300: my %items = (
1.3 raeburn 1301: 'url' => {
1302: text => '<b>'.&mt($itemtext->{'url'}).'</b>'.(' 'x2).
1.1 raeburn 1303: '<a href="javascript:openbrowser'.
1304: "('display','url','sequence')\">".
1305: &mt('Select Map').'</a><br /><span class="LC_warning"> '.
1306: &mt('Modification may make assessment data inaccessible!').
1307: '</span>',
1308: input => 'textbox',
1309: size => '40',
1.19 faziophi 1310: advanced => 1
1.1 raeburn 1311: },
1312: 'description' => {
1.3 raeburn 1313: text => '<b>'.&mt($itemtext->{'description'}).'</b>',
1.1 raeburn 1314: input => 'textbox',
1315: size => '25',
1316: },
1317: 'courseid' => {
1.3 raeburn 1318: text => '<b>'.&mt($itemtext->{'courseid'}).'</b><br />'.'('.
1319: &mt('internal, optional').')',
1.1 raeburn 1320: input => 'textbox',
1321: size => '25',
1322: },
1323: 'cloners' => {
1.3 raeburn 1324: text => '<b>'.&mt($itemtext->{'cloners'}).'</b><br />'.
1.9 raeburn 1325: &mt('Coordinators included automatically'),
1.1 raeburn 1326: input => 'textbox',
1327: size => '40',
1.19 faziophi 1328: advanced => 1
1.1 raeburn 1329: },
1330: 'rolenames' => {
1.3 raeburn 1331: text => '<b>'.&mt($itemtext->{'rolenames'}).'</b><br />'.
1.9 raeburn 1332: '('.$replace.')',
1.1 raeburn 1333: input => 'textbox',
1334: size => '20',
1.19 faziophi 1335: advanced => 1
1.1 raeburn 1336: },
1337: 'externalsyllabus' => {
1.3 raeburn 1338: text => '<b>'.&mt($itemtext->{'externalsyllabus'}).'</b><br />('.
1339: &mt('not using syllabus template)'),
1.1 raeburn 1340: input => 'textbox',
1341: size => '40',
1342: },
1343: 'hidefromcat' => {
1.3 raeburn 1344: text => '<b>'.&mt($itemtext->{'hidefromcat'}).'</b><br />'.
1.1 raeburn 1345: ' ('.&mt('included by default if assigned institutional code, or categorized').')',
1346: input => 'radio',
1347: },
1348: 'categories' => {
1.3 raeburn 1349: text => '<b>'.&mt($itemtext->{'categories'}).'</b> <a href="javascript:catsbrowser()">'.
1.1 raeburn 1350: &mt('Display Categories').'</a>',
1351: input => 'textbox',
1352: size => '25',
1353: },
1354: );
1355: my $datatable;
1356: my $count = 0;
1357: foreach my $item (@{$ordered}) {
1358: if ($item eq 'hidefromcat') {
1359: next if (!$can_toggle_cat);
1360: } elsif ($item eq 'categories') {
1361: next if (!$can_categorize);
1362: }
1363: $count ++;
1.19 faziophi 1364: if (exists $items{$item}{advanced} && $items{$item}{advanced} == 1) {
1365: $datatable .= &item_table_row_start($items{$item}{text},$count,"advanced");
1366: } else {
1367: $datatable .= &item_table_row_start($items{$item}{text},$count);
1368: }
1.1 raeburn 1369: if ($items{$item}{input} eq 'radio') {
1370: $datatable .= &yesno_radio($item,$settings);
1371: } elsif ($item eq 'cloners') {
1372: my $includeempty = 1;
1373: my $num = 0;
1374: $datatable .= &Apache::loncommon::start_data_table().
1375: &Apache::loncommon::start_data_table_row().
1376: '<td><span class="LC_nobreak"><label>'.
1377: &mt('Any user in any domain:').
1378: ' <input type="radio" name="cloners_all" value="1" ';
1379: if ($settings->{$item} eq '*') {
1380: $datatable .= ' checked="checked" ';
1381: }
1382: $datatable .= 'onchange="javascript:update_cloners('.
1383: "'cloners_all'".');" />'.&mt('Yes').'</label>'.
1384: (' 'x2).'<input type="radio" name="cloners_all" value="0" ';
1385: if ($settings->{$item} ne '*') {
1386: $datatable .= ' checked="checked" ';
1387: }
1388: $datatable .= ' onchange="javascript:update_cloners('.
1389: "'cloners_all'".');"/>'.&mt('No').'</label></td>'.
1390: &Apache::loncommon::end_data_table_row().
1391: &Apache::loncommon::end_data_table().
1392: '<table><tr><td align="left">'.&mt('Or').
1393: '</td></tr></table>'.
1394: &Apache::loncommon::start_data_table();
1395: my @cloners;
1396: if ($settings->{$item} eq '') {
1397: $datatable .= &new_cloners_dom_row($cdom,'0');
1398: } elsif ($settings->{$item} ne '*') {
1399: my @entries = split(/,/,$settings->{$item});
1400: if (@entries > 0) {
1401: foreach my $entry (@entries) {
1402: my ($uname,$udom) = split(/:/,$entry);
1403: if ($uname eq '*') {
1404: $datatable .=
1405: &Apache::loncommon::start_data_table_row().
1.3 raeburn 1406: '<td valign="top" align="left"><span class="LC_nobreak">'.
1.1 raeburn 1407: &mt('Domain:').'<b> '.$udom.
1408: '</b><input type="hidden" name="cloners_dom_'.$num.
1409: '" value="'.$udom.'" /></span><br />'.
1410: '<span class="LC_nobreak"><label><input type="checkbox" '.
1.3 raeburn 1411: 'name="cloners_delete" value="'.$num.'" onchange="javascript:update_cloners('."'cloners_delete','$num'".');" />'.
1.1 raeburn 1412: &mt('Delete').'</label></span></td>'.
1413: &Apache::loncommon::end_data_table_row();
1414: $num ++;
1415: } else {
1416: push(@cloners,$entry);
1417: }
1418: }
1419: }
1420: }
1421: my $add_domtitle = &mt('Any user in additional domain:');
1422: if ($settings->{$item} eq '*') {
1423: $add_domtitle = &mt('Any user in specific domain:');
1424: } elsif ($settings->{$item} eq '') {
1425: $add_domtitle = &mt('Any user in other domain:');
1426: }
1427: my $cloners_str = join(',',@cloners);
1428: $datatable .= &Apache::loncommon::start_data_table_row().
1429: '<td align="left"><span class="LC_nobreak">'.
1430: $add_domtitle.'</span><br />'.
1431: &Apache::loncommon::select_dom_form('','cloners_newdom',
1432: $includeempty).
1433: '<input type="hidden" name="cloners_total" value="'.$num.'" />'.
1434: '</td>'.&Apache::loncommon::end_data_table_row().
1.3 raeburn 1435: &Apache::loncommon::end_data_table().
1436: '<table><tr><td align="left">'.&mt('And').
1437: '</td></tr></table>'.
1.1 raeburn 1438: &Apache::loncommon::start_data_table().
1439: &Apache::loncommon::start_data_table_row().
1440: '<td align="left">'.
1441: &mt('Specific users').' (<tt>'.
1442: &mt('user:domain,user:domain').'</tt>)<br />'.
1443: &Apache::lonhtmlcommon::textbox($item,$cloners_str,
1444: $items{$item}{'size'}).
1445: '</td>'.&Apache::loncommon::end_data_table_row().
1446: &Apache::loncommon::end_data_table();
1447: } elsif ($item eq 'rolenames') {
1448: $datatable .= &Apache::loncommon::start_data_table();
1.9 raeburn 1449: my @roles;
1450: if ($crstype eq 'Community') {
1451: @roles = ('co');
1452: } else {
1453: @roles = ('cc');
1454: }
1455: push (@roles,('in','ta','ep','ad','st'));
1456: foreach my $role (@roles) {
1.1 raeburn 1457: $datatable .= &Apache::loncommon::start_data_table_row().
1458: '<td align="left"><span class="LC_nobreak">'.
1459: &Apache::lonnet::plaintext($role,$crstype,undef,1).
1460: '</span></td><td align="left">'.
1461: &Apache::lonhtmlcommon::textbox('rolenames_'.$role,
1462: $settings->{$role.'.plaintext'},
1463: $items{$item}{size}).'</td>'.
1464: &Apache::loncommon::end_data_table_row();
1465: }
1466: $datatable .= &Apache::loncommon::end_data_table().'</td>';
1467: } elsif ($item eq 'categories') {
1.3 raeburn 1468: my $launcher = 'onFocus="this.blur();javascript:catsbrowser();";';
1469: $datatable .= '<input type="hidden" name="categories" value="'.$settings->{$item}.'" />'.
1470: &Apache::lonhtmlcommon::textbox($item.'_display',$settings->{$item},
1471: $items{$item}{size},$launcher);
1.1 raeburn 1472: } else {
1473: $datatable .= &Apache::lonhtmlcommon::textbox($item,$settings->{$item},$items{$item}{size});
1474: }
1475: $datatable .= &item_table_row_end();
1476: }
1477: $$rowtotal += scalar(@{$ordered});
1478: return $datatable;
1479: }
1480:
1481: sub new_cloners_dom_row {
1482: my ($newdom,$num) = @_;
1483: my $output;
1484: if ($newdom ne '') {
1485: $output .= &Apache::loncommon::start_data_table_row().
1486: '<td valign="top"><span class="LC_nobreak">'.
1487: &mt('Any user in domain:').' <b>'.$newdom.'</b>'.
1488: (' 'x2).'<label><input type="radio" '.
1489: 'name="cloners_activate" value="'.$num.'" '.
1.3 raeburn 1490: 'onchange="javascript:update_cloners('.
1.1 raeburn 1491: "'cloners_activate','$num'".');" />'.
1492: &mt('Yes').'</label>'.(' 'x2).
1493: '<label><input type="radio" '.
1494: 'name="cloners_activate" value="" checked="checked" '.
1.3 raeburn 1495: 'onchange="javascript:update_cloners('.
1.1 raeburn 1496: "'cloners_activate','$num'".');" />'.
1.3 raeburn 1497: &mt('No').'</label><input type="hidden" name="cloners_dom_'.
1498: $num.'" value="'.$newdom.'" /></span></td>'.
1.1 raeburn 1499: &Apache::loncommon::end_data_table_row();
1500: }
1501: return $output;
1502: }
1503:
1504: sub can_modify_catsettings {
1.12 raeburn 1505: my ($dom,$crstype) = @_;
1.1 raeburn 1506: my %domconf = &Apache::lonnet::get_dom('configuration',['coursecategories'],$dom);
1507: my ($can_toggle_cat,$can_categorize);
1508: if (ref($domconf{'coursecategories'}) eq 'HASH') {
1.12 raeburn 1509: if ($crstype eq 'Community') {
1510: if ($domconf{'coursecategories'}{'togglecatscomm'} eq 'comm') {
1511: $can_toggle_cat = 1;
1512: }
1513: if ($domconf{'coursecategories'}{'categorizecomm'} eq 'comm') {
1514: $can_categorize = 1;
1515: }
1516: } else {
1517: if ($domconf{'coursecategories'}{'togglecats'} eq 'crs') {
1518: $can_toggle_cat = 1;
1519: }
1520: if ($domconf{'coursecategories'}{'categorize'} eq 'crs') {
1521: $can_categorize = 1;
1522: }
1.1 raeburn 1523: }
1524: }
1525: return ($can_toggle_cat,$can_categorize);
1526: }
1527:
1528: sub assign_course_categories {
1.9 raeburn 1529: my ($r,$crstype) = @_;
1.1 raeburn 1530: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
1531: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
1532: my $hascats = 0;
1533: my $cathash;
1534: my %domconf = &Apache::lonnet::get_dom('configuration',['coursecategories'],$cdom);
1535: if (ref($domconf{'coursecategories'}) eq 'HASH') {
1536: $cathash = $domconf{'coursecategories'}{'cats'};
1537: if (ref($cathash) eq 'HASH') {
1.12 raeburn 1538: foreach my $cat (keys(%{$cathash})) {
1539: next if ($cat eq 'instcode::0');
1540: unless ($crstype eq 'Community') {
1541: next if ($cat eq 'communities::0');
1542: }
1543: $hascats ++;
1544: }
1.1 raeburn 1545: }
1546: }
1547: my $catwin_js;
1548: if ($hascats) {
1.9 raeburn 1549: my $alert;
1550: if ($crstype eq 'Community') {
1551: $alert = &mt("Use 'Save' in the main window to save community categories");
1552: } else {
1553: $alert = &mt("Use 'Save' in the main window to save course categories");
1554: }
1.1 raeburn 1555: $catwin_js = <<ENDSCRIPT;
1556: <script type="text/javascript">
1557:
1558: function updateCategories() {
1559: var newcategories = '';
1560: var unescapedcats = '';
1561: if (document.chgcats.usecategory.length) {
1562: for (var i=0; i<document.chgcats.usecategory.length; i++) {
1563: if (document.chgcats.usecategory[i].checked == true) {
1564: newcategories = newcategories + document.chgcats.usecategory[i].value + '&';
1565: unescapedcats = unescapedcats + document.chgcats.catname[i].value + ' & ';
1566: }
1567: }
1568: if (newcategories.length > 0) {
1569: newcategories = newcategories.slice(0,-1);
1570: }
1571: if (unescapedcats.length > 0) {
1572: unescapedcats = unescapedcats.slice(0,-3);
1573: }
1574: } else {
1575: if (document.chgcats.usecategory.checked == true) {
1576: newcategories = document.chgcats.usecategory.value;
1577: unescapedcats = document.chgcats.catname.value;
1578: }
1579: }
1580: opener.document.display.categories.value = newcategories;
1581: opener.document.display.categories_display.value = unescapedcats;
1582: alert("$alert");
1583: self.close();
1584: return;
1585: }
1586:
1587: </script>
1588: ENDSCRIPT
1589: } else {
1590: my $onload;
1591: }
1.9 raeburn 1592: my ($crscat,$catcrs,$assign);
1593: if ($crstype eq 'Community') {
1594: $crscat = 'Community Categories';
1595: $catcrs = &mt('Categorize Community');
1596: $assign = &mt('Assign one or more categories to this community.')
1597: } else {
1598: $crscat = 'Course Categories';
1599: $catcrs = &mt('Categorize Course');
1600: $assign = &mt('Assign one or more categories to this course.')
1601: }
1.1 raeburn 1602: my $start_page =
1.9 raeburn 1603: &Apache::loncommon::start_page($crscat,$catwin_js,
1.1 raeburn 1604: {'only_body' => 1,});
1605: my $end_page = &Apache::loncommon::end_page();
1.9 raeburn 1606: my $categoriesform = '<h3>'.$catcrs.'</h3>';
1.1 raeburn 1607: if ($hascats) {
1608: my %currsettings =
1609: &Apache::lonnet::get('environment',['hidefromcat','categories'],$cdom,$cnum);
1.12 raeburn 1610: my $cattable = &Apache::loncommon::assign_categories_table($cathash,
1611: $currsettings{'categories'},$crstype);
1612: if ($cattable eq '') {
1613: $categoriesform .= &mt('No suitable categories defined for this course type in this domain.');
1614: } else {
1615: $categoriesform .= $assign.'<br /><br />'.
1616: '<form name="chgcats" action="/adm/courseprefs" method="post">'."\n".
1617: $cattable."\n".
1618: '<br /><input type="button" name="changes" value="'.
1619: &mt('Copy to main window').'" '.
1620: 'onclick="javascript:updateCategories()" /></form><br />';
1621: }
1.1 raeburn 1622: } else {
1.12 raeburn 1623: $categoriesform .= &mt('No categories defined in this domain.');
1.1 raeburn 1624: }
1625: $r->print($start_page.$categoriesform.$end_page);
1626: return;
1627: }
1628:
1629: sub print_localization {
1.3 raeburn 1630: my ($cdom,$settings,$ordered,$itemtext,$rowtotal) = @_;
1631: unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
1.1 raeburn 1632: return;
1633: }
1634: my %items = (
1635: languages => {
1.17 faziophi 1636: text => '<b>'.&mt($itemtext->{'languages'}).'</b><br />'.
1637: &mt("(overrides individual user preference)"),
1.1 raeburn 1638: input => 'selectbox',
1639: },
1640: timezone => {
1.17 faziophi 1641: text => '<b>'.&mt($itemtext->{'timezone'}).'</b>',
1.1 raeburn 1642: input => 'selectbox',
1643: },
1644: datelocale => {
1.17 faziophi 1645: text => '<b>'.&mt($itemtext->{'datelocale'}).'</b>',
1.1 raeburn 1646: input => 'selectbox',
1647: },
1648: );
1649: my $datatable;
1650: my $count = 0;
1651: foreach my $item (@{$ordered}) {
1652: $count ++;
1653: $datatable .= &item_table_row_start($items{$item}{text},$count);
1654: if ($item eq 'timezone') {
1655: my $includeempty = 1;
1656: my $timezone = &Apache::lonlocal::gettimezone();
1657: $datatable .=
1658: &Apache::loncommon::select_timezone($item,$timezone,undef,
1659: $includeempty);
1660: } elsif ($item eq 'datelocale') {
1661: my $includeempty = 1;
1662: my $locale_obj = &Apache::lonlocal::getdatelocale();
1663: my $currdatelocale;
1664: if (ref($locale_obj)) {
1665: $currdatelocale = $locale_obj->id();
1666: }
1667: $datatable .=
1668: &Apache::loncommon::select_datelocale($item,$currdatelocale,
1669: undef,$includeempty);
1670: } else {
1671: if ($settings->{$item} eq '') {
1672: $datatable .=
1.3 raeburn 1673: &Apache::loncommon::select_language('languages_0','',1);
1.1 raeburn 1674: } else {
1675: my $num = 0;
1.3 raeburn 1676: my @languages = split(/\s*[,;:]\s*/,$settings->{$item});
1.1 raeburn 1677: $datatable .= &Apache::loncommon::start_data_table();
1678: if (@languages > 0) {
1.3 raeburn 1679: my %langchoices = &get_lang_choices();
1.1 raeburn 1680: foreach my $lang (@languages) {
1681: my $showlang = $lang;
1.3 raeburn 1682: if (exists($langchoices{$lang})) {
1683: $showlang = $langchoices{$lang};
1.1 raeburn 1684: }
1685: $datatable .=
1686: &Apache::loncommon::start_data_table_row().
1.3 raeburn 1687: '<td align="left"><span class="LC_nobreak">'.
1.1 raeburn 1688: &mt('Language:').'<b> '.$showlang.
1689: '</b><input type="hidden" name="languages_'.$num.
1690: '" value="'.$lang.'" /></span><br />'.
1691: '<span class="LC_nobreak"><label><input type="checkbox" '.
1692: 'name="languages_delete" value="'.$num.'" />'.
1693: &mt('Delete').'</label></span></td>'.
1.3 raeburn 1694: &Apache::loncommon::end_data_table_row();
1.1 raeburn 1695: $num ++;
1696: }
1697: }
1698: $datatable .= &Apache::loncommon::start_data_table_row().
1.3 raeburn 1699: '<td align="left"><span class="LC_nobreak">'.
1700: &mt('Additional language:'). '</span><br />'.
1701: &Apache::loncommon::select_language('languages_'.$num,'',1).
1.1 raeburn 1702: '<input type="hidden" name="languages_total" value="'.$num.'" />'.
1703: '</td>'.&Apache::loncommon::end_data_table_row().
1704: &Apache::loncommon::end_data_table();
1705: }
1706: }
1707: $datatable .= &item_table_row_end();
1708: }
1709: $$rowtotal += scalar(@{$ordered});
1710: return $datatable;
1711: }
1712:
1.3 raeburn 1713: sub get_lang_choices {
1714: my %langchoices;
1715: foreach my $id (&Apache::loncommon::languageids()) {
1716: my $code = &Apache::loncommon::supportedlanguagecode($id);
1717: if ($code) {
1718: $langchoices{$code} = &Apache::loncommon::plainlanguagedescription($id);
1719: }
1720: }
1721: return %langchoices;
1722: }
1723:
1.1 raeburn 1724: sub print_feedback {
1.3 raeburn 1725: my ($position,$cdom,$settings,$ordered,$itemtext,$rowtotal) = @_;
1726: unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
1.1 raeburn 1727: return;
1728: }
1729: my %items = (
1.3 raeburn 1730: 'question.email' => {
1731: text => '<b>'.&mt($itemtext->{'question.email'}).'</b>',
1.1 raeburn 1732: input => 'textbox',
1733: size => '50',
1734: },
1735:
1.3 raeburn 1736: 'comment.email' => {
1737: text => '<b>'.&mt($itemtext->{'comment.email'}).'</b>',
1.1 raeburn 1738: input => 'textbox',
1739: size => '50',
1740: },
1741:
1.3 raeburn 1742: 'policy.email' => {
1743: text => '<b>'.&mt($itemtext->{'policy.email'}).'</b>',
1.1 raeburn 1744: input => 'textbox',
1745: size => '50',
1746: },
1747: );
1748: my $datatable;
1749: my $count = 0;
1750: my ($cnum) = &get_course();
1751: my %sections = &Apache::loncommon::get_sections($cdom,$cnum);
1752: my @sections = sort( { $a <=> $b } keys(%sections));
1753: my %lt = &Apache::lonlocal::texthash (
1754: currone => 'Current recipient:',
1755: curmult => 'Current recipients:',
1756: add => 'Additional recipient:',
1757: del => 'Delete?',
1758: sec => 'Sections:',
1759: );
1760:
1761: foreach my $item (@{$ordered}) {
1762: $count ++;
1.20 ! faziophi 1763: if ($position eq 'top') {
! 1764: $datatable .= &item_table_row_start($items{$item}{text},$count);
! 1765: } else {
! 1766: $datatable .= &item_table_row_start($items{$item}{text}."<br/>(Custom text)",$count, "advanced");
! 1767: }
1.1 raeburn 1768: if ($position eq 'top') {
1769: my $includeempty = 0;
1770: $datatable .= &user_table($cdom,$item,\@sections,
1.3 raeburn 1771: $settings->{$item},\%lt);
1.1 raeburn 1772: } else {
1.3 raeburn 1773: $datatable .= &Apache::lonhtmlcommon::textbox($item.'.text',
1774: $settings->{$item.'.text'},$items{$item}{size});
1.1 raeburn 1775: }
1776: $datatable .= &item_table_row_end();
1777: }
1778: $$rowtotal += scalar(@{$ordered});
1779: return $datatable;
1780: }
1781:
1782: sub user_table {
1783: my ($cdom,$item,$sections,$currvalue,$lt) = @_;
1784: my $output;
1785: if ($currvalue eq '') {
1786: $output .= &select_recipient($item,'0',$cdom,$sections);
1787: } else {
1788: my $num = 0;
1789: my @curr = split(/,/,$currvalue);
1.10 raeburn 1790: $output .= '<table class="LC_nested_outer">';
1.1 raeburn 1791: my ($currusers);
1792: foreach my $val (@curr) {
1793: next if ($val eq '');
1794: my ($uname,$udom,$seclist) = ($val =~ /^($match_username):($match_domain)(\(?[^\)]*\)?)$/);
1795: my @selsec;
1796: if ($seclist) {
1797: $seclist =~ s/(^\(|\)$)//g;
1798: @selsec = split(/\s*;\s*/,$seclist);
1799: }
1800: $currusers .= '<tr>'.
1801: '<td valign="top"><span class="LC_nobreak">'.
1802: '<label><input type="checkbox" '.
1803: 'name="'.$item.'_delete" value="'.$num.'" />'.
1804: $lt->{'del'}.'</label>'.
1805: '<input type="hidden" name="'.$item.'_user_'.
1.3 raeburn 1806: $num.'" value="'.$uname.':'.$udom.'" />'.(' 'x2).
1.1 raeburn 1807: &Apache::loncommon::aboutmewrapper(
1808: &Apache::loncommon::plainname($uname,$udom,'firstname'),
1809: $uname,$udom,'aboutuser');
1810: if (ref($sections) eq 'ARRAY') {
1811: if (@{$sections}) {
1812: $currusers.= (' 'x3).$lt->{'sec'}.' '.
1813: &select_sections($item,$num,$sections,
1814: \@selsec);
1815: }
1816: }
1817: $currusers .= '</span></td></tr>';
1818: $num ++;
1819: }
1820: if ($num) {
1.10 raeburn 1821: $output .= '<tr>'.
1.1 raeburn 1822: '<td align="left"><i>';
1.20 ! faziophi 1823: if ($num == 1) {
1.1 raeburn 1824: $output .= $lt->{'currone'};
1825: } else {
1.20 ! faziophi 1826: $output .= $lt->{'curmult'};
1.1 raeburn 1827: }
1828: $output .= '</i><br />'.
1829: '<table>'.$currusers.'</table></td>'.
1.10 raeburn 1830: '</tr>';
1.1 raeburn 1831: }
1.10 raeburn 1832: $output .= '<tr>'.
1.1 raeburn 1833: '<td align="left"><span class="LC_nobreak"><i>'.
1834: $lt->{'add'}.'</i></span><br />'.
1835: &select_recipient($item,$num,$cdom,$sections).
1836: '<input type="hidden" name="'.$item.'_total" value="'.$num.'" />'.
1.10 raeburn 1837: '</td></tr></table>';
1.1 raeburn 1838: }
1839: return $output;
1840: }
1841:
1842: sub select_recipient {
1843: my ($item,$num,$cdom,$sections,$selected,$includeempty) = @_;
1844: my $domform = &Apache::loncommon::select_dom_form($cdom,$item.'_udom_'.$num,$includeempty);
1845: my $selectlink =
1846: &Apache::loncommon::selectstudent_link('display',$item.'_uname_'.$num,
1847: $item.'_udom_'.$num,1);
1848: my $output =
1.10 raeburn 1849: '<table><tr><td align="center">'.&mt('Username').'<br />'.
1.1 raeburn 1850: '<input type="text" name="'.$item.'_uname_'.$num.'" value="" /></td>'.
1851: '<td align="center">'.&mt('Domain').'<br />'.$domform.'</td>';
1852: if (ref($sections) eq 'ARRAY') {
1853: if (@{$sections}) {
1854: $output .= '<td align="center">'.&mt('Sections').'<br />'.
1855: &select_sections($item,$num,$sections,$selected).'</td>';
1856: }
1857: }
1858: $output .= '<td valign="top">'.
1859: $selectlink.'</td></tr></table>';
1860: return $output;
1861: }
1862:
1863: sub select_sections {
1864: my ($item,$num,$sections,$selected) = @_;
1865: my ($output,@currsecs,$allsec);
1866: if (ref($selected) eq 'ARRAY') {
1867: @currsecs = @{$selected};
1868: }
1869: if (!@currsecs) {
1870: $allsec = ' selected="selected"';
1871: }
1872: if (ref($sections) eq 'ARRAY') {
1873: if (@{$sections}) {
1874: my $mult;
1875: if (@{$sections} > 1) {
1876: $mult = ' multiple="multiple"';
1877: if (@{$sections} > 3) {
1878: $mult .= ' size="4"';
1879: }
1880: }
1881: $output = '<select name="'.$item.'_sections_'.$num.'"'.$mult.'>'.
1882: ' <option value=""'.$allsec.'>'.&mt('All').'</option>';
1883: foreach my $sec (@{$sections}) {
1884: my $is_sel;
1885: if ((@currsecs) && (grep(/^\Q$sec\E$/,@currsecs))) {
1886: $is_sel = 'selected="selected"';
1887: }
1888: $output .= '<option value="'.$sec.'"'.$is_sel.'>'.$sec.'</option>';
1889: }
1890: $output .= '</select>';
1891: }
1892: }
1893: return $output;
1894: }
1895:
1896: sub print_discussion {
1.3 raeburn 1897: my ($cdom,$settings,$ordered,$itemtext,$rowtotal) = @_;
1898: unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
1.1 raeburn 1899: return;
1900: }
1901: my %items = (
1902: 'plc.roles.denied' => {
1.10 raeburn 1903: text => '<span class="LC_nobreak"><b>'.&mt($itemtext->{'plc.roles.denied'}).'</b>'.
1904: &Apache::loncommon::help_open_topic("Course_Disable_Discussion").'</span><br />'.
1.5 raeburn 1905: &mt('(role-based)'),
1.1 raeburn 1906: input => 'checkbox',
1907: },
1908:
1909: 'plc.users.denied' => {
1.3 raeburn 1910: text => '<b>'.&mt($itemtext->{'plc.users.denied'}).'</b><br />'.
1911: &mt('(specific user(s))'),
1.1 raeburn 1912: input => 'checkbox',
1913: },
1914:
1915: 'pch.roles.denied' => {
1.10 raeburn 1916: text => '<span class="LC_nobreak"><b>'.&mt($itemtext->{'pch.roles.denied'}).'</b>'.
1917: &Apache::loncommon::help_open_topic("Course_Disable_Discussion").'</span><br />'.
1.3 raeburn 1918: &mt('(role-based)'),
1.1 raeburn 1919: input => 'checkbox',
1920: },
1921:
1922: 'pch.users.denied' => {
1.3 raeburn 1923: text => '<b>'.&mt($itemtext->{'pch.users.denied'}).'</b><br />'.
1924: &mt('(specific user(s))'),
1.1 raeburn 1925: input => 'checkbox',
1926: },
1927: 'allow_limited_html_in_feedback' => {
1.3 raeburn 1928: text => '<b>'.&mt($itemtext->{'allow_limited_html_in_feedback'}).'</b>',
1.1 raeburn 1929: input => 'radio',
1930: },
1931:
1932: 'allow_discussion_post_editing' => {
1.3 raeburn 1933: text => '<b>'.&mt($itemtext->{'allow_discussion_post_editing'}).'</b>',
1.1 raeburn 1934: input => 'checkbox',
1935: },
1936: );
1937: my $datatable;
1938: my $count;
1939: my ($cnum) = &get_course();
1940: my %sections = &Apache::loncommon::get_sections($cdom,$cnum);
1941: my @sections = sort( { $a <=> $b } keys(%sections));
1942: my %lt = &Apache::lonlocal::texthash (
1943: currone => 'Disallowed:',
1944: curmult => 'Disallowed:',
1945: add => 'Disallow more:',
1946: del => 'Delete?',
1947: sec => 'Sections:',
1948: );
1949:
1950: foreach my $item (@{$ordered}) {
1951: $count ++;
1952: $datatable .= &item_table_row_start($items{$item}{text},$count);
1953: if ($item eq 'plc.roles.denied') {
1954: $datatable .= '<table>'.&role_checkboxes($cdom,$cnum,$item,$settings).
1955: '</table>';
1956: } elsif ($item eq 'plc.users.denied') {
1957: $datatable .= &user_table($cdom,$item,undef,
1958: $settings->{$item},\%lt);
1959: } elsif ($item eq 'pch.roles.denied') {
1960: $datatable .= '<table>'.&role_checkboxes($cdom,$cnum,$item,$settings).
1961: '</table>';
1962: } elsif ($item eq 'pch.users.denied') {
1963: $datatable .= &user_table($cdom,$item,undef,
1964: $settings->{$item},\%lt);
1965: } elsif ($item eq 'allow_limited_html_in_feedback') {
1966: $datatable .= &yesno_radio($item,$settings);
1967: } elsif ($item eq 'allow_discussion_post_editing') {
1968: $datatable .= &Apache::loncommon::start_data_table().
1969: &Apache::loncommon::start_data_table_row().
1970: '<th align="left">'.&mt('Role').'</th><th>'.
1971: &mt('Sections').'</th>'.
1972: &Apache::loncommon::end_data_table_row().
1973: &role_checkboxes($cdom,$cnum,$item,$settings,1).
1974: &Apache::loncommon::end_data_table();
1975: }
1976: $datatable .= &item_table_row_end();
1977: }
1978: $$rowtotal += scalar(@{$ordered});
1979: return $datatable;
1980: }
1981:
1982: sub role_checkboxes {
1.9 raeburn 1983: my ($cdom,$cnum,$item,$settings,$showsections,$crstype) = @_;
1984: my @roles = ('st','ad','ta','ep','in');
1985: if ($crstype eq 'Community') {
1986: push(@roles,'co');
1987: } else {
1988: push(@roles,'cc');
1989: }
1.1 raeburn 1990: my $output;
1991: my (@current,@curr_roles,%currsec,@sections);
1992: if ($showsections) {
1993: my %sections = &Apache::loncommon::get_sections($cdom,$cnum);
1994: @sections = sort( { $a <=> $b } keys(%sections));
1995: }
1996: if (ref($settings) eq 'HASH') {
1997: if ($settings->{$item}) {
1998: @current = split(',',$settings->{$item});
1999: if ($showsections) {
2000: foreach my $role (@current) {
2001: if ($role =~ /:/) {
2002: my ($trole,$sec) = split(':',$role);
2003: push(@curr_roles,$trole);
2004: if (ref($currsec{$trole}) eq 'ARRAY') {
2005: if (!grep(/^\Q$sec\E/,@{$currsec{$trole}})) {
2006: push(@{$currsec{$trole}},$sec);
2007: }
1.3 raeburn 2008: } else {
2009: $currsec{$trole} = [$sec];
1.1 raeburn 2010: }
2011: } else {
2012: push(@curr_roles,$role);
2013: }
2014: }
2015: @current = @curr_roles;
2016: }
2017: }
2018: }
2019: my $numinrow = 3;
2020: my $count = 0;
2021: foreach my $role (@roles) {
2022: my $checked = '';
2023: if (grep(/^\Q$role\E$/,@current)) {
2024: $checked = ' checked="checked" ';
2025: }
1.9 raeburn 2026: my $plrole=&Apache::lonnet::plaintext($role,$crstype);
1.1 raeburn 2027: if ($showsections) {
2028: $output .= &Apache::loncommon::start_data_table_row();
2029: } else {
2030: my $rem = $count%($numinrow);
2031: if ($rem == 0) {
2032: if ($count > 0) {
2033: $output .= '</tr>';
2034: }
2035: $output .= '<tr>';
2036: }
2037: }
2038: $output .= '<td align="left"><span class="LC_nobreak"><label><input type="checkbox" name='.
2039: $item.'" value="'.$role.'"'.$checked.'/> '.
2040: $plrole.'</label></span></td>';
2041: if ($showsections) {
2042: $output .= '<td align="left">'.
2043: &select_sections($item,$role,\@sections,$currsec{$role}).
2044: '</td></tr>';
2045: }
2046: $count ++;
2047: }
2048: my %adv_roles =
2049: &Apache::lonnet::get_course_adv_roles($env{'request.course.id'},1);
2050: my $total = @roles;
2051: foreach my $role (sort(keys(%adv_roles))) {
2052: if ($role =~ m{^cr/($match_domain)/($match_name)/\w$}) {
2053: my $rolename = $3;
2054: my $value = 'cr_'.$1.'_'.$2.'_'.$rolename;
2055: my $checked = '';
2056: if (grep(/^\Q$value\E$/,@current)) {
2057: $checked = ' checked="checked" ';
2058: }
2059: if ($showsections) {
2060: $output .= &Apache::loncommon::start_data_table_row();
2061: } else {
2062: my $rem = $count%($numinrow);
2063: if ($rem == 0) {
2064: if ($count > 0) {
2065: $output .= '</tr>';
2066: }
2067: $output .= '<tr>';
2068: }
2069: }
2070: $output .= '<td><span class="LC_nobreak"><label><input type="checkbox" name='.
2071: $item.'" value="'.$value.'"'.$checked.' /> '.$rolename.
2072: '</label></span></td>';
2073: if ($showsections) {
2074: $output .= '<td>'.
2075: &select_sections($item,$role,\@sections,$currsec{$role}).
2076: '</td>'.&Apache::loncommon::end_data_table_row();
2077: }
2078: $total ++;
2079: $count ++;
2080: }
2081: }
2082: if (!$showsections) {
2083: my $rem = $total%($numinrow);
2084: my $colsleft = $numinrow - $rem;
2085: if ($colsleft > 1 ) {
2086: $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.
2087: ' </td>';
2088: } elsif ($colsleft == 1) {
2089: $output .= '<td class="LC_left_item"> </td>';
2090: }
2091: $output .= '</tr>';
2092: }
2093: return $output;
2094: }
2095:
2096: sub print_classlists {
1.9 raeburn 2097: my ($position,$cdom,$settings,$itemtext,$rowtotal,$crstype) = @_;
1.1 raeburn 2098: my @ordered;
2099: if ($position eq 'top') {
2100: @ordered = ('default_enrollment_start_date',
2101: 'default_enrollment_end_date');
2102: } elsif ($position eq 'middle') {
2103: @ordered = ('nothideprivileged');
2104: } else {
2105: @ordered = ('student_classlist_view',
2106: 'student_opt_in','student_classlist_portfiles');
2107: }
1.9 raeburn 2108: my %lt;
2109:
2110: if ($crstype eq 'Community') {
2111: %lt = &Apache::lonlocal::texthash (
2112: disabled => 'No viewable membership list',
2113: section => "Membership of viewer's section",
2114: all => 'List of all members',
2115: );
2116: } else {
2117: %lt = &Apache::lonlocal::texthash (
2118: disabled => 'No viewable classlist',
2119: section => "Classlist of viewer's section",
2120: all => 'Classlist of all students',
2121: );
2122: }
2123:
1.1 raeburn 2124: my %items = (
2125: 'default_enrollment_start_date' => {
1.3 raeburn 2126: text => '<b>'.&mt($itemtext->{'default_enrollment_start_date'}).'</b>',
1.1 raeburn 2127: input => 'dates',
2128: },
2129: 'default_enrollment_end_date' => {
1.3 raeburn 2130: text => '<b>'.&mt($itemtext->{'default_enrollment_end_date'}).'</b>',
1.1 raeburn 2131: input => 'dates',
2132: },
2133:
2134: 'nothideprivileged' => {
1.3 raeburn 2135: text => '<b>'.&mt($itemtext->{'nothideprivileged'}).'</b>',
1.1 raeburn 2136: input => 'checkbox',
2137: },
2138:
2139: 'student_classlist_view' => {
1.3 raeburn 2140: text => '<b>'.&mt($itemtext->{'student_classlist_view'}).'</b>',
1.1 raeburn 2141: input => 'selectbox',
1.9 raeburn 2142: options => \%lt,
1.1 raeburn 2143: order => ['disabled','all','section'],
2144: },
2145: 'student_opt_in' => {
1.3 raeburn 2146: text => '<b>'.&mt($itemtext->{'student_opt_in'}).'</b>',
1.1 raeburn 2147: input => 'radio',
2148: },
2149:
2150: 'student_classlist_portfiles' => {
1.3 raeburn 2151: text => '<b>'.&mt($itemtext->{'student_classlist_portfiles'}).'</b>',
1.1 raeburn 2152: input => 'radio',
2153: },
2154: );
2155: unless (($settings->{'student_classlist_view'} eq 'all') ||
2156: ($settings->{'student_classlist_view'} eq 'section')) {
2157: $settings->{'student_classlist_view'} = 'disabled';
2158: }
1.9 raeburn 2159: return &make_item_rows($cdom,\%items,\@ordered,$settings,$rowtotal,$crstype);
1.1 raeburn 2160: }
2161:
2162: sub print_appearance {
1.9 raeburn 2163: my ($cdom,$settings,$ordered,$itemtext,$rowtotal,$crstype) = @_;
1.3 raeburn 2164: unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
1.1 raeburn 2165: return;
2166: }
1.9 raeburn 2167: my $mathdef;
2168: if ($crstype eq 'Community') {
2169: $mathdef = &mt("None specified - use member's choice");
2170: } else {
2171: $mathdef = &mt("None specified - use student's choice");
2172: }
1.1 raeburn 2173: my %items = (
2174: 'default_xml_style' => {
1.3 raeburn 2175: text => '<b>'.&mt($itemtext->{'default_xml_style'}).'</b> '.
1.1 raeburn 2176: '<a href="javascript:openbrowser'.
2177: "('display','default_xml_style'".
2178: ",'sty')".'">'.&mt('Select Style File').'</a>',
2179: input => 'textbox',
2180: size => 35,
2181: },
2182:
2183: 'pageseparators' => {
1.3 raeburn 2184: text => '<b>'.&mt($itemtext->{'pageseparators'}).'</b>',
1.1 raeburn 2185: input => 'radio',
2186: },
2187: 'disable_receipt_display' => {
1.3 raeburn 2188: text => '<b>'.&mt($itemtext->{'disable_receipt_display'}).'</b>',
1.1 raeburn 2189: input => 'radio',
2190: },
2191: 'texengine' => {
1.3 raeburn 2192: text => '<b>'.&mt($itemtext->{'texengine'}).'</b>',
1.1 raeburn 2193: input => 'selectbox',
2194: options => {
2195: jsMath => 'jsMath',
2196: mimetex => &mt('Convert to Images'),
2197: tth => &mt('TeX to HTML'),
2198: },
2199: order => ['jsMath','mimetex','tth'],
1.9 raeburn 2200: nullval => $mathdef,
1.1 raeburn 2201: },
2202: 'tthoptions' => {
1.3 raeburn 2203: text => '<b>'.&mt($itemtext->{'tthoptions'}).'</b>',
1.1 raeburn 2204: input => 'textbox',
2205: size => 40,
2206: },
2207: );
1.9 raeburn 2208: return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype);
1.1 raeburn 2209: }
2210:
2211: sub print_grading {
1.9 raeburn 2212: my ($cdom,$settings,$ordered,$itemtext,$rowtotal,$crstype) = @_;
1.3 raeburn 2213: unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
1.1 raeburn 2214: return;
2215: }
2216: my %items = (
2217: 'grading' => {
1.3 raeburn 2218: text => '<b>'.&mt($itemtext->{'grading'}).'</b>'.
1.1 raeburn 2219: &Apache::loncommon::help_open_topic('GradingOptions'),
2220: input => 'selectbox',
2221: options => {
2222: standard => &mt('Standard: shows points'),
1.11 www 2223: external => &mt('External: shows number of completed parts and totals'),
2224: externalnototals => &mt('External: shows only number of completed parts'),
1.1 raeburn 2225: spreadsheet => &mt('Spreadsheet: (with link to detailed scores)'),
2226: },
1.11 www 2227: order => ['standard','external','externalnototals','spreadsheet'],
1.1 raeburn 2228: },
2229: 'rndseed' => {
1.3 raeburn 2230: text => '<b>'.&mt($itemtext->{'rndseed'}).'</b>'.
1.17 faziophi 2231: '<span class="LC_warning">'.'<br />'.
1.1 raeburn 2232: &mt('Modifying this will make problems have different numbers and answers!').
2233: '</span>',
2234: input => 'selectbox',
2235: options => {
2236: '32bit' => '32bit',
2237: '64bit' => '64bit',
2238: '64bit2' => '64bit2',
2239: '64bit3' => '64bit3',
2240: '64bit4' => '64bit4',
2241: '64bit5' => '64bit5',
2242: },
2243: order => ['32bit','64bit','64bit2','64bit3','64bit4','64bit5'],
2244: },
2245: 'receiptalg' => {
1.3 raeburn 2246: text => '<b>'.&mt($itemtext->{'receiptalg'}).'</b><br />'.
1.5 raeburn 2247: &mt('This controls how receipt numbers are generated'),
1.1 raeburn 2248: input => 'selectbox',
2249: options => {
2250: receipt => 'receipt',
2251: receipt2 => 'receipt2',
2252: receipt3 => 'receipt3',
2253: },
2254: order => ['receipt','receipt2','receipt3'],
2255: },
2256: 'disablesigfigs' => {
1.3 raeburn 2257: text => '<b>'.&mt($itemtext->{'disablesigfigs'}).'</b>',
1.1 raeburn 2258: input => 'radio',
2259: },
2260: );
1.9 raeburn 2261: return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype);
1.1 raeburn 2262: }
2263:
2264: sub print_printouts {
1.9 raeburn 2265: my ($cdom,$settings,$ordered,$itemtext,$rowtotal,$crstype) = @_;
1.3 raeburn 2266: unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
1.1 raeburn 2267: return;
2268: }
2269: my %items = (
2270: problem_stream_switch => {
1.3 raeburn 2271: text => '<b>'.&mt($itemtext->{'problem_stream_switch'}).'</b>',
1.1 raeburn 2272: input => 'radio',
2273: },
2274: suppress_tries => {
1.3 raeburn 2275: text => '<b>'.&mt($itemtext->{'suppress_tries'}).'</b>',
1.1 raeburn 2276: input => 'radio',
2277: },
2278: default_paper_size => {
1.3 raeburn 2279: text => '<b>'.&mt($itemtext->{'default_paper_size'}).'</b>',
1.1 raeburn 2280: input => 'selectbox',
2281: options => {
2282: Letter => &mt('Letter').' [8 1/2x11 in]',
2283: Legal => &mt('Legal').' [8 1/2x14 in]',
2284: Tabloid => &mt('Tabloid').' [11x17 in]',
2285: Executive => &mt('Executive').' [7 1/2x10 in]',
2286: A2 => &mt('A2').' [420x594 mm]',
2287: A3 => &mt('A3').' [297x420 mm]',
2288: A4 => &mt('A4').' [210x297 mm]',
2289: A5 => &mt('A5').' [148x210 mm]',
2290: A6 => &mt('A6').' [105x148 mm]',
2291: },
2292: order => ['Letter','Legal','Tabloid','Executive','A2','A3','A4','A5','A6'],
2293: nullval => 'None specified',
2294: },
2295: print_header_format => {
1.3 raeburn 2296: text => '<b>'.&mt($itemtext->{'print_header_format'}).'</b>',
1.1 raeburn 2297: input => 'checkbox',
2298: },
2299: disableexampointprint => {
1.3 raeburn 2300: text => '<b>'.&mt($itemtext->{'disableexampointprint'}).'</b>',
1.1 raeburn 2301: input => 'radio',
2302: },
1.14 raeburn 2303: canuse_pdfforms => {
2304: text => '<b>'.&mt($itemtext->{'canuse_pdfforms'}).'</b>',
2305: input => 'selectbox',
2306: options => {
2307: 1 => &mt('Yes'),
2308: 0 => &mt('No'),
2309: },
2310: order => ['1','0'],
2311: nullval => 'None specified - use domain default',
2312: }
1.1 raeburn 2313: );
1.9 raeburn 2314: return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype);
1.1 raeburn 2315: }
2316:
2317: sub print_spreadsheet {
1.9 raeburn 2318: my ($cdom,$settings,$ordered,$itemtext,$rowtotal,$crstype) = @_;
1.3 raeburn 2319: unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
1.1 raeburn 2320: return;
2321: }
2322: my $SelectSpreadsheetFile=&mt('Select Spreadsheet File');
2323: my %items = (
2324: spreadsheet_default_classcalc => {
1.3 raeburn 2325: text => '<b>'.&mt($itemtext->{'spreadsheet_default_classcalc'}).'</b> '.
1.1 raeburn 2326: '<span class="LC_nobreak"><a href="javascript:openbrowser'.
2327: "('display','spreadsheet_default_classcalc'".
2328: ",'spreadsheet')".'">'.$SelectSpreadsheetFile.'</a></span>',
2329: input => 'textbox',
2330: },
2331: spreadsheet_default_studentcalc => {
1.3 raeburn 2332: text => '<b>'.&mt($itemtext->{'spreadsheet_default_studentcalc'}).'</b> '.
1.1 raeburn 2333: '<span class="LC_nobreak"><a href="javascript:openbrowser'.
2334: "('display','spreadsheet_default_calc'".
2335: ",'spreadsheet')".'">'.$SelectSpreadsheetFile.'</a></span>',
2336: input => 'textbox',
2337: },
2338: spreadsheet_default_assesscalc => {
1.3 raeburn 2339: text => '<b>'.&mt($itemtext->{'spreadsheet_default_assesscalc'}).'</b> '.
1.1 raeburn 2340: '<span class="LC_nobreak"><a href="javascript:openbrowser'.
2341: "('display','spreadsheet_default_assesscalc'".
2342: ",'spreadsheet')".'">'.$SelectSpreadsheetFile.'</a></span>',
2343: input => 'textbox',
2344: },
2345: hideemptyrows => {
1.3 raeburn 2346: text => '<b>'.&mt($itemtext->{'hideemptyrows'}).'</b>',
1.1 raeburn 2347: input => 'radio',
2348: },
2349: );
1.9 raeburn 2350: return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype);
2351: }
1.1 raeburn 2352:
2353: sub print_bridgetasks {
1.9 raeburn 2354: my ($cdom,$settings,$ordered,$itemtext,$rowtotal,$crstype) = @_;
1.3 raeburn 2355: unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
1.1 raeburn 2356: return;
2357: }
1.9 raeburn 2358: my ($stumsg,$msgnote);
2359: if ($crstype eq 'Community') {
2360: $stumsg = &mt('Send message to member');
2361: $msgnote = &mt('Message to member and add to user notes');
2362: } else {
2363: $stumsg = &mt('Send message to student');
2364: $msgnote = &mt('Message to student and add to user notes');
2365: }
1.1 raeburn 2366: my %items = (
2367: task_messages => {
1.3 raeburn 2368: text => '<b>'.&mt($itemtext->{'task_messages'}).'</b>',
1.1 raeburn 2369: input => 'selectbox',
2370: options => {
1.9 raeburn 2371: only_student => $stumsg,
2372: student_and_user_notes_screen => $msgnote,
1.1 raeburn 2373: },
2374: order => ['only_student','student_and_user_notes_screen'],
2375: nullval => &mt('No message or record in user notes'),
2376: },
2377: task_grading => {
1.3 raeburn 2378: text => '<b>'.&mt($itemtext->{'task_grading'}).'</b>',
1.1 raeburn 2379: input => 'selectbox',
2380: options => {
2381: any => &mt('Grade BTs in any section'),
2382: section => &mt('Grade BTs only in own section')
2383: },
2384: order => ['any','section'],
2385: },
2386: suppress_embed_prompt => {
1.3 raeburn 2387: text => '<b>'.&mt($itemtext->{'suppress_embed_prompt'}).'</b><span class="LC_nobreak">'.
2388: ' '.&mt('(applies when current role is student)').'</span>',
1.1 raeburn 2389: input => 'radio',
2390: },
2391: );
1.9 raeburn 2392: return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype);
1.1 raeburn 2393: }
2394:
2395: sub print_other {
1.9 raeburn 2396: my ($cdom,$settings,$allitems,$rowtotal,$crstype) = @_;
1.1 raeburn 2397: unless ((ref($settings) eq 'HASH') && (ref($allitems) eq 'ARRAY')) {
2398: return;
2399: }
1.3 raeburn 2400: my @ordered = &get_other_items($cdom,$settings,$allitems);
2401: my %items;
2402: foreach my $parameter (@ordered) {
2403: $items{$parameter} = {
2404: text => '<b>'.$parameter.'</b>',
2405: input => 'textbox',
2406: size => '15',
2407: },
2408: }
2409: push (@ordered,'newp_value');
2410: $items{'newp_value'} = {
2411: text => '<b>'.&mt('Create New Environment Variable').'</b><br />'.
2412: '<input type="textbox" name="newp_name"'.
2413: ' value="" size="30" />',
2414: input => 'textbox',
2415: size => '30',
2416: };
1.9 raeburn 2417: my $output = &make_item_rows($cdom,\%items,\@ordered,$settings,$rowtotal,$crstype);
1.3 raeburn 2418: }
2419:
2420: sub get_other_items {
2421: my ($cdom,$settings,$allitems) = @_;
2422: unless ((ref($settings) eq 'HASH') && (ref($allitems) eq 'ARRAY')) {
2423: return;
2424: }
1.1 raeburn 2425: my @ordered;
2426: if (ref($settings) eq 'HASH') {
2427: foreach my $parameter (sort(keys(%{$settings}))) {
2428: next if (grep/^\Q$parameter\E$/,@{$allitems});
1.3 raeburn 2429: next if (($parameter eq 'course.helper.not.run') &&
2430: (!exists($env{'user.role.dc./'.$env{'request.role.domain'}.'/'})));
1.1 raeburn 2431: unless (($parameter =~ m/^internal\./)||($parameter =~ m/^metadata\./) ||
2432: ($parameter =~ m/^selfenroll_/) || ($parameter =~ /_selfenroll$/)
2433: || ($parameter eq 'type') ||
1.9 raeburn 2434: ($parameter =~ m/^(cc|co|in|ta|ep|ad|st)\.plaintext$/)) {
1.1 raeburn 2435: push(@ordered,$parameter);
2436: }
2437: }
2438: }
1.3 raeburn 2439: return @ordered;
1.1 raeburn 2440: }
2441:
2442: sub item_table_row_start {
1.19 faziophi 2443: my ($text,$count,$add_class) = @_;
1.1 raeburn 2444: my $output;
1.19 faziophi 2445: my $css_class = ($count % 2) ? 'LC_odd_row' : 'LC_even_row';
2446: $css_class = (join(' ',$css_class,$add_class)) unless ($add_class eq '');
2447: $output .= '<tr class="'.$css_class.'">'."\n";;
1.1 raeburn 2448: $output .= '<td class="LC_left_item">'.$text.
1.19 faziophi 2449: '</td><td class="LC_right_item">';
1.1 raeburn 2450: return $output;
2451: }
2452:
2453: sub item_table_row_end {
2454: return '</td></tr>';
2455: }
2456:
2457: sub yesno_radio {
2458: my ($item,$settings) = @_;
2459: my $itemon = ' ';
2460: my $itemoff = ' checked="checked" ';
2461: if (ref($settings) eq 'HASH') {
2462: if ($settings->{$item} eq 'yes') {
2463: $itemon = $itemoff;
2464: $itemoff = ' ';
2465: }
2466: }
2467: return '<span class="LC_nobreak"><label>'.
2468: '<input type="radio" name="'.$item.'"'.
2469: $itemon.' value="yes" />'.&mt('Yes').'</label> '.
2470: '<label><input type="radio" name="'.$item.'"'.
2471: $itemoff.' value="" />'.&mt('No').'</label></span>';
2472: }
2473:
2474: sub select_from_options {
2475: my ($item,$order,$options,$curr,$nullval,$multiple,$maxsize,$onchange) = @_;
2476: my $output;
2477: if ((ref($order) eq 'ARRAY') && (ref($options) eq 'HASH')) {
2478: $output='<select name="'.$item.'" '.$onchange;
2479: if ($multiple) {
2480: $output .= ' multiple="multiple"';
2481: my $num = @{$order};
2482: $num ++ if ($nullval ne '');
2483: if (($maxsize) && ($maxsize < $num)) {
2484: $output .= ' size="'.$maxsize.'"';
2485: }
2486: }
2487: $output .= '>'."\n";
2488: if ($nullval ne '') {
2489: $output .= '<option value=""';
2490: if (ref($curr) eq 'ARRAY') {
2491: if ((@{$curr} == 0) || (grep(/^$/,@{$curr}))) {
2492: $output .= ' selected="selected" ';
2493: }
2494: } else {
2495: if ($curr eq '') {
2496: $output .= ' selected="selected" ';
2497: }
2498: }
2499: $output .= '>'.$nullval.'</option>';
2500: }
2501: foreach my $option (@{$order}) {
2502: $output.= '<option value="'.$option.'"';
2503: if (ref($curr) eq 'ARRAY') {
2504: if (grep(/^\Q$option\E$/,@{$curr})) {
2505: $output .= ' selected="selected" ';
2506: }
2507: } else {
2508: if ($option eq $curr) {
2509: $output.=' selected="selected"';
2510: }
2511: }
2512: $output.=">$options->{$option}</option>\n";
2513: }
2514: $output.="</select>";
2515: }
2516: return $output;
2517: }
2518:
2519: sub make_item_rows {
1.9 raeburn 2520: my ($cdom,$items,$ordered,$settings,$rowtotal,$crstype) = @_;
1.1 raeburn 2521: my $datatable;
2522: if ((ref($items) eq 'HASH') && (ref($ordered) eq 'ARRAY')) {
2523: my $count = 0;
2524: foreach my $item (@{$ordered}) {
2525: $count ++;
2526: $datatable .= &item_table_row_start($items->{$item}{text},$count);
2527: if ($item eq 'nothideprivileged') {
1.9 raeburn 2528: $datatable .= ¬hidepriv_row($cdom,$item,$settings,$crstype);
1.1 raeburn 2529: } elsif ($item eq 'print_header_format') {
2530: $datatable .= &print_hdrfmt_row($item,$settings);
2531: } elsif ($items->{$item}{input} eq 'dates') {
2532: $datatable .=
2533: &Apache::lonhtmlcommon::date_setter('display',$item,
2534: $settings->{$item});
2535: } elsif ($items->{$item}{input} eq 'radio') {
2536: $datatable .= &yesno_radio($item,$settings);
2537: } elsif ($items->{$item}{input} eq 'selectbox') {
2538: my $curr = $settings->{$item};
2539: $datatable .=
2540: &select_from_options($item,$items->{$item}{'order'},
2541: $items->{$item}{'options'},$curr,
2542: $items->{$item}{'nullval'});
2543: } elsif ($items->{$item}{input} eq 'textbox') {
2544: $datatable .=
2545: &Apache::lonhtmlcommon::textbox($item,$settings->{$item},
2546: $items->{$item}{size});
2547: }
2548: $datatable .= &item_table_row_end();
2549: }
2550: if (ref($rowtotal)) {
2551: $$rowtotal += scalar(@{$ordered});
2552: }
2553: }
2554: return $datatable;
2555: }
2556:
2557: sub nothidepriv_row {
1.9 raeburn 2558: my ($cdom,$item,$settings,$crstype) = @_;
1.1 raeburn 2559: my ($cnum) = &get_course();
2560: my %nothide;
2561: my $datatable;
2562: if (ref($settings) eq 'HASH') {
2563: if ($settings->{$item} ne '') {
2564: foreach my $user (split(/\s*\,\s*/,$settings->{$item})) {
2565: if ($user !~ /:/) {
2566: $nothide{join(':',split(/[\@]/,$user))}=1;
2567: } else {
2568: $nothide{$user} = 1;
2569: }
2570: }
2571: }
2572: }
2573: my %coursepersonnel = &Apache::lonnet::dump('nohist_userroles',$cdom,$cnum);
2574: my $now = time;
2575: my @privusers;
1.3 raeburn 2576: my %privileged;
1.1 raeburn 2577: foreach my $person (keys(%coursepersonnel)) {
2578: my ($role,$user,$usec) = ($person =~ /^([^:]*):([^:]+:[^:]+):([^:]*)/);
2579: $user =~ s/:$//;
2580: my ($end,$start) = split(/:/,$coursepersonnel{$person});
2581: if ($end == -1 || $start == -1) {
2582: next;
2583: }
2584: my ($uname,$udom) = split(':',$user);
1.3 raeburn 2585: unless (ref($privileged{$udom}) eq 'HASH') {
2586: my %dompersonnel = &Apache::lonnet::get_domain_roles($udom,['dc'],undef,$now);
2587: $privileged{$udom} = {};
2588: if (keys(%dompersonnel)) {
2589: foreach my $server (keys(%dompersonnel)) {
2590: foreach my $user (sort(keys(%{$dompersonnel{$server}}))) {
2591: my ($trole,$uname,$udom) = split(/:/,$user);
2592: $privileged{$udom}{$uname} = $trole;
2593: }
2594: }
2595: }
2596: }
2597: if (exists($privileged{$udom}{$uname})) {
1.7 raeburn 2598: unless (grep(/^\Q$user\E$/,@privusers)) {
2599: push(@privusers,$user);
2600: }
1.1 raeburn 2601: }
2602: }
2603: if (@privusers) {
2604: $datatable .= '<table align="right">';
2605: foreach my $user (sort(@privusers)) {
2606: my $hideon = ' checked="checked" ';
2607: my $hideoff = '';
2608: if ($nothide{$user}) {
2609: $hideoff = $hideon;
2610: $hideon = '';
2611: }
2612: my ($uname,$udom) = split(':',$user);
2613: $datatable .= '<tr><td align="left">'.
2614: &Apache::loncommon::aboutmewrapper(
2615: &Apache::loncommon::plainname($uname,$udom,'firstname'),
2616: $uname,$udom,'aboutuser').
2617: '</td><td align="left">'.
2618: '<span class="LC_nobreak"><label>'.
2619: '<input type="radio" name="'.$item.'_'.$user.'"'.
1.7 raeburn 2620: $hideon.' value="" />'.&mt('Hidden').'</label> '.
2621: '<label><input type="radio" name="'.$item.'_'.$user.'"'. $hideoff.' value="yes" />'.&mt('Shown').'</label></span></td>'.
1.1 raeburn 2622: '</tr>';
2623: }
2624: $datatable .= '</table>';
2625: } else {
1.9 raeburn 2626: if ($crstype eq 'Community') {
2627: $datatable .= &mt('No Domain Coordinators have community roles');
2628: } else {
2629: $datatable .= &mt('No Domain Coordinators have course roles');
2630: }
1.1 raeburn 2631: }
2632: return $datatable;
2633: }
2634:
2635: sub print_hdrfmt_row {
2636: my ($item,$settings) = @_;
2637: my @curr;
2638: my $currnum = 0;
2639: my $maxnum = 2;
2640: my $currstr;
2641: if ($settings->{$item} ne '') {
2642: $currstr .= '<b>'.&mt('Current print header:').' <span class="LC_warning"><tt>'.
2643: $settings->{$item}.'</tt></span></b><br />';
2644: my @current = split(/(%\d*[nca])/,$settings->{$item});
2645: foreach my $item (@current) {
2646: unless ($item eq '') {
2647: push(@curr,$item);
2648: }
2649: }
2650: $currnum = @curr;
2651: $maxnum += $currnum;
2652: }
2653:
2654: my $output = <<ENDJS;
2655:
2656: <script type="text/javascript" language="Javascript">
2657:
2658: function reOrder(chgnum) {
2659: var maxnum = $maxnum;
2660: var oldidx = 'printfmthdr_oldpos_'+chgnum;
2661: var newidx = 'printfmthdr_pos_'+chgnum;
2662: oldidx = getIndexByName(oldidx);
2663: newidx = getIndexByName(newidx);
2664: var oldpos = document.display.elements[oldidx].value;
2665: var newpos = document.display.elements[newidx].options[document.display.elements[newidx].selectedIndex].value;
2666: document.display.elements[oldidx].value = newpos;
2667: var chgtype = 'up';
2668: if (newpos < oldpos) {
2669: chgtype = 'down';
2670: }
2671: for (var j=0; j<maxnum; j++) {
2672: if (j != chgnum) {
2673: oldidx = 'printfmthdr_oldpos_'+j;
2674: newidx = 'printfmthdr_pos_'+j;
2675: oldidx = getIndexByName(oldidx);
2676: newidx = getIndexByName(newidx);
2677: var currpos = document.display.elements[newidx].options[document.display.elements[newidx].selectedIndex].value;
2678: var currsel = document.display.elements[newidx].selectedIndex;
2679: if (chgtype == 'up') {
2680: if ((currpos > oldpos) && (currpos <= newpos)) {
2681: document.display.elements[newidx].selectedIndex = currsel-1;
2682: document.display.elements[oldidx].value = document.display.elements[newidx].options[document.display.elements[newidx].selectedIndex].value;
2683: }
2684: } else {
2685: if ((currpos >= newpos) && (currpos < oldpos)) {
2686: document.display.elements[newidx].selectedIndex = currsel+1;
2687: document.display.elements[oldidx].value = document.display.elements[newidx].options[document.display.elements[newidx].selectedIndex].value;
2688: }
2689: }
2690: }
2691: }
2692: return;
2693: }
2694:
2695: function getIndexByName(item) {
2696: for (var i=0;i<document.display.elements.length;i++) {
2697: if (document.display.elements[i].name == item) {
2698: return i;
2699: }
2700: }
2701: return -1;
2702: }
2703:
2704: </script>
2705:
2706: ENDJS
1.10 raeburn 2707: $output .= $currstr.'<table class="LC_nested_outer">';
1.1 raeburn 2708: if (@curr > 0) {
2709: for (my $i=0; $i<@curr; $i++) {
2710: my $pos = $i+1;
1.10 raeburn 2711: $output .= '<tr>'.
1.1 raeburn 2712: '<td align="left"><span class="LC_nobreak">'.
2713: &position_selector($pos,$i,$maxnum).&mt('Delete:').
2714: '<input type="checkbox" name="printfmthdr_del_'.$i.
2715: '" /></span></td>';
2716: if ($curr[$i] =~ /^%\d*[nca]$/) {
2717: my ($limit,$subst) = ($curr[$i] =~ /^%(\d*)([nca])$/);
2718: $output .= '<td align="left">'.
2719: &substitution_selector($i,$subst,$limit).'</td>';
2720: } else {
2721: $output .= '<td colspan="2" align="left">'.&mt('Text').'<br />'.
2722: '<input type="textbox" name="printfmthdr_text_'.$i.'"'.
2723: ' value="'.$curr[$i].'" size="25" /></td>';
2724: }
1.10 raeburn 2725: $output .= '</tr>';
1.1 raeburn 2726: }
2727: }
2728: my $pos = $currnum+1;
1.10 raeburn 2729: $output .= '<tr>'.
1.1 raeburn 2730: '<td align="left"><span class="LC_nobreak">'.
2731: &position_selector($pos,$currnum,$maxnum).
2732: '<b>'.&mt('New').'</b></span></td><td align="left">'.
2733: &substitution_selector($currnum).'</td>'.
1.10 raeburn 2734: '</tr>';
1.1 raeburn 2735: $pos ++;
2736: $currnum ++;
1.10 raeburn 2737: $output .= '<tr>'.
1.1 raeburn 2738: '<td align="left"><span class="LC_nobreak">'.
2739: &position_selector($pos,$currnum,$maxnum).
2740: '<b>'.&mt('New').'</b></span></td>'.
2741: '<td colspan="2" align="left">'.&mt('Text').'<br />'.
2742: '<input type="textbox" name="printfmthdr_text_'.$currnum.
1.3 raeburn 2743: '" value="" size ="25" />'.
2744: '<input type="hidden" name="printfmthdr_maxnum" value="'.
2745: $maxnum.'" /></td>'.
1.10 raeburn 2746: '</tr>'.
2747: '</table>';
1.1 raeburn 2748: return $output;
2749: }
2750:
2751: sub position_selector {
2752: my ($pos,$num,$maxnum) = @_;
2753: my $output = '<select name="printfmthdr_pos_'.$num.'" onchange="reOrder('."'$num'".');">';
2754: for (my $j=1; $j<=$maxnum; $j++) {
2755: my $sel = '';
2756: if ($pos == $j) {
2757: $sel = ' selected="selected"';
2758: }
2759: $output .= '<option value="'.$j.'"'.$sel.'">'.$j.'</option>';
2760: }
2761: $output .= '</select><input type="hidden" name="printfmthdr_oldpos_'.$num.
2762: '" value="'.$pos.'" />';
2763: return $output;
2764: }
2765:
2766: sub substitution_selector {
1.9 raeburn 2767: my ($num,$subst,$limit,$crstype) = @_;
2768: my ($stunametxt,$crsidtxt);
2769: if ($crstype eq 'Community') {
2770: $stunametxt = 'member name';
2771: $crsidtxt = 'community ID',
2772: } else {
2773: $stunametxt = 'student name';
2774: $crsidtxt = 'course ID',
2775: }
1.1 raeburn 2776: my %lt = &Apache::lonlocal::texthash(
1.9 raeburn 2777: n => $stunametxt,
2778: c => $crsidtxt,
1.1 raeburn 2779: a => 'assignment note',
2780: );
2781: my $output .= &mt('Substitution').'<br />'.
2782: '<select name=""printfmthdr_sub__'.$num.'">';
2783: if ($subst eq '') {
2784: $output .= '<option value="" selected="selected"> </option>';
2785: }
2786: foreach my $field ('n','c','a') {
2787: my $sel ='';
2788: if ($subst eq $field) {
2789: $sel = ' selected="selected"';
2790: }
2791: $output .= '<option value="'.$field.'"'.$sel.'>'.
2792: $lt{$field}.'</option>';
2793: }
2794: $output .= '</select></td><td align="left">'.&mt('Size limit').'<br />'.
2795: '<input type="textbox" name="printfmthdr_limit_'.$num.
2796: '" value="'.$limit.'" size="5" /></span>';
2797: return $output;
2798: }
2799:
2800: 1;
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>