Diff for /loncom/interface/lonparmset.pm between versions 1.615 and 1.622

version 1.615, 2022/07/03 04:31:07 version 1.622, 2025/06/28 14:34:46
Line 329  use Apache::lonnavmaps; Line 329  use Apache::lonnavmaps;
 use Apache::longroup;  use Apache::longroup;
 use Apache::lonrss;  use Apache::lonrss;
 use HTML::Entities;  use HTML::Entities;
   use Text::Wrap();
 use LONCAPA qw(:DEFAULT :match);  use LONCAPA qw(:DEFAULT :match);
   
   
Line 991  sub valout { Line 992  sub valout {
             $result=' ';              $result=' ';
         }          }
     } else {      } else {
         if ($type eq 'date_interval') {          if (($type eq 'date_interval') || ($type eq 'string_grace')) {
             my ($totalsecs,$donesuffix) = split(/_/,$value,2);              if ($type eq 'string_grace') {
             my ($usesdone,$donebuttontext,$proctor,$secretkey);                  my @items;
             if ($donesuffix =~ /^done\:([^\:]+)\:(.*)$/) {                  if ($value =~ /,/) {
                 $donebuttontext = $1;                      @items = split(/,/,$value);
                 (undef,$proctor,$secretkey) = split(/_/,$2);  
                 $usesdone = 'done';  
             } elsif ($donesuffix =~ /^done(|_.+)$/) {  
                 $donebuttontext = &mt('Done');  
                 ($usesdone,$proctor,$secretkey) = split(/_/,$donesuffix);  
             }  
             my ($sec,$min,$hour,$mday,$mon,$year)=gmtime($totalsecs);  
             my @timer;  
             $year=$year-70;  
             $mday--;  
             if ($year) {  
 #               $result.=&mt('[quant,_1,yr]',$year).' ';  
                 push(@timer,&mt('[quant,_1,yr]',$year));  
             }  
             if ($mon) {  
 #               $result.=&mt('[quant,_1,mth]',$mon).' ';  
                 push(@timer,&mt('[quant,_1,mth]',$mon));  
             }  
             if ($mday) {  
 #               $result.=&mt('[quant,_1,day]',$mday).' ';  
                 push(@timer,&mt('[quant,_1,day]',$mday));  
             }  
             if ($hour) {  
 #               $result.=&mt('[quant,_1,hr]',$hour).' ';  
                 push(@timer,&mt('[quant,_1,hr]',$hour));  
             }  
             if ($min) {  
 #               $result.=&mt('[quant,_1,min]',$min).' ';  
                 push(@timer,&mt('[quant,_1,min]',$min));  
             }  
             if ($sec) {  
 #               $result.=&mt('[quant,_1,sec]',$sec).' ';  
                 push(@timer,&mt('[quant,_1,sec]',$sec));  
             }  
 #           $result=~s/\s+$//;  
             if (!@timer) { # Special case: all entries 0 -> display "0 secs" intead of empty field to keep this field editable  
                 push(@timer,&mt('[quant,_1,sec]',0));  
             }  
             $result.=join(", ",@timer);  
             if ($usesdone eq 'done') {  
                 if ($secretkey) {  
                     $result .= ' '.&mt('+ "[_1]" with proctor key: [_2]',$donebuttontext,$secretkey);    
                 } else {                  } else {
                     $result .= ' + "'.$donebuttontext.'"';                      @items = ($value);
                   }
                   foreach my $item (@items) {
                       if ($item =~ /^\d+:(0|1)\.?\d*:(0|1)$/) {
                           my ($totalsecs,$fraction,$grad) = split(/:/,$item);
                           $result .= &interval_to_humanstr($totalsecs);
                           if (($fraction >=0) && ($fraction <=1)) {
                               $result .= '&nbsp;|&nbsp;'.$fraction.'&nbsp;'.&mt('pts');
                               if ($grad == 1) {
                                   $result .= '&nbsp;('.&mt('gradual').')';
                               }
                           }
                           $result .= ', ';
                       }
                   }
                   $result =~ s/, $//;
               } else {
                   my ($totalsecs,$donesuffix) = split(/_/,$value,2);
                   $result = &interval_to_humanstr($totalsecs);
                   my ($usesdone,$donebuttontext,$proctor,$secretkey);
                   if ($donesuffix =~ /^done\:([^\:]+)\:(.*)$/) {
                       $donebuttontext = $1;
                       (undef,$proctor,$secretkey) = split(/_/,$2);
                       $usesdone = 'done';
                   } elsif ($donesuffix =~ /^done(|_.+)$/) {
                       $donebuttontext = &mt('Done');
                       ($usesdone,$proctor,$secretkey) = split(/_/,$donesuffix);
                   }
                   if ($usesdone eq 'done') {
                       if ($secretkey) {
                           $result .= ' '.&mt('+ "[_1]" with proctor key: [_2]',$donebuttontext,$secretkey);
                       } else {
                           $result .= ' + "'.$donebuttontext.'"';
                       }
                 }                  }
             }              }
         } elsif (&isdateparm($type)) {          } elsif (&isdateparm($type)) {
Line 1054  sub valout { Line 1046  sub valout {
     return $result;      return $result;
 }  }
   
   sub interval_to_humanstr {
       my ($totalsecs) = @_;
       my ($sec,$min,$hour,$mday,$mon,$year)=gmtime($totalsecs);
       my @timer;
       $year=$year-70;
       $mday--;
       if ($year) {
           push(@timer,&mt('[quant,_1,yr]',$year));
       }
       if ($mon) {
           push(@timer,&mt('[quant,_1,mth]',$mon));
       }
       if ($mday) {
           push(@timer,&mt('[quant,_1,day]',$mday));
       }
       if ($hour) {
           push(@timer,&mt('[quant,_1,hr]',$hour));
       }
       if ($min) {
           push(@timer,&mt('[quant,_1,min]',$min));
       }
       if ($sec) {
           push(@timer,&mt('[quant,_1,sec]',$sec));
       }
       if (!@timer) { # Special case: all entries 0 -> display "0 secs" intead of empty field to keep this field editable
           push(@timer,&mt('[quant,_1,sec]',0));
       }
       return '<span style="white-space:nowrap">'.join('</span>, <span style="white-space:nowrap">',@timer).'</span>';
   }
   
 # Returns HTML containing a link on a parameter value, for table mode.  # Returns HTML containing a link on a parameter value, for table mode.
 # The link uses the javascript function 'pjump'.  # The link uses the javascript function 'pjump'.
Line 1244  function validateParms() { Line 1265  function validateParms() {
     var ipRegExp = /^setip/;      var ipRegExp = /^setip/;
     var ipallowRegExp = /^setipallow_/;      var ipallowRegExp = /^setipallow_/;
     var ipdenyRegExp = /^setipdeny_/;       var ipdenyRegExp = /^setipdeny_/; 
       var graceRegExp = /^setgrace_/;
     var deeplinkRegExp = /^deeplink_/;      var deeplinkRegExp = /^deeplink_/;
     var dlListScopeRegExp = /^deeplink_(state|others|listing|scope)_/;       var dlListScopeRegExp = /^deeplink_(state|others|listing|scope)_/; 
     var dlLinkProtectRegExp = /^deeplink_protect_/;      var dlLinkProtectRegExp = /^deeplink_protect_/;
Line 1253  function validateParms() { Line 1275  function validateParms() {
     var dlMenusRegExp = /^deeplink_menus_/;      var dlMenusRegExp = /^deeplink_menus_/;
     var dlCollsRegExp = /^deeplink_colls_/;      var dlCollsRegExp = /^deeplink_colls_/;
     var dlTargetRegExp = /^deeplink_target_/;      var dlTargetRegExp = /^deeplink_target_/;
       var dlExitRegExp = /^deeplink_exit_/;
       var dlExitTextRegExp = /^deeplink_exittext_/;
     var patternIP = /[\[\]\*\.a-zA-Z\d\-]+/;      var patternIP = /[\[\]\*\.a-zA-Z\d\-]+/;
     if ((document.parmform.elements.length != 'undefined')  && (document.parmform.elements.length) != 'null') {      var numelements = document.parmform.elements.length;
         if (document.parmform.elements.length) {      if ((typeof(numelements) != 'undefined') && (numelements != null)) {
             for (i=0; i<document.parmform.elements.length; i++) {          if (numelements) {
               for (i=0; i<numelements; i++) {
                 var name=document.parmform.elements[i].name;                  var name=document.parmform.elements[i].name;
                 if (textRegExp.test(name)) {                  if (textRegExp.test(name)) {
                     var identifier = name.replace(textRegExp,'');                      var identifier = name.replace(textRegExp,'');
Line 1411  function validateParms() { Line 1436  function validateParms() {
                         var identifier =  name.replace(dlTargetRegExp,'');                          var identifier =  name.replace(dlTargetRegExp,'');
                         var idx = document.parmform.elements[i].selectedIndex;                          var idx = document.parmform.elements[i].selectedIndex;
                         if (idx > 0) {                          if (idx > 0) {
                             var possdeeplink = document.parmform.elements[i].options[idx].value                              var linktarget = document.parmform.elements[i].options[idx].value
                             possdeeplink = possdeeplink.replace(/^\s+|\s+$/g,'');                              linktarget = linktarget.replace(/^\s+|\s+$/g,'');
                             if (document.parmform.elements['set_'+identifier].value) {                              if (document.parmform.elements['set_'+identifier].value) {
                                 possdeeplink = ','+possdeeplink;                                  linktarget = ','+linktarget;
                               }
                               document.parmform.elements['set_'+identifier].value += linktarget;
                           }
                       } else if (dlExitRegExp.test(name)) {
                           if (document.parmform.elements[i].checked) {
                               var identifier =  name.replace(dlExitRegExp,'');
                               var posslinkexit = document.parmform.elements[i].value;
                               posslinkexit = posslinkexit.replace(/^\s+|\s+$/g,'');
                               if (document.parmform.elements['set_'+identifier].value) {
                                   posslinkexit = ','+posslinkexit;
                               }
                               document.parmform.elements['set_'+identifier].value += posslinkexit;
                           }
                       } else if (dlExitTextRegExp.test(name)) {
                           var identifier = name.replace(dlExitTextRegExp,'');
                           if ((isRadioSet('deeplink_exit_'+identifier,'yes')) ||
                               (isRadioSet('deeplink_exit_'+identifier,'url'))) {
                               var posstext = document.parmform.elements[i].value;
                               posstext = posstext.replace(/^\s+|\s+$/g,'');
                               var origlength = posstext.length;
                               posstext = posstext.replace(/[:;'",]/g,'');
                               var newlength = posstext.length;
                               if (newlength > 0) {
                                   var change = origlength - newlength;
                                   if (change) {
                                       alert(change+' disallowed character(s) removed from Exit Button text');
                                   }
                                   if (posstext !== 'Exit Tool') {
                                       posstext = ':'+posstext;
                                       document.parmform.elements['set_'+identifier].value += posstext;
                                   }
                               } else {
                                   document.parmform.elements['set_'+identifier].value = '';
                                   if (newlength < origlength) {
                                       alert("An exit link type of 'In use' was selected but the button text value was blank, after removing disallowed characters.\nDisallowed characters are ,\":;'");
                                   } else {
                                       alert("An exit link type of 'In use' was selected but the button text value was blank.\nPlease enter the text to use.");
                                   }
                                   return false;
                               }
                           }
                       }
                   } else if (graceRegExp.test(name)) {
                       var identifier = name.replace(graceRegExp,'');
                       var divElem = document.parmform.elements[i].closest('div'); 
                       var timeSels = divElem.getElementsByTagName("select");
                       var total = 0;
                       if (timeSels.length) {
                            for (var j=0; j<timeSels.length; j++) {
                               var sname = timeSels[j].getAttribute('name');
                               var poss = parseInt(timeSels[j].options[timeSels[j].selectedIndex].value);
                               if (sname == 'days_'+identifier) {
                                   if ((poss > 0) && (poss <= 31)) {
                                       total += (poss * 86400); 
                                   }
                               } else if (sname == 'hours_'+identifier) {
                                   if ((poss > 0) && (poss < 24)) {
                                       total += (poss * 3600);
                                   }
                               } else if (sname == 'minutes_'+identifier) {
                                   if ((poss > 0) && (poss < 60)) {
                                       total += (poss * 60);
                                   }
                               } else if (sname == 'seconds_'+identifier) {
                                   if ((poss > 0) && (poss < 60)) {
                                       total += poss;
                                   }
                             }                              }
                             document.parmform.elements['set_'+identifier].value += possdeeplink;  
                         }                          }
                     }                      }
                       var inputElems = divElem.getElementsByTagName("input");
                       var frac = '';
                       var grad = '';
                       if (inputElems.length) {
                           for (var j=0; j<inputElems.length; j++) {
                               var iname = inputElems[j].getAttribute('name');
                               if (iname == 'frac_'+identifier) {
                                   var ival = inputElems[j].value;
                                   ival.trim();
                                   var poss = parseFloat(ival);
                                   if ((typeof poss === 'number') && (!isNaN(poss))) {
                                       if ((poss => 0) && (poss <= 1)) {
                                           frac = poss;
                                       }
                                   }
                               } else if (iname == 'grad_'+identifier) {
                                   if (inputElems[j].checked) {
                                       grad = 1;
                                   } else {
                                       grad = 0;
                                   }
                               }
                           }
                       }
                       document.parmform.elements[i].value = total+':'+frac+':'+grad;
                       if (document.parmform.elements['set_'+identifier].value) {
                           document.parmform.elements['set_'+identifier].value += ',';
                       }
                       document.parmform.elements['set_'+identifier].value += document.parmform.elements[i].value;
                 }                  }
             }              }
         }          }
Line 1471  sub ipacc_boxes_js  { Line 1591  sub ipacc_boxes_js  {
 END  END
 }  }
   
   sub grace_js {
       my %lt = &grace_titles();
       &js_escape(\%lt);
       my $overdue = '<fieldset class="LC_grace"><legend>'.$lt{'sinc'}.'</legend>';
       foreach my $which (['days', 86400, 31],
                          ['hours', 3600, 23],
                          ['minutes', 60, 59],
                          ['seconds',  1, 59]) {
           my ($name, $factor, $max) = @{ $which };
           my %select = ((map {$_ => $_} (0..$max)),
                         'select_form_order' => [0..$max]);
           my $selector = &Apache::loncommon::select_form('',$name."_'+identifier+'",
                                                          \%select);
           $selector =~ s/([\r\n\f]+)//g;
           $overdue .= $selector.'&nbsp;'.$lt{$name}.('&nbsp;'x2).' ';
       }
       $overdue .= '</fieldset>';
       return <<"END";
   \$(document).ready(function() {
       var wrapper         = \$(".LC_string_grace_wrap");
       var add_button      = \$(".LC_add_grace_button");
       var graceRegExp     = /^LC_string_grace_/;
   
       \$(add_button).click(function(e){
           e.preventDefault();
           var identifier = \$(this).closest("div").attr("id");
           identifier = identifier.replace(graceRegExp,'');
           \$(this).closest('div').find('.LC_string_grace_inner').append('<div><input type="hidden" name="setgrace_'+identifier+'" value="" />$overdue<fieldset class="LC_grace"><legend>$lt{scor}</legend><input type="text" size="3" name="frac_'+identifier+'" value="" />&nbsp;&nbsp;<label><input type="checkbox" value="1" name="grad_'+identifier+'" />$lt{grad}</label></fieldset><a href="#" class="LC_remove_grace">$lt{remo}</a></div>');
       });
   
       \$(wrapper).delegate(".LC_remove_grace","click", function(e){
           e.preventDefault(); \$(this).closest("div").remove();
       })
   });
   
   
   END
   }
   
 # Javascript function toggleSecret, for overview mode.  # Javascript function toggleSecret, for overview mode.
 sub done_proctor_js {  sub done_proctor_js {
     my $defaultdone = &mt('Done');      my $defaultdone = &mt('Done');
Line 1562  function toggleDeepLink(form,item,key) { Line 1721  function toggleDeepLink(form,item,key) {
                             keybox.type = 'hidden';                              keybox.type = 'hidden';
                         }                          }
                     }                      }
                   } else if (item == 'exit') {
                       if (document.getElementById('deeplinkdiv_'+item+'_'+key)) {
                           if (radios[i].value == 'no') {
                               document.getElementById('deeplinkdiv_'+item+'_'+key).style.display = 'none';          
                               if (document.getElementById('deeplink_exittext_'+key)) {
                                   if (document.getElementById('deeplink_exittext_'+key).value != '') {
                                       document.getElementById('deeplink_exittext_'+key).value = '';    
                                   }
                               }
                           } else {
                               document.getElementById('deeplinkdiv_'+item+'_'+key).style.display = 'inline-block';
                               if (document.getElementById('deeplink_exittext_'+key)) {
                                   if (document.getElementById('deeplink_exittext_'+key).value == '') {
                                       document.getElementById('deeplink_exittext_'+key).value = 'Exit Tool';
                                   }
                               }
                           }
                       }
                 }                  }
             }              }
         }          }
Line 1690  sub print_row { Line 1867  sub print_row {
     if ($automatic) {      if ($automatic) {
         $parm.='<span class="LC_warning"><br />'.&mt('Automatically sets').' '.join(', ',split(/\:/,$automatic)).'</span>';          $parm.='<span class="LC_warning"><br />'.&mt('Automatically sets').' '.join(', ',split(/\:/,$automatic)).'</span>';
     }      }
       my $advice;
       if ((ref($name) eq 'HASH') && ($name->{$which} eq 'mapalias') &&
           (ref($symbp) eq 'HASH') && ($parmlev eq 'full')) {
           if ($symbp->{$rid} =~ m{^uploaded/}) {
               if ($result == 14) {
                   $advice = &mt('Use Course Editor to modify this.');
               } else {
                   $advice = &mt('Use Course Editor to set this.');
               }
           } else {
               if ($result == 14) {
                   $advice = &mt('Use Resource Assembly Tool to modify this.');
               } else {
                   $advice = &mt('Use Resource Assembly Tool to set this.');
               }
           }
           $parm .= '<br /><span class="LC_fontsize_small LC_cusr_emph">'.$advice.'</span>';
       }
     $r->print('<td>'.$parm.'</td>');      $r->print('<td>'.$parm.'</td>');
   
     my $thismarker=$which;      my $thismarker=$which;
Line 1771  sub print_row { Line 1966  sub print_row {
                 $extra = 'ltid_'.$domltistr;                  $extra = 'ltid_'.$domltistr;
             }              }
         }          }
         my %courselti = &Apache::lonnet::get_course_lti($cnum,$cdom);          my %courselti = &Apache::lonnet::get_course_lti($cnum,$cdom,'provider');
         if (keys(%courselti)) {          if (keys(%courselti)) {
             foreach my $item (sort { $a <=> $b } keys(%courselti)) {              foreach my $item (sort { $a <=> $b } keys(%courselti)) {
                 if (($item =~ /^\d+$/) && (ref($courselti{$item}) eq 'HASH')) {                  if (($item =~ /^\d+$/) && (ref($courselti{$item}) eq 'HASH')) {
Line 2363  sub lookUpTableParameter { Line 2558  sub lookUpTableParameter {
         'opendate' => 'time_settings',          'opendate' => 'time_settings',
         'duedate' => 'time_settings',          'duedate' => 'time_settings',
         'answerdate' => 'time_settings',          'answerdate' => 'time_settings',
           'grace' => 'time_settings',
         'interval' => 'time_settings',          'interval' => 'time_settings',
         'contentopen' => 'time_settings',          'contentopen' => 'time_settings',
         'contentclose' => 'time_settings',          'contentclose' => 'time_settings',
Line 2404  sub lookUpTableParameter { Line 2600  sub lookUpTableParameter {
         'lenient' => 'grading',          'lenient' => 'grading',
         'retrypartial' => 'tries',          'retrypartial' => 'tries',
         'discussvote'  => 'misc',          'discussvote'  => 'misc',
           'texdisplay' => 'misc',
         'examcode' => 'high_level_randomization',          'examcode' => 'high_level_randomization',
     );      );
 }  }
Line 2493  sub parmboxes { Line 2690  sub parmboxes {
         &whatIsMyCategory($tempparameter, \%categoryList);          &whatIsMyCategory($tempparameter, \%categoryList);
     }      }
     #part to print the parm-list      #part to print the parm-list
       $Text::Wrap::columns=60;
       $Text::Wrap::separator='<br />';
     foreach my $key (sort { $category_order{$a} <=> $category_order{$b} } keys(%categoryList)) {      foreach my $key (sort { $category_order{$a} <=> $category_order{$b} } keys(%categoryList)) {
         next if (@{$categoryList{$key}} == 0);          next if (@{$categoryList{$key}} == 0);
         next if ($key eq '');          next if ($key eq '');
Line 2506  sub parmboxes { Line 2705  sub parmboxes {
             if ($$pscat[0] eq "all" || grep $_ eq $tempkey, @{$pscat}) {              if ($$pscat[0] eq "all" || grep $_ eq $tempkey, @{$pscat}) {
                 $r->print( ' checked="checked"');                  $r->print( ' checked="checked"');
             }              }
             $r->print(' />'.($$allparms{$tempkey}=~/\S/ ? $$allparms{$tempkey}              $r->print(' />'.($$allparms{$tempkey}=~/\S/ ? 
                                                       : $tempkey)                               Text::Wrap::wrap('','&nbsp;'x4,$$allparms{$tempkey})
                                : $tempkey)
                      .'</label></span><br />'."\n");                       .'</label></span><br />'."\n");
         }          }
         $r->print('</div>');          $r->print('</div>');
Line 3098  sub standardkeyorder { Line 3298  sub standardkeyorder {
     return ('parameter_0_opendate' => 1,      return ('parameter_0_opendate' => 1,
         'parameter_0_duedate' => 2,          'parameter_0_duedate' => 2,
         'parameter_0_answerdate' => 3,          'parameter_0_answerdate' => 3,
         'parameter_0_interval' => 4,          'parameter_0_grace' => 4,
         'parameter_0_weight' => 5,          'parameter_0_interval' => 5,
         'parameter_0_maxtries' => 6,          'parameter_0_weight' => 6,
         'parameter_0_hinttries' => 7,          'parameter_0_maxtries' => 7,
         'parameter_0_contentopen' => 8,          'parameter_0_hinttries' => 8,
         'parameter_0_contentclose' => 9,          'parameter_0_contentopen' => 9,
         'parameter_0_type' => 10,          'parameter_0_contentclose' => 10,
         'parameter_0_problemstatus' => 11,          'parameter_0_type' => 11,
         'parameter_0_hiddenresource' => 12,          'parameter_0_problemstatus' => 12,
         'parameter_0_hiddenparts' => 13,          'parameter_0_hiddenresource' => 13,
         'parameter_0_display' => 14,          'parameter_0_hiddenparts' => 14,
         'parameter_0_ordered' => 15,          'parameter_0_display' => 15,
         'parameter_0_tol' => 16,          'parameter_0_ordered' => 16,
         'parameter_0_sig' => 17,          'parameter_0_tol' => 17,
         'parameter_0_turnoffunit' => 18,          'parameter_0_sig' => 18,
         'parameter_0_discussend' => 19,          'parameter_0_turnoffunit' => 19,
         'parameter_0_discusshide' => 20,          'parameter_0_discussend' => 20,
         'parameter_0_discussvote' => 21,          'parameter_0_discusshide' => 21,
         'parameter_0_printstartdate'  =>  22,          'parameter_0_discussvote' => 22,
         'parameter_0_printenddate' =>  23);          'parameter_0_printstartdate' => 23,
           'parameter_0_printenddate' => 24);
 }  }
   
   
Line 3630  sub assessparms { Line 3831  sub assessparms {
             'date_interval','int','float','string','string_lenient',              'date_interval','int','float','string','string_lenient',
             'string_examcode','string_deeplink','string_discussvote',              'string_examcode','string_deeplink','string_discussvote',
             'string_useslots','string_problemstatus','string_ip',              'string_useslots','string_problemstatus','string_ip',
             'string_questiontype') {              'string_questiontype','string_tex','string_grace') {
         $r->print('<input type="hidden" value="'.          $r->print('<input type="hidden" value="'.
             &HTML::Entities::encode($env{'form.recent_'.$item},'"&<>').              &HTML::Entities::encode($env{'form.recent_'.$item},'"&<>').
             '" name="recent_'.$item.'" />');              '" name="recent_'.$item.'" />');
Line 4299  sub readdata { Line 4500  sub readdata {
 # Stores parameter data, using form parameters directly.  # Stores parameter data, using form parameters directly.
 #  #
 # Uses the following form parameters. The variable part in the names is a resourcedata key (except for a modification for user data).  # Uses the following form parameters. The variable part in the names is a resourcedata key (except for a modification for user data).
 # set_* (except settext, setipallow, setipdeny, setdeeplink) - set a parameter value  # set_* (except settext, setipallow, setipdeny, setdeeplink, setgrace) - set a parameter value
 # del_* - remove a parameter  # del_* - remove a parameter
 # datepointer_* - set a date parameter (value is key_* refering to a set of other form parameters)  # datepointer_* - set a date parameter (value is key_* refering to a set of other form parameters)
 # dateinterval_* - set a date interval parameter (value refers to more form parameters)  # dateinterval_* - set a date interval parameter (value refers to more form parameters)
Line 4332  sub storedata { Line 4533  sub storedata {
             my $cmd=$1;              my $cmd=$1;
             my $thiskey=$2;              my $thiskey=$2;
             my ($altkey,$recursive,$tkey,$tkeyrec,$tkeynonrec);              my ($altkey,$recursive,$tkey,$tkeyrec,$tkeynonrec);
             next if ($cmd eq 'rec' || $cmd eq 'settext' || $cmd eq 'setipallow' || $cmd eq 'setipdeny' || $cmd eq 'setdeeplink');              next if ($cmd eq 'rec' || $cmd eq 'settext' || $cmd eq 'setipallow' || $cmd eq 'setipdeny' || $cmd eq 'setdeeplink' || $cmd eq 'setgrace');
             if ((($cmd eq 'set') || ($cmd eq 'datepointer') || ($cmd eq 'dateinterval') || ($cmd eq 'del')) &&               if ((($cmd eq 'set') || ($cmd eq 'datepointer') || ($cmd eq 'dateinterval') || ($cmd eq 'del')) && 
                  ($thiskey =~ /(?:sequence|page)\Q___(all)\E/)) {                   ($thiskey =~ /(?:sequence|page)\Q___(all)\E/)) {
                 unless ($thiskey =~ /(encrypturl|hiddenresource)$/) {                  unless ($thiskey =~ /(encrypturl|hiddenresource)$/) {
Line 4391  sub storedata { Line 4592  sub storedata {
                         if ($thiskey =~ /\.retrypartial$/) {                          if ($thiskey =~ /\.retrypartial$/) {
                             $name = 'retrypartial';                              $name = 'retrypartial';
                         }                          }
                       } elsif ($typeof eq 'string_tex') {
                           $name = 'texdisplay';
                     }                      }
                 } elsif ($cmd eq 'datepointer') {                  } elsif ($cmd eq 'datepointer') {
                     $data=&Apache::lonhtmlcommon::get_date_from_form($env{$key});                      $data=&Apache::lonhtmlcommon::get_date_from_form($env{$key});
Line 4965  sub listdata { Line 5168  sub listdata {
     # Ready to print      # Ready to print
     #      #
             my $parmitem = &standard_parameter_names($name);              my $parmitem = &standard_parameter_names($name);
               my $advice;
               if (($name eq 'mapalias') && ($middle) && (!$is_map)) {
                   if ($middle =~ m{^uploaded/}) {
                       $advice = &mt('Use Course Editor to set this.');
                   } else {
                       $advice = &mt('Use Resource Assembly Tool to set this.');
                   }
                   $advice = '<br /><span class="LC_fontsize_small LC_cusr_emph">'.$advice.'</span>';
               }
             $r->print(&tablestart($readonly,$is_map).              $r->print(&tablestart($readonly,$is_map).
                 &Apache::loncommon::start_data_table_row().                  &Apache::loncommon::start_data_table_row().
                 '<td><b>'.&mt($parmitem).                  '<td><b>'.&mt($parmitem).
                 '</b></td>');                  '</b>'.$advice.'</td>');
             unless ($readonly) {              unless ($readonly) {
                 my $disabled;                  my $disabled;
                 if (($name eq 'availablestudent') &&                  if (($name eq 'availablestudent') &&
                     (($showval eq '') || ($userscope))) {                      (($showval eq '') || ($userscope))) {
                     $disabled = ' disabled="disabled"';                      $disabled = ' disabled="disabled"';
                   } elsif (($name eq 'mapalias') && ($showval eq '')) {
                       $disabled = ' disabled="disabled"';
                 }                  }
                 $r->print('<td><input type="checkbox" name="del_'.                  $r->print('<td><input type="checkbox" name="del_'.
                         $thiskey.'"'.$disabled.' /></td>');                          $thiskey.'"'.$disabled.' /></td>');
Line 5006  sub listdata { Line 5220  sub listdata {
             } elsif ($thistype =~ m/^string/) {              } elsif ($thistype =~ m/^string/) {
                 if ($name eq 'availablestudent') {                  if ($name eq 'availablestudent') {
                     $readonly = 1;                      $readonly = 1;
                   } elsif (($name eq 'mapalias') && ($showval eq '')) {
                       $readonly = 1;
                 }                  }
                 $r->print(&string_selector($thistype,$thiskey,                  $r->print(&string_selector($thistype,$thiskey,
                           $showval,$name,$readonly));                            $showval,$name,$readonly));
Line 5166  sub string_ip_selector { Line 5382  sub string_ip_selector {
   
 sub string_deeplink_selector {  sub string_deeplink_selector {
     my ($thiskey, $showval, $readonly) = @_;      my ($thiskey, $showval, $readonly) = @_;
     my (@components,%values,@current,%titles,%options,%optiontext,%defaults,      my (@tables,%values,@current,%titles,%options,%optiontext,%defaults,
         %selectnull,%domlti,%crslti,@possmenus);          %selectnull,%domlti,%crslti,@possmenus,%components);
     @components = ('state','others','listing','scope','protect','menus','target');      @tables = ('upper','lower');
       %components = (
                       upper => ['state','others','listing','scope'],
                       lower => ['protect','menus','target','exit'],
                     );   
     %titles = &Apache::lonlocal::texthash (      %titles = &Apache::lonlocal::texthash (
                   state   => 'Access status',                    state   => 'Access status',
                   others  => 'Hide other resources',                    others  => 'Hide other resources',
Line 5177  sub string_deeplink_selector { Line 5397  sub string_deeplink_selector {
                   protect => 'Link protection',                    protect => 'Link protection',
                   menus   => 'Menu Items Displayed',                    menus   => 'Menu Items Displayed',
                   target  => 'Embedded?',                    target  => 'Embedded?',
                     exit    => 'Exit Tool Button?',
               );                );
     %options = (      %options = (
                    state   => ['only','off','both'],                     state   => ['only','off','both'],
Line 5186  sub string_deeplink_selector { Line 5407  sub string_deeplink_selector {
                    protect => ['none','key','ltid','ltic'],                     protect => ['none','key','ltid','ltic'],
                    menus   => ['std','colls'],                     menus   => ['std','colls'],
                    target  => ['_self','_top'],                     target  => ['_self','_top'],
                      exit    => ['no','yes','url'],
                );                 );
     %optiontext = &Apache::lonlocal::texthash (      %optiontext = &Apache::lonlocal::texthash (
                     only       => 'deep only',                      only       => 'deep only',
Line 5209  sub string_deeplink_selector { Line 5431  sub string_deeplink_selector {
                     colls      => 'Numbered collection',                      colls      => 'Numbered collection',
                     _self      => 'Embedded',                      _self      => 'Embedded',
                     _top       => 'Not embedded',                      _top       => 'Not embedded',
                       no         => 'Not in use',
                       yes        => 'In use, no URL redirect',
                       url        => 'In use, redirect to URL',  
                   );                    );
     %selectnull = &Apache::lonlocal::texthash (      %selectnull = &Apache::lonlocal::texthash (
                     ltic => 'Select Launcher',                      ltic => 'Select Launcher',
Line 5225  sub string_deeplink_selector { Line 5450  sub string_deeplink_selector {
         ($values{'protect'}) = ($current[4] =~ /^(key:[a-zA-Z\d_.!\@#\$%^&*()+=-]+|ltic:\d+|ltid:\d+)$/);          ($values{'protect'}) = ($current[4] =~ /^(key:[a-zA-Z\d_.!\@#\$%^&*()+=-]+|ltic:\d+|ltid:\d+)$/);
         ($values{'menus'}) = ($current[5] =~ /^(\d+)$/);          ($values{'menus'}) = ($current[5] =~ /^(\d+)$/);
         ($values{'target'}) = ($current[6] =~ /^(_self|_top)$/);          ($values{'target'}) = ($current[6] =~ /^(_self|_top)$/);
           ($values{'exit'}) = ($current[7] =~ /^((?:(?:yes|url)(?:|\:[^:;"',]+))|no)$/);
     } else {      } else {
         $defaults{'state'} = 'off',          $defaults{'state'} = 'off',
         $defaults{'others'} = 'unhide',          $defaults{'others'} = 'unhide',
Line 5233  sub string_deeplink_selector { Line 5459  sub string_deeplink_selector {
         $defaults{'protect'} = 'none';          $defaults{'protect'} = 'none';
         $defaults{'menus'} = '0';          $defaults{'menus'} = '0';
         $defaults{'target'} = '_top';          $defaults{'target'} = '_top';
           $defaults{'exit'} = 'yes';
     }      }
     my $disabled;      my $disabled;
     if ($readonly) {      if ($readonly) {
Line 5240  sub string_deeplink_selector { Line 5467  sub string_deeplink_selector {
     }      }
     my %courselti =      my %courselti =
         &Apache::lonnet::get_course_lti($env{'course.'.$env{'request.course.id'}.'.num'},          &Apache::lonnet::get_course_lti($env{'course.'.$env{'request.course.id'}.'.num'},
                                         $env{'course.'.$env{'request.course.id'}.'.domain'});                                          $env{'course.'.$env{'request.course.id'}.'.domain'},
                                           'provider');
     foreach my $item (keys(%courselti)) {      foreach my $item (keys(%courselti)) {
         if (ref($courselti{$item}) eq 'HASH') {          if (ref($courselti{$item}) eq 'HASH') {
             $crslti{$item} = $courselti{$item}{'name'};              $crslti{$item} = $courselti{$item}{'name'};
Line 5263  sub string_deeplink_selector { Line 5491  sub string_deeplink_selector {
         }          }
     }      }
   
     my $output = '<input type="hidden" name="set_'.$thiskey.'" /><table><tr>';      my $output = '<input type="hidden" name="set_'.$thiskey.'" />';
     foreach my $item (@components) {      foreach my $table ('upper','lower') {
         $output .= '<th>'.$titles{$item}.'</th>';          next unless (ref($components{$table}) eq 'ARRAY');
     }          $output .= '<table width="100%"><tr>';
     $output .= '</tr><tr>';          foreach my $item (@{$components{$table}}) {
     foreach my $item (@components) {              $output .= '<th>'.$titles{$item}.'</th>';
         $output .= '<td>';          }
         if (($item eq 'protect') || ($item eq 'menus')) {          $output .= '</tr><tr>';
             my $selected = $values{$item};          foreach my $item (@{$components{$table}}) {
             foreach my $option (@{$options{$item}}) {              $output .= '<td>';
                 if ($item eq 'protect') {               if (($item eq 'protect') || ($item eq 'menus') || ($item eq 'exit')) {
                     if ($option eq 'ltid') {                  my $selected = $values{$item};
                         next unless (keys(%domlti));                  foreach my $option (@{$options{$item}}) {
                     } elsif ($option eq 'ltic') {                      if ($item eq 'protect') { 
                         next unless (keys(%crslti));                          if ($option eq 'ltid') {
                     }                              next unless (keys(%domlti));
                 } elsif (($item eq 'menus') && ($option eq 'colls')) {                          } elsif ($option eq 'ltic') {
                     next unless (@possmenus);                              next unless (keys(%crslti));
                 }                          }
                 my $checked;                      } elsif (($item eq 'menus') && ($option eq 'colls')) {
                 if ($item eq 'menus') {                          next unless (@possmenus);
                     if (($selected =~ /^\d+$/) && (@possmenus) &&                      }
                         (grep(/^\Q$selected\E$/,@possmenus))) {                      my $checked;
                         if ($option eq 'colls') {                      if ($item eq 'menus') {
                           if (($selected =~ /^\d+$/) && (@possmenus) &&
                               (grep(/^\Q$selected\E$/,@possmenus))) {
                               if ($option eq 'colls') {
                                   $checked = ' checked="checked"';
                               }
                           } elsif (($option eq 'std') && ($selected == 0) && ($selected ne '')) {
                             $checked = ' checked="checked"';                              $checked = ' checked="checked"';
                         }                          }
                     } elsif (($option eq 'std') && ($selected == 0) && ($selected ne '')) {                      } elsif ($selected =~ /^\Q$option\E/) {
                         $checked = ' checked="checked"';                          $checked = ' checked="checked"';
                     }                      }
                 } elsif ($selected =~ /^\Q$option\E/) {                      my $onclick;
                     $checked = ' checked="checked"';                      unless ($readonly) {
                 }                          my $esc_key = &js_escape($thiskey);
                 my $onclick;                          $onclick = ' onclick="toggleDeepLink(this.form,'."'$item','$esc_key'".');"';
                 unless ($readonly) {                      }
                     my $esc_key = &js_escape($thiskey);                      $output .= '<span class="LC_nobreak"><label>'.
                     $onclick = ' onclick="toggleDeepLink(this.form,'."'$item','$esc_key'".');"';                                 '<input type="radio" name="deeplink_'.$item.'_'.$thiskey.'" value="'.$option.'"'.$onclick.$disabled.$checked.' />'."\n".
                 }                                 $optiontext{$option}.'</label>';
                 $output .= '<span class="LC_nobreak"><label>'.                      if (($item eq 'protect') && ($option eq 'key')) {
                            '<input type="radio" name="deeplink_'.$item.'_'.$thiskey.'" value="'.$option.'"'.$onclick.$disabled.$checked.' />'."\n".                          my $visibility="hidden";
                            $optiontext{$option}.'</label>';                          my $currkey;
                 if (($item eq 'protect') && ($option eq 'key')) {                          if ($checked) {
                     my $visibility="hidden";                              $visibility = "text";
                     my $currkey;                              $currkey = (split(/\:/,$values{$item}))[1];
                     if ($checked) {                          }
                         $visibility = "text";                          $output .= '&nbsp;'.
                         $currkey = (split(/\:/,$values{$item}))[1];                                     '<input type="'.$visibility.'" name="deeplink_'.$option.'_'.$thiskey.'" id="deeplink_'.$option.'_'.$item.'_'.$thiskey.'" value="'.$currkey.'" size="10"'.$disabled.' />';
                     }                      } elsif (($option eq 'ltic') || ($option eq 'ltid') || ($option eq 'colls')) {
                     $output .= '&nbsp;'.                          my $display="none";
                         '<input type="'.$visibility.'" name="deeplink_'.$option.'_'.$thiskey.'" id="deeplink_'.$option.'_'.$item.'_'.$thiskey.'" value="'.$currkey.'" size="10"'.$disabled.' />';                          my ($current,$blankcheck,@possibles);
                 } elsif (($option eq 'ltic') || ($option eq 'ltid') || ($option eq 'colls')) {                          if ($checked) {
                     my $display="none";                              $display = 'inline-block';
                     my ($current,$blankcheck,@possibles);                              if (($option eq 'ltic') || ($option eq 'ltid'))  {
                     if ($checked) {                                  $current = (split(/\:/,$selected))[1];
                         $display = 'inline-block';                              } else {
                         if (($option eq 'ltic') || ($option eq 'ltid'))  {                                  $current = $selected;
                             $current = (split(/\:/,$selected))[1];                              }
                         } else {                          } else {
                             $current = $selected;                              $blankcheck = ' selected="selected"';
                         }  
                     } else {  
                         $blankcheck = ' selected="selected"';  
                     }  
                     if ($option eq 'ltid') {  
                         @possibles = keys(%domlti);  
                     } elsif ($option eq 'ltic') {  
                         @possibles = keys(%crslti);   
                     } else {  
                         @possibles = @possmenus;  
                     }  
                     $output .= '<div id="deeplinkdiv_'.$option.'_'.$item.'_'.$thiskey.'"'.  
                                ' style="display: '.$display.'">&nbsp;<select name="'.  
                                'deeplink_'.$option.'_'.$thiskey.'"'.$disabled.'>';  
                     if (@possibles > 1) {  
                         $output .= '<option value=""'.$blankcheck.'>'.$selectnull{$option}.  
                                    '</option>'."\n";  
                     }  
                     foreach my $poss (sort { $a <=> $b } @possibles) {  
                         my $selected;  
                         if (($poss == $current) || (scalar(@possibles) ==1)) {  
                             $selected = ' selected="selected"';  
                         }                          }
                         my $shown = $poss;  
                         if ($option eq 'ltid') {                          if ($option eq 'ltid') {
                             $shown = $domlti{$poss};                              @possibles = keys(%domlti);
                         } elsif ($option eq 'ltic') {                          } elsif ($option eq 'ltic') {
                             $shown = $crslti{$poss};                              @possibles = keys(%crslti); 
                           } else {
                               @possibles = @possmenus;
                           }
                           $output .= '<div id="deeplinkdiv_'.$option.'_'.$item.'_'.$thiskey.'"'.
                                      ' style="display: '.$display.'">&nbsp;<select name="'.
                                      'deeplink_'.$option.'_'.$thiskey.'"'.$disabled.'>';
                           if (@possibles > 1) {
                               $output .= '<option value=""'.$blankcheck.'>'.$selectnull{$option}.
                                          '</option>'."\n";
                           }
                           foreach my $poss (sort { $a <=> $b } @possibles) {
                               my $selected;
                               if (($poss == $current) || (scalar(@possibles) ==1)) {
                                   $selected = ' selected="selected"';
                               }
                               my $shown = $poss;
                               if ($option eq 'ltid') {
                                   $shown = $domlti{$poss};
                               } elsif ($option eq 'ltic') {
                                   $shown = $crslti{$poss};
                               }
                               $output .= '<option value="'.$poss.'"'.$selected.'>'.$shown.'</option>';
                           }
                           $output .= '</select></div>';
                       }
                       $output .= '</span> ';
                   }
                   if ($item eq 'exit') {
                       my $exitsty = 'none';
                       my $displayval;
                       if ($values{$item} =~ /^(yes|url)/) { 
                           $exitsty = 'inline-block';
                           my $currval = (split(/\:/,$values{$item}))[1];
                           if ($currval eq '') {
                               $displayval = 'Exit Tool';
                           } else {
                               $displayval = $currval;
                         }                          }
                         $output .= '<option value="'.$poss.'"'.$selected.'>'.$shown.'</option>';  
                     }                      }
                     $output .= '</select></div>';                      $output .= '<div id="deeplinkdiv_'.$item.'_'.$thiskey.'"'.
                                  ' style="display: '.$exitsty.'"><br />'.&mt('Button text').': '.
                                  '<input type="text" name="deeplink_exittext_'.$thiskey.'"'.
                                  ' id="deeplink_exittext_'.$thiskey.'" value="'.$displayval.'"'.
                                  ' size="10"'.$disabled.' /></div>';
                 }                  }
                 $output .= '</span> ';              } else {
             }                  my $selected = $values{$item};
                   my $defsel;
                   if ($selected eq '') {
                       $defsel = ' selected="selected"';
                   }
                   $output .= '<select name="deeplink_'.$item.'_'.$thiskey.'"'.$disabled.'>'."\n".
                              '<option value=""'.$defsel.'>'.&mt('Please select').'</option>'."\n";
                   foreach my $option (@{$options{$item}}) {
                       $output .= '<option value="'.$option.'"';
                       if ($option eq $selected) {
                           $output .= ' selected="selected"';
                       }
                       $output .= '>'.$optiontext{$option}.'</option>';
                   }
                   $output .= '</select>';
               }
               $output .= '</td>';
           }
           $output .= '</tr></table>'."\n";
           if ($table eq 'upper') {
               $output .= '<br />';
           }
       }
       return $output;
   }
   
   sub string_grace_selector {
       my ($thiskey, $showval, $readonly) = @_;
       my $addmore;
       unless ($readonly) {
           $addmore = "\n".'<button class="LC_add_grace_button">'.&mt('Add more').'</button>';
       }
       my $output = '<input type="hidden" name="set_'.$thiskey.'" value="" />'.
                    '<div class="LC_string_grace_wrap" id="LC_string_grace_'.$thiskey.'">'."\n".
                    '<div class="LC_string_grace_inner">'."\n";
       if ($showval ne '') {
           my @current;
           if ($showval =~ /,/) {
               @current = split(/,/,$showval);
         } else {          } else {
             my $selected = $values{$item};              @current = ($showval);
             my $defsel;          }
             if ($selected eq '') {          my $num = scalar(@current);
                 $defsel = ' selected="selected"';          foreach my $item (@current) {
             }              my ($delta,$fraction,$gradational) = split(/:/,$item);
             $output .= '<select name="deeplink_'.$item.'_'.$thiskey.'"'.$disabled.'>'."\n".              if (($delta =~ /^\d+$/) && ($fraction =~ /^(0|1)\.?\d*$/) && 
                        '<option value=""'.$defsel.'>'.&mt('Please select').'</option>'."\n";                  (($gradational eq 1) || ($gradational eq '0'))) {
             foreach my $option (@{$options{$item}}) {                  my $gradchk = '';
                 $output .= '<option value="'.$option.'"';                  if ($gradational) {
                 if ($option eq $selected) {                      $gradchk = ' checked="checked"';
                     $output .= ' selected="selected"';  
                 }                  }
                 $output .= '>'.$optiontext{$option}.'</option>';                  $output .= &grace_form($thiskey,$delta,$fraction,$gradchk,
                                          $readonly);
             }              }
             $output .= '</select>';  
         }          }
         $output .= '</td>';      } elsif (!$readonly) {
           $output .= &grace_form($thiskey,'','','',$readonly);
     }      }
     $output .= '</tr></table>'."\n";      $output .= '</div>'.$addmore.'</div>';
     return $output;      return $output;
 }  }
   
   sub grace_form {
       my ($thiskey,$delta,$fraction,$gradchkon,$readonly) = @_;
       my $disabled;
       if ($readonly) {
           $disabled = ' disabled="disabled"';
       }
       my %lt = &grace_titles();
       my $output = '<div><input type="hidden" name="setgrace_'.$thiskey.'" value="" />'.
                    '<fieldset class="LC_grace"><legend>'.$lt{'sinc'}.'</legend>';
       foreach my $which (['days', 86400, 31],
                          ['hours', 3600, 23],
                          ['minutes', 60, 59],
                          ['seconds',  1, 59]) {
           my ($name, $factor, $max) = @{ $which };
           my $amount;
           if ($delta ne '') {
               $amount = int($delta/$factor);
               $delta %= $factor;
           }
           my %select = ((map {$_ => $_} (0..$max)),
                         'select_form_order' => [0..$max]);
           $output .= &Apache::loncommon::select_form($amount,$name.'_'.$thiskey,
                                                      \%select,'',$readonly);
           $output .= '&nbsp;'.$lt{$name}.'&nbsp;&nbsp; ';
       }
       $output .= '</fieldset>'.
                  '<fieldset class="LC_grace"><legend>'.$lt{'pcr'}.'</legend>'.
                  '<input type="text" size="3" name="frac_'.$thiskey.'" value="'.$fraction.'"'.$disabled.' />'.
                  '&nbsp;&nbsp;<label><input type="checkbox" value="1" name="grad_'.$thiskey.'"'.$gradchkon.$disabled.' />'.
                  $lt{'grad'}.'</label></fieldset>';
       unless ($readonly) {
           $output .= '<a href="#" class="LC_remove_grace">'.$lt{'remo'}.'</a>';
       }
       $output .= '</div>'."\n";
       return $output;
   }
   
   sub grace_titles {
       return &Apache::lonlocal::texthash (
                                            sinc => 'Time past due',
                                            remo => 'Remove',
                                            pcr => 'Partial credit',
                                            grad => 'gradual',
                                            days => 'days',
                                            hours => 'hours',
                                            minutes => 'minutes',
                                            seconds => 'seconds',
       );
   }
   
 { # block using some constants related to parameter types (overview mode)  { # block using some constants related to parameter types (overview mode)
   
Line 5414  my %strings = Line 5752  my %strings =
              => [['_allowfrom_','Hostname(s), or IP(s) from which access is allowed'],               => [['_allowfrom_','Hostname(s), or IP(s) from which access is allowed'],
                  ['_denyfrom_','Hostname(s) or IP(s) from which access is disallowed']],                    ['_denyfrom_','Hostname(s) or IP(s) from which access is disallowed']], 
      'string_deeplink'       'string_deeplink'
              => [['on','Set choices for link protection, resource listing, access scope, shown menu items, and embedding']],               => [['on','Set choices for link protection, resource listing, access scope, shown menu items, embedding, and exit link']],
        'string_tex'
                => [['tth', 'tth (TeX to HTML)'],
                    ['mathjax', 'MathJax']],
        'string_grace'
                => [['on','Set grading scale and grace period for submissions after due date']],
     );      );
         
   
Line 5425  my %stringmatches = ( Line 5768  my %stringmatches = (
               => [['_allowfrom_','[^\!]+'],                => [['_allowfrom_','[^\!]+'],
                   ['_denyfrom_','\!']],                    ['_denyfrom_','\!']],
          'string_deeplink'           'string_deeplink'
               => [['on','^(only|off|both)\,(hide|unhide)\,(full|absent|grades|details|datestatus)\,(res|map|rec)\,(none|key\:\w+|ltic\:\d+|ltid\:\d+)\,(\d+|)\,_(self|top)$']],                => [['on','^(only|off|both)\,(hide|unhide)\,(full|absent|grades|details|datestatus)\,(res|map|rec)\,(none|key\:\w+|ltic\:\d+|ltid\:\d+)\,(\d+|)\,_(self|top),(yes|url|no)(|:[^:;\'",]+)$']],
            'string_grace'
                 => [['on','^\d+,(0|1)\.?\d*,(0|1)']],
     );      );
   
 my %stringtypes = (  my %stringtypes = (
Line 5436  my %stringtypes = ( Line 5781  my %stringtypes = (
                     examcode     => 'string_examcode',                      examcode     => 'string_examcode',
                     acc          => 'string_ip',                      acc          => 'string_ip',
                     deeplink     => 'string_deeplink',                      deeplink     => 'string_deeplink',
                       grace        => 'string_grace',
                       texdisplay   => 'string_tex',
                   );                    );
   
 # Returns the possible values and titles for a given string type, or undef if there are none.  # Returns the possible values and titles for a given string type, or undef if there are none.
Line 5496  sub string_selector { Line 5843  sub string_selector {
             ($thistype eq 'string_discussvote') ||              ($thistype eq 'string_discussvote') ||
             ($thistype eq 'string_ip') ||              ($thistype eq 'string_ip') ||
             ($thistype eq 'string_deeplink') ||              ($thistype eq 'string_deeplink') ||
               ($thistype eq 'string_tex') ||
               ($thistype eq 'string_grace') ||
             ($name eq 'retrypartial')) {              ($name eq 'retrypartial')) {
         my ($got_chostname,$chostname,$cmajor,$cminor);           my ($got_chostname,$chostname,$cmajor,$cminor); 
         foreach my $possibilities (@{ $strings{$thistype} }) {          foreach my $possibilities (@{ $strings{$thistype} }) {
Line 5533  sub string_selector { Line 5882  sub string_selector {
     }      }
   
     if ($thistype eq 'string_ip') {      if ($thistype eq 'string_ip') {
         return &string_ip_selector($thiskey,$showval,$readonly);           return &string_ip_selector($thiskey,$showval,$readonly);
       } elsif ($thistype eq 'string_grace') {
           return &string_grace_selector($thiskey,$showval,$readonly);
     } elsif ($thistype eq 'string_deeplink') {      } elsif ($thistype eq 'string_deeplink') {
         return &string_deeplink_selector($thiskey,$showval,$readonly);          return &string_deeplink_selector($thiskey,$showval,$readonly);
     }      }
Line 5972  sub newoverview { Line 6323  sub newoverview {
             &toggleparmtextbox_js()."\n".              &toggleparmtextbox_js()."\n".
             &validateparms_js()."\n".              &validateparms_js()."\n".
             &ipacc_boxes_js()."\n".              &ipacc_boxes_js()."\n".
               &grace_js()."\n".
             &done_proctor_js()."\n".              &done_proctor_js()."\n".
             &deeplink_js()."\n".              &deeplink_js()."\n".
 '// ]]>  '// ]]>
Line 6200  sub overview { Line 6552  sub overview {
              &toggleparmtextbox_js()."\n".               &toggleparmtextbox_js()."\n".
              &validateparms_js()."\n".               &validateparms_js()."\n".
              &ipacc_boxes_js()."\n".               &ipacc_boxes_js()."\n".
                &grace_js()."\n".
              &done_proctor_js()."\n".               &done_proctor_js()."\n".
              &deeplink_js()."\n".               &deeplink_js()."\n".
              '// ]]>'."\n".               '// ]]>'."\n".
Line 7489  sub parm_change_log { Line 7842  sub parm_change_log {
                     } else {                      } else {
                         if (&isdateparm($istype{$parmname})) {                          if (&isdateparm($istype{$parmname})) {
                             $showvalue = &Apache::lonlocal::locallocaltime($value);                              $showvalue = &Apache::lonlocal::locallocaltime($value);
                           } elsif (($istype{$parmname} eq 'string_grace') ||
                                    ($istype{$parmname} eq 'string_ip')) {
                               $showvalue =~ s/,/, /g;
                         }                          }
                     }                      }
                     $output .= $showvalue;                      $output .= $showvalue;

Removed from v.1.615  
changed lines
  Added in v.1.622


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