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