Diff for /loncom/interface/loncommon.pm between versions 1.867 and 1.1025

version 1.867, 2009/07/27 11:30:05 version 1.1025, 2011/10/31 01:14:24
Line 409  sub studentbrowser_javascript { Line 409  sub studentbrowser_javascript {
 <script type="text/javascript" language="Javascript">  <script type="text/javascript" language="Javascript">
 // <![CDATA[  // <![CDATA[
     var stdeditbrowser;      var stdeditbrowser;
     function openstdbrowser(formname,uname,udom,roleflag,ignorefilter,courseadvonly) {      function openstdbrowser(formname,uname,udom,clicker,roleflag,ignorefilter,courseadvonly) {
         var url = '/adm/pickstudent?';          var url = '/adm/pickstudent?';
         var filter;          var filter;
  if (!ignorefilter) {   if (!ignorefilter) {
Line 421  sub studentbrowser_javascript { Line 421  sub studentbrowser_javascript {
    }     }
         }          }
         url += 'form=' + formname + '&unameelement='+uname+          url += 'form=' + formname + '&unameelement='+uname+
                                     '&udomelement='+udom;                                      '&udomelement='+udom+
                                       '&clicker='+clicker;
  if (roleflag) { url+="&roles=1"; }   if (roleflag) { url+="&roles=1"; }
         if (courseadvonly) { url+="&courseadvonly=1"; }          if (courseadvonly) { url+="&courseadvonly=1"; }
         var title = 'Student_Browser';          var title = 'Student_Browser';
Line 435  sub studentbrowser_javascript { Line 436  sub studentbrowser_javascript {
 ENDSTDBRW  ENDSTDBRW
 }  }
   
   sub resourcebrowser_javascript {
      unless ($env{'request.course.id'}) { return ''; }
      return (<<'ENDRESBRW');
   <script type="text/javascript" language="Javascript">
   // <![CDATA[
       var reseditbrowser;
       function openresbrowser(formname,reslink) {
           var url = '/adm/pickresource?form='+formname+'&reslink='+reslink;
           var title = 'Resource_Browser';
           var options = 'scrollbars=1,resizable=1,menubar=0';
           options += ',width=700,height=500';
           reseditbrowser = open(url,title,options,'1');
           reseditbrowser.focus();
       }
   // ]]>
   </script>
   ENDRESBRW
   }
   
 sub selectstudent_link {  sub selectstudent_link {
    my ($form,$unameele,$udomele,$courseadvonly)=@_;     my ($form,$unameele,$udomele,$courseadvonly,$clickerid)=@_;
    my $callargs = "'".$form."','".$unameele."','".$udomele."'";     my $callargs = "'".&Apache::lonhtmlcommon::entity_encode($form)."','".
                         &Apache::lonhtmlcommon::entity_encode($unameele)."','".
                         &Apache::lonhtmlcommon::entity_encode($udomele)."'";
    if ($env{'request.course.id'}) {       if ($env{'request.course.id'}) {  
        if (!&Apache::lonnet::allowed('srm',$env{'request.course.id'})         if (!&Apache::lonnet::allowed('srm',$env{'request.course.id'})
    && !&Apache::lonnet::allowed('srm',$env{'request.course.id'}.     && !&Apache::lonnet::allowed('srm',$env{'request.course.id'}.
  '/'.$env{'request.course.sec'})) {   '/'.$env{'request.course.sec'})) {
    return '';     return '';
        }         }
          $callargs.=",'".&Apache::lonhtmlcommon::entity_encode($clickerid)."'";
        if ($courseadvonly)  {         if ($courseadvonly)  {
            $callargs .= ",'',1,1";             $callargs .= ",'',1,1";
        }         }
Line 452  sub selectstudent_link { Line 475  sub selectstudent_link {
               &mt('Select User').'</a></span>';                &mt('Select User').'</a></span>';
    }     }
    if ($env{'request.role'}=~/^(au|dc|su)/) {     if ($env{'request.role'}=~/^(au|dc|su)/) {
        $callargs .= ",1";          $callargs .= ",'',1"; 
        return '<span class="LC_nobreak">'.         return '<span class="LC_nobreak">'.
               '<a href="javascript:openstdbrowser('.$callargs.');">'.                '<a href="javascript:openstdbrowser('.$callargs.');">'.
               &mt('Select User').'</a></span>';                &mt('Select User').'</a></span>';
Line 460  sub selectstudent_link { Line 483  sub selectstudent_link {
    return '';     return '';
 }  }
   
   sub selectresource_link {
      my ($form,$reslink,$arg)=@_;
      
      my $callargs = "'".&Apache::lonhtmlcommon::entity_encode($form)."','".
                         &Apache::lonhtmlcommon::entity_encode($reslink)."'";
      unless ($env{'request.course.id'}) { return $arg; }
      return '<span class="LC_nobreak">'.
                 '<a href="javascript:openresbrowser('.$callargs.');">'.
                 $arg.'</a></span>';
   }
   
   
   
 sub authorbrowser_javascript {  sub authorbrowser_javascript {
     return <<"ENDAUTHORBRW";      return <<"ENDAUTHORBRW";
 <script type="text/javascript" language="JavaScript">  <script type="text/javascript" language="JavaScript">
Line 482  ENDAUTHORBRW Line 518  ENDAUTHORBRW
 }  }
   
 sub coursebrowser_javascript {  sub coursebrowser_javascript {
     my ($domainfilter,$sec_element,$formname)=@_;      my ($domainfilter,$sec_element,$formname,$role_element,$crstype) = @_;
     my $crs_or_grp_alert = &mt('Please select the type of LON-CAPA entity - Course or Community - for which you wish to add/modify a user role');      my $wintitle = 'Course_Browser';
    my $output = '      if ($crstype eq 'Community') {
           $wintitle = 'Community_Browser';
       }
       my $id_functions = &javascript_index_functions();
       my $output = '
 <script type="text/javascript" language="JavaScript">  <script type="text/javascript" language="JavaScript">
 // <![CDATA[  // <![CDATA[
     var stdeditbrowser;'."\n";      var stdeditbrowser;'."\n";
    $output .= <<"ENDSTDBRW";  
     function opencrsbrowser(formname,uname,udom,desc,extra_element,multflag,crstype) {      $output .= <<"ENDSTDBRW";
       function opencrsbrowser(formname,uname,udom,desc,extra_element,multflag,type,type_elem) {
         var url = '/adm/pickcourse?';          var url = '/adm/pickcourse?';
         var domainfilter = '';  
         var formid = getFormIdByName(formname);          var formid = getFormIdByName(formname);
         if (formid > -1) {          var domainfilter = getDomainFromSelectbox(formname,udom);
             var domid = getIndexByName(formid,udom);  
             if (domid > -1) {  
                 if (document.forms[formid].elements[domid].type == 'select-one') {  
                     domainfilter=document.forms[formid].elements[domid].options[document.forms[formid].elements[domid].selectedIndex].value;  
                 }  
                 if (document.forms[formid].elements[domid].type == 'hidden') {  
                     domainfilter=document.forms[formid].elements[domid].value;  
                 }  
             }  
         }  
         if (domainfilter != null) {          if (domainfilter != null) {
            if (domainfilter != '') {             if (domainfilter != '') {
                url += 'domainfilter='+domainfilter+'&';                 url += 'domainfilter='+domainfilter+'&';
Line 529  sub coursebrowser_javascript { Line 559  sub coursebrowser_javascript {
                 }                  }
             }                   }     
         }          }
         if (multflag !=null && multflag != '') {          if (type != null && type != '') {
             url += '&multiple='+multflag;              url += '&type='+type;
         }          }
         if (crstype == 'Course/Community') {          if (type_elem != null && type_elem != '') {
             if (formname == 'cu') {              url += '&typeelement='+type_elem;
                 crstype = document.cu.crstype.options[document.cu.crstype.selectedIndex].value;           }
                 if (crstype == "") {          if (formname == 'ccrs') {
                     alert("$crs_or_grp_alert");              var ownername = document.forms[formid].ccuname.value;
                     return;              var ownerdom =  document.forms[formid].ccdomain.options[document.forms[formid].ccdomain.selectedIndex].value;
                 }              url += '&cloner='+ownername+':'+ownerdom;
             }  
         }          }
         if (crstype !=null && crstype != '') {          if (multflag !=null && multflag != '') {
             url += '&type='+crstype;              url += '&multiple='+multflag;
         }          }
         var title = 'Course_Browser';          var title = '$wintitle';
         var options = 'scrollbars=1,resizable=1,menubar=0';          var options = 'scrollbars=1,resizable=1,menubar=0';
         options += ',width=700,height=600';          options += ',width=700,height=600';
         stdeditbrowser = open(url,title,options,'1');          stdeditbrowser = open(url,title,options,'1');
         stdeditbrowser.focus();          stdeditbrowser.focus();
     }      }
   $id_functions
   ENDSTDBRW
       if (($sec_element ne '') || ($role_element ne '')) {
           $output .= &setsec_javascript($sec_element,$formname,$role_element);
       }
       $output .= '
   // ]]>
   </script>';
       return $output;
   }
   
   sub javascript_index_functions {
       return <<"ENDJS";
   
   function getFormIdByName(formname) {
       for (var i=0;i<document.forms.length;i++) {
           if (document.forms[i].name == formname) {
               return i;
           }
       }
       return -1;
   }
   
   function getIndexByName(formid,item) {
       for (var i=0;i<document.forms[formid].elements.length;i++) {
           if (document.forms[formid].elements[i].name == item) {
               return i;
           }
       }
       return -1;
   }
   
     function getFormIdByName(formname) {  function getDomainFromSelectbox(formname,udom) {
         for (var i=0;i<document.forms.length;i++) {      var userdom;
             if (document.forms[i].name == formname) {      var formid = getFormIdByName(formname);
                 return i;      if (formid > -1) {
           var domid = getIndexByName(formid,udom);
           if (domid > -1) {
               if (document.forms[formid].elements[domid].type == 'select-one') {
                   userdom=document.forms[formid].elements[domid].options[document.forms[formid].elements[domid].selectedIndex].value;
               }
               if (document.forms[formid].elements[domid].type == 'hidden') {
                   userdom=document.forms[formid].elements[domid].value;
             }              }
         }          }
         return -1;   
     }      }
       return userdom;
   }
   
   ENDJS
   
   }
   
     function getIndexByName(formid,item) {  sub javascript_array_indexof {
         for (var i=0;i<document.forms[formid].elements.length;i++) {      return <<ENDJS;
             if (document.forms[formid].elements[i].name == item) {  <script type="text/javascript" language="JavaScript">
                 return i;  // <![CDATA[
   
   if (!Array.prototype.indexOf) {
       Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
           "use strict";
           if (this === void 0 || this === null) {
               throw new TypeError();
           }
           var t = Object(this);
           var len = t.length >>> 0;
           if (len === 0) {
               return -1;
           }
           var n = 0;
           if (arguments.length > 0) {
               n = Number(arguments[1]);
               if (n !== n) { // shortcut for verifying if it's NaN
                   n = 0;
               } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) {
                   n = (n > 0 || -1) * Math.floor(Math.abs(n));
               }
           }
           if (n >= len) {
               return -1;
           }
           var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
           for (; k < len; k++) {
               if (k in t && t[k] === searchElement) {
                   return k;
             }              }
         }          }
         return -1;          return -1;
     }      }
 ENDSTDBRW  }
     if ($sec_element ne '') {  
         $output .= &setsec_javascript($sec_element,$formname);  
     }  
     $output .= '  
 // ]]>  // ]]>
 </script>';  </script>
     return $output;  
   ENDJS
   
   }
   
   sub userbrowser_javascript {
       my $id_functions = &javascript_index_functions();
       return <<"ENDUSERBRW";
   
   function openuserbrowser(formname,uname,udom,ulast,ufirst,uemail,hideudom,crsdom,caller) {
       var url = '/adm/pickuser?';
       var userdom = getDomainFromSelectbox(formname,udom);
       if (userdom != null) {
          if (userdom != '') {
              url += 'srchdom='+userdom+'&';
          }
       }
       url += 'form=' + formname + '&unameelement='+uname+
                                   '&udomelement='+udom+
                                   '&ulastelement='+ulast+
                                   '&ufirstelement='+ufirst+
                                   '&uemailelement='+uemail+
                                   '&hideudomelement='+hideudom+
                                   '&coursedom='+crsdom;
       if ((caller != null) && (caller != undefined)) {
           url += '&caller='+caller;
       }
       var title = 'User_Browser';
       var options = 'scrollbars=1,resizable=1,menubar=0';
       options += ',width=700,height=600';
       var stdeditbrowser = open(url,title,options,'1');
       stdeditbrowser.focus();
   }
   
   function fix_domain (formname,udom,origdom,uname) {
       var formid = getFormIdByName(formname);
       if (formid > -1) {
           var unameid = getIndexByName(formid,uname);
           var domid = getIndexByName(formid,udom);
           var hidedomid = getIndexByName(formid,origdom);
           if (hidedomid > -1) {
               var fixeddom = document.forms[formid].elements[hidedomid].value;
               var unameval = document.forms[formid].elements[unameid].value;
               if ((fixeddom != '') && (fixeddom != undefined) && (fixeddom != null) && (unameval != '') && (unameval != undefined) && (unameval != null)) {
                   if (domid > -1) {
                       var slct = document.forms[formid].elements[domid];
                       if (slct.type == 'select-one') {
                           var i;
                           for (i=0;i<slct.length;i++) {
                               if (slct.options[i].value==fixeddom) { slct.selectedIndex=i; }
                           }
                       }
                       if (slct.type == 'hidden') {
                           slct.value = fixeddom;
                       }
                   }
               }
           }
       }
       return;
   }
   
   $id_functions
   ENDUSERBRW
 }  }
   
 sub setsec_javascript {  sub setsec_javascript {
     my ($sec_element,$formname) = @_;      my ($sec_element,$formname,$role_element) = @_;
       my (@courserolenames,@communityrolenames,$rolestr,$courserolestr,
           $communityrolestr);
       if ($role_element ne '') {
           my @allroles = ('st','ta','ep','in','ad');
           foreach my $crstype ('Course','Community') {
               if ($crstype eq 'Community') {
                   foreach my $role (@allroles) {
                       push(@communityrolenames,&Apache::lonnet::plaintext($role,$crstype));
                   }
                   push(@communityrolenames,&Apache::lonnet::plaintext('co'));
               } else {
                   foreach my $role (@allroles) {
                       push(@courserolenames,&Apache::lonnet::plaintext($role,$crstype));
                   }
                   push(@courserolenames,&Apache::lonnet::plaintext('cc'));
               }
           }
           $rolestr = '"'.join('","',@allroles).'"';
           $courserolestr = '"'.join('","',@courserolenames).'"';
           $communityrolestr = '"'.join('","',@communityrolenames).'"';
       }
     my $setsections = qq|      my $setsections = qq|
 function setSect(sectionlist) {  function setSect(sectionlist) {
     var sectionsArray = new Array();      var sectionsArray = new Array();
Line 613  function setSect(sectionlist) { Line 794  function setSect(sectionlist) {
         }          }
     }      }
 }  }
   
   function setRole(crstype) {
   |;
       if ($role_element eq '') {
           $setsections .= '    return;
   }
   ';
       } else {
           $setsections .= qq|
       var elementLength = document.$formname.$role_element.length;
       var allroles = Array($rolestr);
       var courserolenames = Array($courserolestr);
       var communityrolenames = Array($communityrolestr);
       if (elementLength != undefined) {
           if (document.$formname.$role_element.options[5].value == 'cc') {
               if (crstype == 'Course') {
                   return;
               } else {
                   allroles[5] = 'co';
                   for (var i=0; i<6; i++) {
                       document.$formname.$role_element.options[i].value = allroles[i];
                       document.$formname.$role_element.options[i].text = communityrolenames[i];
                   }
               }
           } else {
               if (crstype == 'Community') {
                   return;
               } else {
                   allroles[5] = 'cc';
                   for (var i=0; i<6; i++) {
                       document.$formname.$role_element.options[i].value = allroles[i];
                       document.$formname.$role_element.options[i].text = courserolenames[i];
                   }
               }
           }
       }
       return;
   }
 |;  |;
       }
     return $setsections;      return $setsections;
 }  }
   
   
 sub selectcourse_link {  sub selectcourse_link {
    my ($form,$unameele,$udomele,$desc,$extra_element,$multflag,$selecttype)=@_;     my ($form,$unameele,$udomele,$desc,$extra_element,$multflag,$selecttype,
          $typeelement) = @_;
      my $type = $selecttype;
      my $linktext = &mt('Select Course');
      if ($selecttype eq 'Community') {
          $linktext = &mt('Select Community');
      } elsif ($selecttype eq 'Course/Community') {
          $linktext = &mt('Select Course/Community');
          $type = '';
      } elsif ($selecttype eq 'Select') {
          $linktext = &mt('Select');
          $type = '';
      }
    return '<span class="LC_nobreak">'     return '<span class="LC_nobreak">'
          ."<a href='"           ."<a href='"
          .'javascript:opencrsbrowser("'.$form.'","'.$unameele           .'javascript:opencrsbrowser("'.$form.'","'.$unameele
          .'","'.$udomele.'","'.$desc.'","'.$extra_element           .'","'.$udomele.'","'.$desc.'","'.$extra_element
          .'","'.$multflag.'","'.$selecttype.'");'           .'","'.$multflag.'","'.$type.'","'.$typeelement.'");'
          ."'>".&mt('Select Course').'</a>'           ."'>".$linktext.'</a>'
          .'</span>';           .'</span>';
 }  }
   
Line 635  sub selectauthor_link { Line 866  sub selectauthor_link {
           &mt('Select Author').'</a>';            &mt('Select Author').'</a>';
 }  }
   
   sub selectuser_link {
       my ($form,$unameelem,$domelem,$lastelem,$firstelem,$emailelem,$hdomelem,
           $coursedom,$linktext,$caller) = @_;
       return '<a href="javascript:openuserbrowser('."'$form','$unameelem','$domelem',".
              "'$lastelem','$firstelem','$emailelem','$hdomelem','$coursedom','$caller'".
              ');">'.$linktext.'</a>';
   }
   
 sub check_uncheck_jscript {  sub check_uncheck_jscript {
     my $jscript = <<"ENDSCRT";      my $jscript = <<"ENDSCRT";
 function checkAll(field) {  function checkAll(field) {
Line 745  sub select_language { Line 984  sub select_language {
             $langchoices{$code} = &plainlanguagedescription($id);              $langchoices{$code} = &plainlanguagedescription($id);
         }          }
     }      }
     return &select_form($selected,$name,%langchoices);      return &select_form($selected,$name,\%langchoices);
 }  }
   
 =pod  =pod
Line 917  END Line 1156  END
   
 =pod  =pod
   
 =item * &help_open_topic($topic,$text,$stayOnPage,$width,$height)  =item * &help_open_topic($topic,$text,$stayOnPage,$width,$height,$imgid)
   
 Returns a string corresponding to an HTML link to the given help  Returns a string corresponding to an HTML link to the given help
 $topic, where $topic corresponds to the name of a .tex file in  $topic, where $topic corresponds to the name of a .tex file in
Line 935  a new window using Javascript. (Default Line 1174  a new window using Javascript. (Default
   
 $width and $height are optional numerical parameters that will  $width and $height are optional numerical parameters that will
 override the width and height of the popped up window, which may  override the width and height of the popped up window, which may
 be useful for certain help topics with big pictures included.   be useful for certain help topics with big pictures included.
   
   $imgid is the id of the img tag used for the help icon. This may be
   used in a javascript call to switch the image src.  See 
   lonhtmlcommon::htmlareaselectactive() for an example.
   
 =cut  =cut
   
 sub help_open_topic {  sub help_open_topic {
     my ($topic, $text, $stayOnPage, $width, $height) = @_;      my ($topic, $text, $stayOnPage, $width, $height, $imgid) = @_;
     $text = "" if (not defined $text);      $text = "" if (not defined $text);
     $stayOnPage = 0 if (not defined $stayOnPage);      $stayOnPage = 0 if (not defined $stayOnPage);
     $width = 350 if (not defined $width);      $width = 350 if (not defined $width);
Line 969  sub help_open_topic { Line 1212  sub help_open_topic {
     # (Always) Add the graphic      # (Always) Add the graphic
     my $title = &mt('Online Help');      my $title = &mt('Online Help');
     my $helpicon=&lonhttpdurl("/adm/help/help.png");      my $helpicon=&lonhttpdurl("/adm/help/help.png");
       if ($imgid ne '') {
           $imgid = ' id="'.$imgid.'"';
       }
     $template.=' <a target="_top" href="'.$link.'" title="'.$title.'">'      $template.=' <a target="_top" href="'.$link.'" title="'.$title.'">'
               .'<img src="'.$helpicon.'" border="0"'                .'<img src="'.$helpicon.'" border="0"'
               .' alt="'.&mt('Help: [_1]',$topic).'"'                .' alt="'.&mt('Help: [_1]',$topic).'"'
               .' title="'.$title.'"'                 .' title="'.$title.'" style="vertical-align:middle;"'.$imgid 
               .' /></a>';                .' /></a>';
     if ($text ne "") {      if ($text ne "") {
         $template.='</span>';          $template.='</span>';
Line 1015  sub general_help { Line 1261  sub general_help {
     my $helptopic='Student_Intro';      my $helptopic='Student_Intro';
     if ($env{'request.role'}=~/^(ca|au)/) {      if ($env{'request.role'}=~/^(ca|au)/) {
  $helptopic='Authoring_Intro';   $helptopic='Authoring_Intro';
     } elsif ($env{'request.role'}=~/^cc/) {      } elsif ($env{'request.role'}=~/^(cc|co)/) {
  $helptopic='Course_Coordination_Intro';   $helptopic='Course_Coordination_Intro';
     } elsif ($env{'request.role'}=~/^dc/) {      } elsif ($env{'request.role'}=~/^dc/) {
         $helptopic='Domain_Coordination_Intro';          $helptopic='Domain_Coordination_Intro';
Line 1047  ENDOUTPUT Line 1293  ENDOUTPUT
 sub help_open_menu {  sub help_open_menu {
     my ($topic,$component_help,$faq,$bug,$stayOnPage,$width,$height,$text)       my ($topic,$component_help,$faq,$bug,$stayOnPage,$width,$height,$text) 
  = @_;       = @_;    
     $stayOnPage = 0 if (not defined $stayOnPage);      $stayOnPage = 1;
     # only use pop-up help (stayOnPage == 0)  
     # if environment.remote is on (using remote control UI)  
     if ($env{'environment.remote'} eq 'off' ) {  
         $stayOnPage=1;  
     }  
     my $output;      my $output;
     if ($component_help) {      if ($component_help) {
  if (!$text) {   if (!$text) {
Line 1073  sub help_open_menu { Line 1314  sub help_open_menu {
 sub top_nav_help {  sub top_nav_help {
     my ($text) = @_;      my ($text) = @_;
     $text = &mt($text);      $text = &mt($text);
     my $stay_on_page =       my $stay_on_page = 1;
  ($env{'environment.remote'} eq 'off' );  
     my $link = ($stay_on_page) ? "javascript:helpMenu('display')"      my $link = ($stay_on_page) ? "javascript:helpMenu('display')"
                      : "javascript:helpMenu('open')";                       : "javascript:helpMenu('open')";
     my $banner_link = &update_help_link(undef,undef,undef,undef,$stay_on_page);      my $banner_link = &update_help_link(undef,undef,undef,undef,$stay_on_page);
Line 1089  END Line 1330  END
   
 sub help_menu_js {  sub help_menu_js {
     my ($text) = @_;      my ($text) = @_;
       my $stayOnPage = 1;
     my $stayOnPage =   
  ($env{'environment.remote'} eq 'off' );  
   
     my $width = 620;      my $width = 620;
     my $height = 600;      my $height = 600;
     my $helptopic=&general_help();      my $helptopic=&general_help();
Line 1111  sub help_menu_js { Line 1349  sub help_menu_js {
   
     my $template .= <<"ENDTEMPLATE";      my $template .= <<"ENDTEMPLATE";
 <script type="text/javascript">  <script type="text/javascript">
 // <!-- BEGIN LON-CAPA Internal  
 // <![CDATA[  // <![CDATA[
   // <!-- BEGIN LON-CAPA Internal
 var banner_link = '';  var banner_link = '';
 function helpMenu(target) {  function helpMenu(target) {
     var caller = this;      var caller = this;
Line 1137  function writeHelp(caller) { Line 1375  function writeHelp(caller) {
     caller.document.close()      caller.document.close()
     caller.focus()      caller.focus()
 }  }
 // ]]>  
 // END LON-CAPA Internal -->  // END LON-CAPA Internal -->
   // ]]>
 </script>  </script>
 ENDTEMPLATE  ENDTEMPLATE
     return $template;      return $template;
Line 1149  sub help_open_bug { Line 1387  sub help_open_bug {
     unless ($env{'user.adv'}) { return ''; }      unless ($env{'user.adv'}) { return ''; }
     unless ($Apache::lonnet::perlvar{'BugzillaHost'}) { return ''; }      unless ($Apache::lonnet::perlvar{'BugzillaHost'}) { return ''; }
     $text = "" if (not defined $text);      $text = "" if (not defined $text);
     $stayOnPage = 0 if (not defined $stayOnPage);  
     if ($env{'environment.remote'} eq 'off' ) {  
  $stayOnPage=1;   $stayOnPage=1;
     }  
     $width = 600 if (not defined $width);      $width = 600 if (not defined $width);
     $height = 600 if (not defined $height);      $height = 600 if (not defined $height);
   
Line 1193  sub help_open_faq { Line 1428  sub help_open_faq {
     unless ($env{'user.adv'}) { return ''; }      unless ($env{'user.adv'}) { return ''; }
     unless ($Apache::lonnet::perlvar{'FAQHost'}) { return ''; }      unless ($Apache::lonnet::perlvar{'FAQHost'}) { return ''; }
     $text = "" if (not defined $text);      $text = "" if (not defined $text);
     $stayOnPage = 0 if (not defined $stayOnPage);  
     if ($env{'environment.remote'} eq 'off' ) {  
  $stayOnPage=1;   $stayOnPage=1;
     }  
     $width = 350 if (not defined $width);      $width = 350 if (not defined $width);
     $height = 400 if (not defined $height);      $height = 400 if (not defined $height);
   
Line 1564  sub create_workbook { Line 1796  sub create_workbook {
     my $workbook  = Spreadsheet::WriteExcel->new('/home/httpd'.$filename);      my $workbook  = Spreadsheet::WriteExcel->new('/home/httpd'.$filename);
     if (! defined($workbook)) {      if (! defined($workbook)) {
         $r->log_error("Error creating excel spreadsheet $filename: $!");          $r->log_error("Error creating excel spreadsheet $filename: $!");
         $r->print('<p>'.&mt("Unable to create new Excel file.  ".          $r->print(
                             "This error has been logged.  ".              '<p class="LC_error">'
                             "Please alert your LON-CAPA administrator").             .&mt('Problems occurred in creating the new Excel file.')
                   '</p>');             .' '.&mt('This error has been logged.')
              .' '.&mt('Please alert your LON-CAPA administrator.')
              .'</p>'
           );
         return (undef);          return (undef);
     }      }
     #      #
     $workbook->set_tempdir('/home/httpd/perl/tmp');      $workbook->set_tempdir(LONCAPA::tempdir());
     #      #
     my $format = &Apache::loncommon::define_excel_formats($workbook);      my $format = &Apache::loncommon::define_excel_formats($workbook);
     return ($workbook,$filename,$format);      return ($workbook,$filename,$format);
Line 1607  sub create_text_file { Line 1842  sub create_text_file {
     $fh = Apache::File->new('>/home/httpd'.$filename);      $fh = Apache::File->new('>/home/httpd'.$filename);
     if (! defined($fh)) {      if (! defined($fh)) {
         $r->log_error("Couldn't open $filename for output $!");          $r->log_error("Couldn't open $filename for output $!");
         $r->print(&mt('Problems occurred in creating the output file. '          $r->print(
                      .'This error has been logged. '              '<p class="LC_error">'
                      .'Please alert your LON-CAPA administrator.'));             .&mt('Problems occurred in creating the output file.')
              .' '.&mt('This error has been logged.')
              .' '.&mt('Please alert your LON-CAPA administrator.')
              .'</p>'
           );
     }      }
     return ($fh,$filename)      return ($fh,$filename)
 }  }
Line 1638  sub domain_select { Line 1877  sub domain_select {
  return &multiple_select_form($name,$value,4,\%domains);   return &multiple_select_form($name,$value,4,\%domains);
     } else {      } else {
  $domains{'select_form_order'} = [sort {lc($a) cmp lc($b) } (keys(%domains))];   $domains{'select_form_order'} = [sort {lc($a) cmp lc($b) } (keys(%domains))];
  return &select_form($name,$value,%domains);   return &select_form($name,$value,\%domains);
     }      }
 }  }
   
Line 1700  sub multiple_select_form { Line 1939  sub multiple_select_form {
   
 =pod  =pod
   
 =item * &select_form($defdom,$name,%hash)  =item * &select_form($defdom,$name,$hashref,$onchange)
   
 Returns a string containing a <select name='$name' size='1'> form to   Returns a string containing a <select name='$name' size='1'> form to 
 allow a user to select options from a hash option_name => displayed text.    allow a user to select options from a ref to a hash containing:
   option_name => displayed text. An optional $onchange can include
   a javascript onchange item, e.g., onchange="this.form.submit();"  
   
 See lonrights.pm for an example invocation and use.  See lonrights.pm for an example invocation and use.
   
 =cut  =cut
   
 #-------------------------------------------  #-------------------------------------------
 sub select_form {  sub select_form {
     my ($def,$name,%hash) = @_;      my ($def,$name,$hashref,$onchange) = @_;
     my $selectform = "<select name=\"$name\" size=\"1\">\n";      return unless (ref($hashref) eq 'HASH');
       if ($onchange) {
           $onchange = ' onchange="'.$onchange.'"';
       }
       my $selectform = "<select name=\"$name\" size=\"1\"$onchange>\n";
     my @keys;      my @keys;
     if (exists($hash{'select_form_order'})) {      if (exists($hashref->{'select_form_order'})) {
  @keys=@{$hash{'select_form_order'}};   @keys=@{$hashref->{'select_form_order'}};
     } else {      } else {
  @keys=sort(keys(%hash));   @keys=sort(keys(%{$hashref}));
     }      }
     foreach my $key (@keys) {      foreach my $key (@keys) {
         $selectform.=          $selectform.=
     '<option value="'.&HTML::Entities::encode($key,'"<>&').'" '.      '<option value="'.&HTML::Entities::encode($key,'"<>&').'" '.
             ($key eq $def ? 'selected="selected" ' : '').              ($key eq $def ? 'selected="selected" ' : '').
                 ">".&mt($hash{$key})."</option>\n";                  ">".$hashref->{$key}."</option>\n";
     }      }
     $selectform.="</select>";      $selectform.="</select>";
     return $selectform;      return $selectform;
Line 1740  sub display_filter { Line 1986  sub display_filter {
            &mt('Filter [_1]',             &mt('Filter [_1]',
    &select_form($env{'form.displayfilter'},     &select_form($env{'form.displayfilter'},
  'displayfilter',   'displayfilter',
  ('currentfolder' => 'Current folder/page',   {'currentfolder' => 'Current folder/page',
  'containing' => 'Containing phrase',   'containing' => 'Containing phrase',
  'none' => 'None'))).   'none' => 'None'})).
  '<input type="text" name="containingphrase" size="30" value="'.&HTML::Entities::encode($env{'form.containingphrase'}).'" /></span>';   '<input type="text" name="containingphrase" size="30" value="'.&HTML::Entities::encode($env{'form.containingphrase'}).'" /></span>';
 }  }
   
Line 1787  sub select_level_form { Line 2033  sub select_level_form {
   
 =pod  =pod
   
 =item * &select_dom_form($defdom,$name,$includeempty,$showdomdesc,$autosubmit)  =item * &select_dom_form($defdom,$name,$includeempty,$showdomdesc,$onchange,$incdoms)
   
 Returns a string containing a <select name='$name' size='1'> form to   Returns a string containing a <select name='$name' size='1'> form to 
 allow a user to select the domain to preform an operation in.    allow a user to select the domain to preform an operation in.  
Line 1798  selected"); Line 2044  selected");
   
 If the $showdomdesc flag is set, the domain name is followed by the domain description.  If the $showdomdesc flag is set, the domain name is followed by the domain description.
   
 If the $autosubmit flag is set, the form containing the domain selector will be auto-submitted by an onchange action.    The optional $onchange argument specifies what should occur if the domain selector is changed, e.g., 'this.form.submit()' if the form is to be automatically submitted.
   
   The optional $incdoms is a reference to an array of domains which will be the only available options. 
   
 =cut  =cut
   
 #-------------------------------------------  #-------------------------------------------
 sub select_dom_form {  sub select_dom_form {
     my ($defdom,$name,$includeempty,$showdomdesc,$autosubmit) = @_;      my ($defdom,$name,$includeempty,$showdomdesc,$onchange,$incdoms) = @_;
     my $onchange;      if ($onchange) {
     if ($autosubmit) {          $onchange = ' onchange="'.$onchange.'"';
         $onchange = ' onchange="this.form.submit()"';      }
       my @domains;
       if (ref($incdoms) eq 'ARRAY') {
           @domains = sort {lc($a) cmp lc($b)} (@{$incdoms});
       } else {
           @domains = sort {lc($a) cmp lc($b)} (&Apache::lonnet::all_domains());
     }      }
     my @domains = sort {lc($a) cmp lc($b)} (&Apache::lonnet::all_domains());  
     if ($includeempty) { @domains=('',@domains); }      if ($includeempty) { @domains=('',@domains); }
     my $selectdomain = "<select name=\"$name\" size=\"1\"$onchange>\n";      my $selectdomain = "<select name=\"$name\" size=\"1\"$onchange>\n";
     foreach my $dom (@domains) {      foreach my $dom (@domains) {
Line 2106  function changed_text(choice,currentform Line 2358  function changed_text(choice,currentform
 }  }
   
 function set_auth_radio_buttons(newvalue,currentform) {  function set_auth_radio_buttons(newvalue,currentform) {
       var numauthchoices = currentform.login.length;
       if (typeof numauthchoices  == "undefined") {
           return;
       } 
     var i=0;      var i=0;
     while (i < currentform.login.length) {      while (i < numauthchoices) {
         if (currentform.login[i].value == newvalue) { break; }          if (currentform.login[i].value == newvalue) { break; }
         i++;          i++;
     }      }
     if (i == currentform.login.length) {      if (i == numauthchoices) {
         return;          return;
     }      }
     current.radiovalue = newvalue;      current.radiovalue = newvalue;
Line 2862  sub messagewrapper { Line 3118  sub messagewrapper {
 sub noteswrapper {  sub noteswrapper {
     my ($link,$un,$do)=@_;      my ($link,$un,$do)=@_;
     return       return 
 "<a href='/adm/email?recordftf=retrieve&recname=$un&recdom=$do'>$link</a>";  "<a href='/adm/email?recordftf=retrieve&amp;recname=$un&amp;recdom=$do'>$link</a>";
 }  }
   
 # ------------------------------------------------------------- Aboutme Wrapper  # ------------------------------------------------------------- Aboutme Wrapper
Line 2872  sub aboutmewrapper { Line 3128  sub aboutmewrapper {
     if (!defined($username)  && !defined($domain)) {      if (!defined($username)  && !defined($domain)) {
         return;          return;
     }      }
     return '<a href="/adm/'.$domain.'/'.$username.'/aboutme"'.      return '<a href="/adm/'.$domain.'/'.$username.'/aboutme?forcestudent=1"'.
  ($target?' target="$target"':'').' title="'.&mt("View this user's personal information page").'">'.$link.'</a>';   ($target?' target="$target"':'').' title="'.&mt("View this user's personal information page").'">'.$link.'</a>';
 }  }
   
Line 2886  sub syllabuswrapper { Line 3142  sub syllabuswrapper {
 # -----------------------------------------------------------------------------  # -----------------------------------------------------------------------------
   
 sub track_student_link {  sub track_student_link {
     my ($linktext,$sname,$sdom,$target,$start) = @_;      my ($linktext,$sname,$sdom,$target,$start,$only_body) = @_;
     my $link ="/adm/trackstudent?";      my $link ="/adm/trackstudent?";
     my $title = 'View recent activity';      my $title = 'View recent activity';
     if (defined($sname) && $sname !~ /^\s*$/ &&      if (defined($sname) && $sname !~ /^\s*$/ &&
Line 2900  sub track_student_link { Line 3156  sub track_student_link {
         $target = '';          $target = '';
     }      }
     if ($start) { $link.='&amp;start='.$start; }      if ($start) { $link.='&amp;start='.$start; }
       if ($only_body) { $link .= '&amp;only_body=1'; }
     $title = &mt($title);      $title = &mt($title);
     $linktext = &mt($linktext);      $linktext = &mt($linktext);
     return qq{<a href="$link" title="$title" $target>$linktext</a>}.      return qq{<a href="$link" title="$title" $target>$linktext</a>}.
Line 3077  sub filemimetype { Line 3334  sub filemimetype {
 sub filecategoryselect {  sub filecategoryselect {
     my ($name,$value)=@_;      my ($name,$value)=@_;
     return &select_form($value,$name,      return &select_form($value,$name,
  '' => &mt('Any category'),                          {'' => &mt('Any category'), map { $_,$_ } sort(keys(%category_extensions))});
  map { $_,$_ } sort(keys(%category_extensions)));  
 }  }
   
 =pod  =pod
Line 3243  sub get_previous_attempt { Line 3499  sub get_previous_attempt {
       }        }
       $prevattempts=&start_data_table().&start_data_table_header_row();        $prevattempts=&start_data_table().&start_data_table_header_row();
       $prevattempts.='<th>'.&mt('History').'</th>';        $prevattempts.='<th>'.&mt('History').'</th>';
         my (%typeparts,%lasthidden);
         my $showsurv=&Apache::lonnet::allowed('vas',$env{'request.course.id'});
       foreach my $key (sort(keys(%lasthash))) {        foreach my $key (sort(keys(%lasthash))) {
  my ($ign,@parts) = split(/\./,$key);   my ($ign,@parts) = split(/\./,$key);
  if ($#parts > 0) {   if ($#parts > 0) {
   my $data=$parts[-1];    my $data=$parts[-1];
             next if ($data eq 'foilorder');
   pop(@parts);    pop(@parts);
   $prevattempts.='<th>'.&mt('Part ').join('.',@parts).'<br />'.$data.'&nbsp;</th>';            $prevattempts.='<th>'.&mt('Part ').join('.',@parts).'<br />'.$data.'&nbsp;</th>';
             if ($data eq 'type') {
                 unless ($showsurv) {
                     my $id = join(',',@parts);
                     $typeparts{$ign.'.'.$id} = $lasthash{$key};
                     if (($lasthash{$key} eq 'anonsurvey') || ($lasthash{$key} eq 'anonsurveycred')) {
                         $lasthidden{$ign.'.'.$id} = 1;
                     }
                 }
             } 
  } else {   } else {
   if ($#parts == 0) {    if ($#parts == 0) {
     $prevattempts.='<th>'.$parts[0].'</th>';      $prevattempts.='<th>'.$parts[0].'</th>';
Line 3260  sub get_previous_attempt { Line 3528  sub get_previous_attempt {
       $prevattempts.=&end_data_table_header_row();        $prevattempts.=&end_data_table_header_row();
       if ($getattempt eq '') {        if ($getattempt eq '') {
  for ($version=1;$version<=$returnhash{'version'};$version++) {   for ($version=1;$version<=$returnhash{'version'};$version++) {
   $prevattempts.=&start_data_table_row().              my @hidden;
       '<td>'.&mt('Transaction [_1]',$version).'</td>';              if (%typeparts) {
     foreach my $key (sort(keys(%lasthash))) {                  foreach my $id (keys(%typeparts)) {
  my $value = &format_previous_attempt_value($key,                      if (($returnhash{$version.':'.$id.'.type'} eq 'anonsurvey') || ($returnhash{$version.':'.$id.'.type'} eq 'anonsurveycred')) {
    $returnhash{$version.':'.$key});                          push(@hidden,$id);
  $prevattempts.='<td>'.$value.'&nbsp;</td>';                         }
     }                  }
   $prevattempts.=&end_data_table_row();              }
               $prevattempts.=&start_data_table_row().
                              '<td>'.&mt('Transaction [_1]',$version).'</td>';
               if (@hidden) {
                   foreach my $key (sort(keys(%lasthash))) {
                       next if ($key =~ /\.foilorder$/);
                       my $hide;
                       foreach my $id (@hidden) {
                           if ($key =~ /^\Q$id\E/) {
                               $hide = 1;
                               last;
                           }
                       }
                       if ($hide) {
                           my ($id,$data) = ($key =~ /^(.+)\.([^.]+)$/);
                           if (($data eq 'award') || ($data eq 'awarddetail')) {
                               my $value = &format_previous_attempt_value($key,
                                                $returnhash{$version.':'.$key});
                               $prevattempts.='<td>'.$value.'&nbsp;</td>';
                           } else {
                               $prevattempts.='<td>&nbsp;</td>';
                           }
                       } else {
                           if ($key =~ /\./) {
                               my $value = &format_previous_attempt_value($key,
                                                 $returnhash{$version.':'.$key});
                               $prevattempts.='<td>'.$value.'&nbsp;</td>';
                           } else {
                               $prevattempts.='<td>&nbsp;</td>';
                           }
                       }
                   }
               } else {
           foreach my $key (sort(keys(%lasthash))) {
                       next if ($key =~ /\.foilorder$/);
       my $value = &format_previous_attempt_value($key,
               $returnhash{$version.':'.$key});
       $prevattempts.='<td>'.$value.'&nbsp;</td>';
           }
               }
       $prevattempts.=&end_data_table_row();
  }   }
       }        }
         my @currhidden = keys(%lasthidden);
       $prevattempts.=&start_data_table_row().'<td>'.&mt('Current').'</td>';        $prevattempts.=&start_data_table_row().'<td>'.&mt('Current').'</td>';
       foreach my $key (sort(keys(%lasthash))) {        foreach my $key (sort(keys(%lasthash))) {
  my $value = &format_previous_attempt_value($key,$lasthash{$key});            next if ($key =~ /\.foilorder$/);
  if ($key =~/$regexp$/ && (defined &$gradesub)) {$value = &$gradesub($value)}            if (%typeparts) {
  $prevattempts.='<td>'.$value.'&nbsp;</td>';                my $hidden;
                 foreach my $id (@currhidden) {
                     if ($key =~ /^\Q$id\E/) {
                         $hidden = 1;
                         last;
                     }
                 }
                 if ($hidden) {
                     my ($id,$data) = ($key =~ /^(.+)\.([^.]+)$/);
                     if (($data eq 'award') || ($data eq 'awarddetail')) {
                         my $value = &format_previous_attempt_value($key,$lasthash{$key});
                         if ($key =~/$regexp$/ && (defined &$gradesub)) {
                             $value = &$gradesub($value);
                         }
                         $prevattempts.='<td>'.$value.'&nbsp;</td>';
                     } else {
                         $prevattempts.='<td>&nbsp;</td>';
                     }
                 } else {
                     my $value = &format_previous_attempt_value($key,$lasthash{$key});
                     if ($key =~/$regexp$/ && (defined &$gradesub)) {
                         $value = &$gradesub($value);
                     }
                     $prevattempts.='<td>'.$value.'&nbsp;</td>';
                 }
             } else {
         my $value = &format_previous_attempt_value($key,$lasthash{$key});
         if ($key =~/$regexp$/ && (defined &$gradesub)) {
                     $value = &$gradesub($value);
                 }
         $prevattempts.='<td>'.$value.'&nbsp;</td>';
             }
       }        }
       $prevattempts.= &end_data_table_row().&end_data_table();        $prevattempts.= &end_data_table_row().&end_data_table();
     } else {      } else {
Line 3293  sub get_previous_attempt { Line 3633  sub get_previous_attempt {
   
 sub format_previous_attempt_value {  sub format_previous_attempt_value {
     my ($key,$value) = @_;      my ($key,$value) = @_;
     if ($key =~ /timestamp/) {      if (($key =~ /timestamp/) || ($key=~/duedate/)) {
  $value = &Apache::lonlocal::locallocaltime($value);   $value = &Apache::lonlocal::locallocaltime($value);
     } elsif (ref($value) eq 'ARRAY') {      } elsif (ref($value) eq 'ARRAY') {
  $value = '('.join(', ', @{ $value }).')';   $value = '('.join(', ', @{ $value }).')';
       } elsif ($key =~ /answerstring$/) {
           my %answers = &Apache::lonnet::str2hash($value);
           my @anskeys = sort(keys(%answers));
           if (@anskeys == 1) {
               my $answer = $answers{$anskeys[0]};
               if ($answer =~ m{\0}) {
                   $answer =~ s{\0}{,}g;
               }
               my $tag_internal_answer_name = 'INTERNAL';
               if ($anskeys[0] eq $tag_internal_answer_name) {
                   $value = $answer; 
               } else {
                   $value = $anskeys[0].'='.$answer;
               }
           } else {
               foreach my $ans (@anskeys) {
                   my $answer = $answers{$ans};
                   if ($answer =~ m{\0}) {
                       $answer =~ s{\0}{,}g;
                   }
                   $value .=  $ans.'='.$answer.'<br />';;
               } 
           }
     } else {      } else {
  $value = &unescape($value);   $value = &unescape($value);
     }      }
Line 3447  sub submlink { Line 3810  sub submlink {
     }      }
     if (!$symb) { $symb=&Apache::lonnet::symbread(); }      if (!$symb) { $symb=&Apache::lonnet::symbread(); }
     $symb=&escape($symb);      $symb=&escape($symb);
     if ($target) { $target="target=\"$target\""; }      if ($target) { $target=" target=\"$target\""; }
     return '<a href="/adm/grades?&command=submission&'.      return
  'symb='.$symb.'&student='.$uname.          '<a href="/adm/grades?command=submission'.
  '&userdom='.$udom.'" '.$target.'>'.$text.'</a>';          '&amp;symb='.$symb.
           '&amp;student='.$uname.
           '&amp;userdom='.$udom.'"'.
           $target.'>'.$text.'</a>';
 }  }
 ##############################################  ##############################################
   
Line 3572  sub findallcourses { Line 3938  sub findallcourses {
         $udom = $env{'user.domain'};          $udom = $env{'user.domain'};
     }      }
     if (($uname ne $env{'user.name'}) || ($udom ne $env{'user.domain'})) {      if (($uname ne $env{'user.name'}) || ($udom ne $env{'user.domain'})) {
         my %roleshash = &Apache::lonnet::dump('roles',$udom,$uname);          my $extra = &Apache::lonnet::freeze_escape({'skipcheck' => 1});
           my %roleshash = &Apache::lonnet::dump('roles',$udom,$uname,'.',undef,
                                                 $extra);
         if (!%roles) {          if (!%roles) {
             %roles = (              %roles = (
                        cc => 1,                         cc => 1,
                          co => 1,
                        in => 1,                         in => 1,
                        ep => 1,                         ep => 1,
                        ta => 1,                         ta => 1,
Line 3831  sub parse_block_record { Line 4200  sub parse_block_record {
     return ($setuname,$setudom,$title,$blocks);      return ($setuname,$setudom,$title,$blocks);
 }  }
   
 sub build_block_table {  
     my ($startblock,$endblock,$setters) = @_;  
     my %lt = &Apache::lonlocal::texthash(  
         'cacb' => 'Currently active communication blocks',  
         'cour' => 'Course',  
         'dura' => 'Duration',  
         'blse' => 'Block set by'  
     );  
     my $output;  
     $output = '<br />'.$lt{'cacb'}.':<br />';  
     $output .= &start_data_table();  
     $output .= '  
 <tr>  
  <th>'.$lt{'cour'}.'</th>  
  <th>'.$lt{'dura'}.'</th>  
  <th>'.$lt{'blse'}.'</th>  
 </tr>  
 ';  
     foreach my $course (keys(%{$setters})) {  
         my %courseinfo=&Apache::lonnet::coursedescription($course);  
         for (my $i=0; $i<@{$$setters{$course}{staff}}; $i++) {  
             my ($uname,$udom) = @{$$setters{$course}{staff}[$i]};  
             my $fullname = &plainname($uname,$udom);  
             if (defined($env{'user.name'}) && defined($env{'user.domain'})  
                 && $env{'user.name'} ne 'public'   
                 && $env{'user.domain'} ne 'public') {  
                 $fullname = &aboutmewrapper($fullname,$uname,$udom);  
             }  
             my ($openblock,$closeblock) = @{$$setters{$course}{times}[$i]};  
             $openblock = &Apache::lonlocal::locallocaltime($openblock);  
             $closeblock= &Apache::lonlocal::locallocaltime($closeblock);  
             $output .= &Apache::loncommon::start_data_table_row().  
                        '<td>'.$courseinfo{'description'}.'</td>'.  
                        '<td>'.$openblock.' to '.$closeblock.'</td>'.  
                        '<td>'.$fullname.'</td>'.  
                         &Apache::loncommon::end_data_table_row();  
         }  
     }  
     $output .= &end_data_table();  
 }  
 sub blocking_status {  sub blocking_status {
   my $blocked;  
   my ($activity,$uname,$udom) = @_;    my ($activity,$uname,$udom) = @_;
   my %setters;    my %setters;
   
     # check for active blocking
   my ($startblock,$endblock)=&blockcheck(\%setters,$activity,$uname,$udom);    my ($startblock,$endblock)=&blockcheck(\%setters,$activity,$uname,$udom);
   if ($startblock && $endblock) {  
     $blocked = 1;  
   }  
   if(!wantarray) {  
     return $blocked;  
   }  
   my $output;  
   my $querystring;  
   $querystring = "?activity=$activity";  
   
       $output .= <<"END_MYBLOCK";    my $blocked = $startblock && $endblock ? 1 : 0;
 <script type="text/javascript">  
 // <![CDATA[    # caller just wants to know whether a block is active
     if (!wantarray) { return $blocked; }
   
     # build a link to a popup window containing the details
     my $querystring  = "?activity=$activity";
     # $uname and $udom decide whose portfolio the user is trying to look at
        $querystring .= "&amp;udom=$udom"      if $udom;
        $querystring .= "&amp;uname=$uname"    if $uname;
   
     my $output .= <<'END_MYBLOCK';
     function openWindow(url, wdwName, w, h, toolbar,scrollbar) {      function openWindow(url, wdwName, w, h, toolbar,scrollbar) {
         var options = "width=" + w + ",height=" + h + ",";          var options = "width=" + w + ",height=" + h + ",";
         options += "resizable=yes,scrollbars="+scrollbar+",status=no,";          options += "resizable=yes,scrollbars="+scrollbar+",status=no,";
Line 3896  sub blocking_status { Line 4226  sub blocking_status {
         var newWin = window.open(url, wdwName, options);          var newWin = window.open(url, wdwName, options);
         newWin.focus();          newWin.focus();
     }      }
   
 // ]]>  
 </script>  
 END_MYBLOCK  END_MYBLOCK
   
     $output = Apache::lonhtmlcommon::scripttag($output);
     
   my $popupUrl = "/adm/blockingstatus/$querystring";    my $popupUrl = "/adm/blockingstatus/$querystring";
     my $text = mt('Communication Blocked');
   
   $output .= <<"END_BLOCK";    $output .= <<"END_BLOCK";
 <div class='LC_comblock'>  <div class='LC_comblock'>
   <a onclick='openWindow("$popupUrl","Blocking Table",600,300,"no","no");return false;' href='/adm/blockingstatus/$querystring'>    <a onclick='openWindow("$popupUrl","Blocking Table",600,300,"no","no");return false;' href='/adm/blockingstatus/$querystring'
   <img class='LC_noBorder LC_middle' src='/res/adm/pages/comblock.png' alt='Communication Blocking'/></a>    title='$text'>
   <a onclick='openWindow("$popupUrl","Blocking Table",600,300,"no","no");return false;' href='/adm/blockingstatus/$querystring'>Communication Blocking</a>    <img class='LC_noBorder LC_middle' title='$text' src='/res/adm/pages/comblock.png' alt='$text'/></a>
     <a onclick='openWindow("$popupUrl","Blocking Table",600,300,"no","no");return false;' href='/adm/blockingstatus/$querystring' 
     title='$text'>$text</a>
 </div>  </div>
   
 END_BLOCK  END_BLOCK
Line 3988  sub determinedomain { Line 4322  sub determinedomain {
     my $domain=shift;      my $domain=shift;
     if (! $domain) {      if (! $domain) {
         # Determine domain if we have not been given one          # Determine domain if we have not been given one
         $domain = $Apache::lonnet::perlvar{'lonDefDomain'};          $domain = &Apache::lonnet::default_login_domain();
         if ($env{'user.domain'}) { $domain=$env{'user.domain'}; }          if ($env{'user.domain'}) { $domain=$env{'user.domain'}; }
         if ($env{'request.role.domain'}) {           if ($env{'request.role.domain'}) { 
             $domain=$env{'request.role.domain'};               $domain=$env{'request.role.domain'}; 
Line 4011  sub get_domainconf { Line 4345  sub get_domainconf {
     if (defined($cached)) { return %{$result}; }      if (defined($cached)) { return %{$result}; }
   
     my %domconfig = &Apache::lonnet::get_dom('configuration',      my %domconfig = &Apache::lonnet::get_dom('configuration',
      ['login','rolecolors'],$udom);       ['login','rolecolors','autoenroll'],$udom);
     my (%designhash,%legacy);      my (%designhash,%legacy);
     if (keys(%domconfig) > 0) {      if (keys(%domconfig) > 0) {
         if (ref($domconfig{'login'}) eq 'HASH') {          if (ref($domconfig{'login'}) eq 'HASH') {
             if (keys(%{$domconfig{'login'}})) {              if (keys(%{$domconfig{'login'}})) {
                 foreach my $key (keys(%{$domconfig{'login'}})) {                  foreach my $key (keys(%{$domconfig{'login'}})) {
                     if (ref($domconfig{'login'}{$key}) eq 'HASH') {                      if (ref($domconfig{'login'}{$key}) eq 'HASH') {
                         foreach my $img (keys(%{$domconfig{'login'}{$key}})) {                          if ($key eq 'loginvia') {
                             $designhash{$udom.'.login.'.$key.'_'.$img} =                               if (ref($domconfig{'login'}{'loginvia'}) eq 'HASH') {
                                 $domconfig{'login'}{$key}{$img};                                  foreach my $hostname (keys(%{$domconfig{'login'}{'loginvia'}})) {
                                       if (ref($domconfig{'login'}{'loginvia'}{$hostname}) eq 'HASH') {
                                           if ($domconfig{'login'}{'loginvia'}{$hostname}{'server'}) {
                                               my $server = $domconfig{'login'}{'loginvia'}{$hostname}{'server'};
                                               $designhash{$udom.'.login.loginvia'} = $server;
                                               if ($domconfig{'login'}{'loginvia'}{$hostname}{'serverpath'} eq 'custom') {
   
                                                   $designhash{$udom.'.login.loginvia_'.$hostname} = $server.':'.$domconfig{'login'}{'loginvia'}{$hostname}{'custompath'};
                                               } else {
                                                   $designhash{$udom.'.login.loginvia_'.$hostname} = $server.':'.$domconfig{'login'}{'loginvia'}{$hostname}{'serverpath'};
                                               }
                                               if ($domconfig{'login'}{'loginvia'}{$hostname}{'exempt'}) {
                                                   $designhash{$udom.'.login.loginvia_exempt_'.$hostname} = $domconfig{'login'}{'loginvia'}{$hostname}{'exempt'};
                                               }
                                           }
                                       }
                                   }
                               }
                           } else {
                               foreach my $img (keys(%{$domconfig{'login'}{$key}})) {
                                   $designhash{$udom.'.login.'.$key.'_'.$img} = 
                                       $domconfig{'login'}{$key}{$img};
                               }
                         }                          }
                     } else {                      } else {
                         $designhash{$udom.'.login.'.$key}=$domconfig{'login'}{$key};                          $designhash{$udom.'.login.'.$key}=$domconfig{'login'}{$key};
Line 4047  sub get_domainconf { Line 4403  sub get_domainconf {
         } else {          } else {
             $legacy{'rolecolors'} = 1;              $legacy{'rolecolors'} = 1;
         }          }
           if (ref($domconfig{'autoenroll'}) eq 'HASH') {
               if ($domconfig{'autoenroll'}{'co-owners'}) {
                   $designhash{$udom.'.autoassign.co-owners'}=$domconfig{'autoenroll'}{'co-owners'};
               }
           }
         if (keys(%legacy) > 0) {          if (keys(%legacy) > 0) {
             my %legacyhash = &get_legacy_domconf($udom);              my %legacyhash = &get_legacy_domconf($udom);
             foreach my $item (keys(%legacyhash)) {              foreach my $item (keys(%legacyhash)) {
Line 4143  sub designparm { Line 4504  sub designparm {
         return $env{'environment.color.'.$which};          return $env{'environment.color.'.$which};
     }      }
     $domain=&determinedomain($domain);      $domain=&determinedomain($domain);
     my %domdesign = &get_domainconf($domain);      my %domdesign;
       unless ($domain eq 'public') {
           %domdesign = &get_domainconf($domain);
       }
     my $output;      my $output;
     if ($domdesign{$domain.'.'.$which} ne '') {      if ($domdesign{$domain.'.'.$which} ne '') {
         $output = $domdesign{$domain.'.'.$which};          $output = $domdesign{$domain.'.'.$which};
Line 4182  Returns: Path to the Construction Space Line 4546  Returns: Path to the Construction Space
   
 sub authorspace {  sub authorspace {
     my $caname = '';      my $caname = '';
       my $cadom = '';
     if ($env{'request.role'} =~ /^ca|^aa/) {      if ($env{'request.role'} =~ /^ca|^aa/) {
         (undef,$caname) =          ($cadom,$caname) =
             ($env{'request.role'}=~/($match_domain)\/($match_username)$/);              ($env{'request.role'}=~/($match_domain)\/($match_username)$/);
     } else {      } else {
         $caname = $env{'user.name'};          $caname = $env{'user.name'};
           $cadom = $env{'user.domain'};
     }      }
     return '/priv/'.$caname.'/';      return '/priv/'.$cadom.'/'.$caname.'/';
 }  }
   
 ##############################################  ##############################################
Line 4206  Returns: HTML div with $content Line 4572  Returns: HTML div with $content
 sub head_subbox {  sub head_subbox {
     my ($content)=@_;      my ($content)=@_;
     my $output =      my $output =
         '<div id="LC_head_subbox">'          '<div class="LC_head_subbox">'
        .$content         .$content
        .'</div>'         .'</div>'
 }  }
Line 4226  Returns: HTML div with CSTR path and rec Line 4592  Returns: HTML div with CSTR path and rec
 sub CSTR_pageheader {  sub CSTR_pageheader {
     # this is for resources; directories have customtitle, and crumbs      # this is for resources; directories have customtitle, and crumbs
             # and select recent are created in lonpubdir.pm                # and select recent are created in lonpubdir.pm  
     my ($uname,$thisdisfn)=      my ($udom,$uname,$thisdisfn)=
         ($env{'request.filename'} =~ m|^/home/([^/]+)/public_html/(.*)|);          ($env{'request.filename'} =~ m|^/home/httpd/html/priv/([^/]+)/([^/]+)/(.*)$|);
     my $formaction='/priv/'.$uname.'/'.$thisdisfn;      my $formaction='/priv/'.$udom.'/'.$uname.'/'.$thisdisfn;
     $formaction=~s/\/+/\//g;      $formaction=~s/\/+/\//g;
   
     my $parentpath = '';      my $parentpath = '';
Line 4239  sub CSTR_pageheader { Line 4605  sub CSTR_pageheader {
     } else {      } else {
         $lastitem = $thisdisfn;          $lastitem = $thisdisfn;
     }      }
     return  
       my $output =
          '<div>'           '<div>'
         .&Apache::loncommon::help_open_menu('','',3,'Authoring') #FIXME: Broken? Where is it?          .&Apache::loncommon::help_open_menu('','',3,'Authoring') #FIXME: Broken? Where is it?
         .'<b>'.&mt('Construction Space:').'</b> '          .'<b>'.&mt('Construction Space:').'</b> '
         .'<form name="dirs" method="post" action="'.$formaction          .'<form name="dirs" method="post" action="'.$formaction
         .'" target="_top"><tt><b>' #FIXME lonpubdir: target="_parent"          .'" target="_top">' #FIXME lonpubdir: target="_parent"
         .&Apache::lonhtmlcommon::crumbs($uname.'/'.$parentpath,'_top','/priv','','+1',1)."$lastitem</b></tt><br />"          .&Apache::lonhtmlcommon::crumbs($uname.'/'.$parentpath,'_top','/priv/'.$udom,undef,undef);
   
       if ($lastitem) {
           $output .=
                '<span class="LC_filename">'
               .$lastitem
               .'</span>';
       }
       $output .=
            '<br />'
         #FIXME lonpubdir: &Apache::lonhtmlcommon::crumbs($uname.$thisdisfn.'/','_top','/priv','','+1',1)."</b></tt><br />"          #FIXME lonpubdir: &Apache::lonhtmlcommon::crumbs($uname.$thisdisfn.'/','_top','/priv','','+1',1)."</b></tt><br />"
         .&Apache::lonhtmlcommon::select_recent('construct','recent','this.form.action=this.form.recent.value;this.form.submit()')          .&Apache::lonhtmlcommon::select_recent('construct','recent','this.form.action=this.form.recent.value;this.form.submit()')
         .'</form>'          .'</form>'
         .&Apache::lonmenu::constspaceform()          .&Apache::lonmenu::constspaceform()
         .'</div>';          .'</div>';
   
       return $output;
 }  }
   
 ###############################################  ###############################################
Line 4290  Inputs: Line 4668  Inputs:
   
 =item * $bgcolor, used to override the bgcolor on a webpage to a specific value  =item * $bgcolor, used to override the bgcolor on a webpage to a specific value
   
 =item * $no_inline_link, if true and in remote mode, don't show the   
          'Switch To Inline Menu' link  
   
 =item * $args, optional argument valid values are  =item * $args, optional argument valid values are
             no_auto_mt_title -> prevents &mt()ing the title arg              no_auto_mt_title -> prevents &mt()ing the title arg
             inherit_jsmath -> when creating popup window in a page,              inherit_jsmath -> when creating popup window in a page,
Line 4310  other decorations will be returned. Line 4685  other decorations will be returned.
   
 sub bodytag {  sub bodytag {
     my ($title,$function,$addentries,$bodyonly,$domain,$forcereg,      my ($title,$function,$addentries,$bodyonly,$domain,$forcereg,
         $no_nav_bar,$bgcolor,$no_inline_link,$args)=@_;          $no_nav_bar,$bgcolor,$args)=@_;
   
       my $public;
       if ((($env{'user.name'} eq 'public') && ($env{'user.domain'} eq 'public'))
           || ($env{'user.name'} eq '') && ($env{'user.domain'} eq '')) {
           $public = 1;
       }
     if (!$args->{'no_auto_mt_title'}) { $title = &mt($title); }      if (!$args->{'no_auto_mt_title'}) { $title = &mt($title); }
   
     $function = &get_users_function() if (!$function);      $function = &get_users_function() if (!$function);
Line 4338  sub bodytag { Line 4718  sub bodytag {
         if ($env{'request.role'} !~ /^cr/) {          if ($env{'request.role'} !~ /^cr/) {
             $role = &Apache::lonnet::plaintext($role,&course_type());              $role = &Apache::lonnet::plaintext($role,&course_type());
         }          }
           if ($env{'request.course.sec'}) {
               $role .= ('&nbsp;'x2).'-&nbsp;'.&mt('section:').'&nbsp;'.$env{'request.course.sec'};
           }   
  $realm = $env{'course.'.$env{'request.course.id'}.'.description'};   $realm = $env{'course.'.$env{'request.course.id'}.'.description'};
     } else {      } else {
         $role = &Apache::lonnet::plaintext($role);          $role = &Apache::lonnet::plaintext($role);
     }      }
   
     if (!$realm) { $realm='&nbsp;'; }      if (!$realm) { $realm='&nbsp;'; }
 # Set messages  
     my $messages=&domainlogo($domain);  
   
     my $extra_body_attr = &make_attr_string($forcereg,\%design);      my $extra_body_attr = &make_attr_string($forcereg,\%design);
   
Line 4358  sub bodytag { Line 4739  sub bodytag {
     }       } 
   
     my $name = &plainname($env{'user.name'},$env{'user.domain'});      my $name = &plainname($env{'user.name'},$env{'user.domain'});
     if ($env{'user.name'} eq 'public' && $env{'user.domain'} eq 'public') {      if ($public) {
  undef($role);   undef($role);
     } else {      } else {
  $name = &aboutmewrapper($name,$env{'user.name'},$env{'user.domain'});   $name = &aboutmewrapper($name,$env{'user.name'},$env{'user.domain'});
Line 4372  sub bodytag { Line 4753  sub bodytag {
                         $env{'course.'.$env{'request.course.id'}.                          $env{'course.'.$env{'request.course.id'}.
                                  '.domain'}.'/'})) {                                   '.domain'}.'/'})) {
         my $cid = $env{'request.course.id'};          my $cid = $env{'request.course.id'};
         $dc_info.= $cid.' '.$env{'course.'.$cid.'.internal.coursecode'};          $dc_info = $cid.' '.$env{'course.'.$cid.'.internal.coursecode'};
         $dc_info =~ s/\s+$//;          $dc_info =~ s/\s+$//;
         $dc_info = '('.$dc_info.')';  
     }      }
   
     $role = "($role)" if $role;      $role = '<span class="LC_nobreak">('.$role.')</span>' if $role;
     &get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['inhibitmenu']);      &get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['inhibitmenu']);
   
     if ($env{'environment.remote'} eq 'off') {          if ($no_nav_bar || $env{'form.inhibitmenu'} eq 'yes') { 
         # No Remote              return $bodytag; 
  if ($env{'request.state'} eq 'construct') {          } 
     $forcereg=1;  
  }  
   
 #    if ($env{'request.state'} eq 'construct') {          if ($env{'request.state'} eq 'construct') { $forcereg=1; }
 #        $titleinfo = &CSTR_pageheader(); #FIXME: Will be removed once all scripts have their own calls  
 #    }  
   
         my $titletable = '<table id="LC_title_bar">'  
                         ."<tr><td> $titleinfo $dc_info</td>"  
                         .'</tr></table>';  
   
  if ($no_nav_bar) {          #    if ($env{'request.state'} eq 'construct') {
     $bodytag .= $titletable;          #        $titleinfo = &CSTR_pageheader(); #FIXME: Will be removed once all scripts have their own calls
  } else {          #    }
         $bodytag .= qq|<div id="LC_nav_bar">$name $role<br />  
             <em>$realm</em> $dc_info</div>| unless $env{'form.inhibitmenu'};  
   
     if ($env{'request.state'} eq 'construct') {  
                 $bodytag .= &Apache::lonmenu::menubuttons($forcereg,$titletable);  
             } else {          if ($env{'request.noversionuri'} =~ m{^/res/adm/pages/}) {
                 $bodytag .= &Apache::lonmenu::menubuttons($forcereg).$titletable;               if ($dc_info) {
                    $dc_info = qq|<span class="LC_cusr_subheading">$dc_info</span>|;
                }
                $bodytag .= qq|<div id="LC_nav_bar">$name $role<br />
                   <em>$realm</em> $dc_info</div>|;
               return $bodytag;
           }
   
           unless ($env{'request.symb'} =~ m/\.page___\d+___/) {
               $bodytag .= qq|<div id="LC_nav_bar">$name $role</div>|;
           }
   
           $bodytag .= Apache::lonhtmlcommon::scripttag(
               Apache::lonmenu::utilityfunctions(), 'start');
   
           $bodytag .= Apache::lonmenu::primary_menu();
   
           if ($dc_info) {
               $dc_info = &dc_courseid_toggle($dc_info);
           }
           $bodytag .= qq|<div id="LC_realm">$realm $dc_info</div>|;
   
           #don't show menus for public users
           if (!$public){
               $bodytag .= Apache::lonmenu::secondary_menu();
               $bodytag .= Apache::lonmenu::serverform();
               $bodytag .= Apache::lonhtmlcommon::scripttag('', 'end');
               if ($env{'request.state'} eq 'construct') {
                   $bodytag .= &Apache::lonmenu::innerregister($forcereg,
                                   $args->{'bread_crumbs'});
               } elsif ($forcereg) { 
                   $bodytag .= &Apache::lonmenu::innerregister($forcereg);
             }              }
           }else{
               # this is to seperate menu from content when there's no secondary
               # menu. Especially needed for public accessible ressources.
               $bodytag .= '<hr style="clear:both" />';
               $bodytag .= Apache::lonhtmlcommon::scripttag('', 'end'); 
         }          }
         return $bodytag;  
     }  
   
 #          return $bodytag;
 # Top frame rendering, Remote is up  }
 #  
   
     my $imgsrc = $img;  sub dc_courseid_toggle {
     if ($img =~ /^\/adm/) {      my ($dc_info) = @_;
         $imgsrc = &lonhttpdurl($img);      return ' <span id="dccidtext" class="LC_cusr_subheading LC_nobreak">'.
     }             '<a href="javascript:showCourseID();">'.
     my $upperleft='<img src="'.$imgsrc.'" alt="'.$function.'" />';             &mt('(More ...)').'</a></span>'.
              '<div id="dccid" class="LC_dccid">'.$dc_info.'</div>';
     # Explicit link to get inline menu  
     my $menu= ($no_inline_link?''  
        :'<a href="/adm/remote?action=collapse">'.&mt('Switch to Inline Menu Mode').'</a>');  
     $bodytag .= qq|<div id="LC_nav_bar">$name $role  
             <em>$realm</em> $dc_info </div>  
             <ol class="LC_smallMenu LC_right">  
                 <li>$menu</li>  
             </ol>| unless $env{'form.inhibitmenu'};  
     #  
     return(<<ENDBODY);  
 $bodytag  
 <table id="LC_title_bar" class="LC_with_remote">  
 <tr><td>$upperleft</td>  
     <td>$messages&nbsp;</td>  
 </tr>  
 <tr><td>$titleinfo $dc_info $menu</td>  
 </tr>  
 </table>  
 ENDBODY  
 }  }
   
 sub make_attr_string {  sub make_attr_string {
Line 4461  sub make_attr_string { Line 4845  sub make_attr_string {
  delete($attr_ref->{$key});   delete($attr_ref->{$key});
     }      }
  }   }
  $attr_ref->{'onload'}  =   $attr_ref->{'onload'}  = $on_load;
     &Apache::lonmenu::loadevents().  $on_load;   $attr_ref->{'onunload'}= $on_unload;
  $attr_ref->{'onunload'}=  
     &Apache::lonmenu::unloadevents().$on_unload;  
     }  
   
 # Accessibility font enhance  
     if ($env{'browser.fontenhance'} eq 'on') {  
  my $style;  
  foreach my $key (keys(%{$attr_ref})) {  
     if (lc($key) eq 'style') {  
  $style.=$attr_ref->{$key}.';';  
  delete($attr_ref->{$key});  
     }  
  }  
  $attr_ref->{'style'}=$style.'; font-size: x-large;';  
     }      }
   
     my $attr_string;      my $attr_string;
Line 4550  sub standard_css { Line 4920  sub standard_css {
     my $vlink  = &designparm($function.'.vlink', $domain);      my $vlink  = &designparm($function.'.vlink', $domain);
     my $link   = &designparm($function.'.link',  $domain);      my $link   = &designparm($function.'.link',  $domain);
   
     my $loginbg = &designparm('login.sidebg',$domain);  
     my $bgcol = &designparm('login.bgcol',$domain);  
     my $textcol = &designparm('login.textcol',$domain);  
   
     my $sans                 = 'Verdana,Arial,Helvetica,sans-serif';      my $sans                 = 'Verdana,Arial,Helvetica,sans-serif';
     my $mono                 = 'monospace';      my $mono                 = 'monospace';
     my $data_table_head      = $sidebg;      my $data_table_head      = $sidebg;
Line 4571  sub standard_css { Line 4937  sub standard_css {
     my $mail_other_hover     = '#669999';      my $mail_other_hover     = '#669999';
     my $table_header         = '#DDDDDD';      my $table_header         = '#DDDDDD';
     my $feedback_link_bg     = '#BBBBBB';      my $feedback_link_bg     = '#BBBBBB';
     my $lg_border_color     = '#C8C8C8';      my $lg_border_color      = '#C8C8C8';
       my $button_hover         = '#BF2317';
   
     my $border = ($env{'browser.type'} eq 'explorer' ||      my $border = ($env{'browser.type'} eq 'explorer' ||
   $env{'browser.type'} eq 'safari'     ) ? '0 2px 0 2px'        $env{'browser.type'} eq 'safari'     ) ? '0 2px 0 2px'
                                                  : '0 3px 0 4px';                                               : '0 3px 0 4px';
   
   
     return <<END;      return <<END;
 body {  
    font-family: $sans;  
    line-height:130%;  
    font-size:0.83em;  
    color:$font;  
 }  
   
 a:link, a:visited {   /* needed for iframe to allow 100% height in FF */
   font-size:100%;   body, html { 
       margin: 0;
       padding: 0 0.5%;
       height: 99%; /* to avoid scrollbars */
 }  }
   
 a:focus {   body {
   color: red;    font-family: $sans;
   background: yellow     line-height:130%;
     font-size:0.83em;
     color:$font;
 }  }
   
 hr {  a:focus,
   clear: both;  a:focus img {
   color: $tabbg;    color: red;
   background-color: $tabbg;    background: yellow;
   height: 3px;  
   border: none;  
 }  }
   
 form, .inline {   form, .inline {
    display: inline;     display: inline;
 }  }
   
 .LC_right {  .LC_right {
    text-align:right;    text-align:right;
 }  }
   
 .LC_middle {  .LC_middle {
    vertical-align:middle;    vertical-align:middle;
 }  }
   
 /* just for tests */  .LC_400Box {
 .LC_400Box {width:400px; }    width:400px;
 /* end */  }
   
   .LC_iframecontainer {
       width: 98%;
       margin: 0;
       position: fixed;
       top: 8.5em;
       bottom: 0;
   }
   
   .LC_iframecontainer iframe{
       border: none;
       width: 100%;
       height: 100%;
   }
   
 .LC_filename {  .LC_filename {
   font-family: $mono;    font-family: $mono;
   white-space:pre;    white-space:pre;
     font-size: 120%;
 }  }
   
 .LC_fileicon {  .LC_fileicon {
Line 4632  form, .inline { Line 5011  form, .inline {
   text-decoration:none;    text-decoration:none;
 }  }
   
   .LC_setting {
     text-decoration:underline;
   }
   
 .LC_error {  .LC_error {
   color: red;    color: red;
   font-size: larger;    font-size: larger;
Line 4676  div.LC_confirm_box .LC_success img { Line 5059  div.LC_confirm_box .LC_success img {
 }  }
   
 .LC_discussion {  .LC_discussion {
    background: $tabbg;    background: $tabbg;
    border: 1px solid black;    border: 1px solid black;
    margin: 2px;    margin: 2px;
 }  }
   
 .LC_disc_action_links_bar {  .LC_disc_action_links_bar {
    background: $tabbg;    background: $tabbg;
    border: none;    border: none;
    margin: 4px;    margin: 4px;
 }  }
   
 .LC_disc_action_left {  .LC_disc_action_left {
    text-align: left;    text-align: left;
 }  }
   
 .LC_disc_action_right {  .LC_disc_action_right {
    text-align: right;    text-align: right;
 }  }
   
 .LC_disc_new_item {  .LC_disc_new_item {
    background: white;    background: white;
    border: 2px solid red;    border: 2px solid red;
    margin: 2px;    margin: 2px;
 }  }
   
 .LC_disc_old_item {  .LC_disc_old_item {
    background: white;    background: white;
    border: 1px solid black;    border: 1px solid black;
    margin: 2px;    margin: 2px;
 }  }
   
 table.LC_pastsubmission {  table.LC_pastsubmission {
Line 4712  table.LC_pastsubmission { Line 5095  table.LC_pastsubmission {
   margin: 2px;    margin: 2px;
 }  }
   
 table#LC_top_nav,  table#LC_menubuttons {
 table#LC_menubuttons,  
 table#LC_nav_location {  
   width: 100%;    width: 100%;
   background: $pgbg;    background: $pgbg;
   border: 2px;    border: 2px;
Line 4732  table#LC_title_bar { Line 5113  table#LC_title_bar {
 }  }
   
 table#LC_title_bar,  table#LC_title_bar,
 table.LC_breadcrumbs,  table.LC_breadcrumbs, /* obsolete? */
 table#LC_title_bar.LC_with_remote {  table#LC_title_bar.LC_with_remote {
   width: 100%;    width: 100%;
   border-color: $pgbg;    border-color: $pgbg;
Line 4745  table#LC_title_bar.LC_with_remote { Line 5126  table#LC_title_bar.LC_with_remote {
   margin: 0;    margin: 0;
 }  }
   
 table#LC_title_bar td {  ul.LC_breadcrumb_tools_outerlist {
   background: $tabbg;      margin: 0;
       padding: 0;
       position: relative;
       list-style: none;
 }  }
   ul.LC_breadcrumb_tools_outerlist li {
 table#LC_menubuttons img{      display: inline;
   border: none;  
 }  }
   
 table#LC_top_nav td {  .LC_breadcrumb_tools_navigation {
   background: $tabbg;      padding: 0;
   border: none;      margin: 0;
   font-size: small;      float: left;
   vertical-align:top;  
   padding:2px 5px 2px 5px;  
 }  }
   .LC_breadcrumb_tools_tools {
 table#LC_top_nav td a,      padding: 0;
 div#LC_top_nav a {      margin: 0;
   color: $font;      float: right;
 }  }
   
 table#LC_top_nav td.LC_top_nav_logo {  table#LC_title_bar td {
   background: $tabbg;    background: $tabbg;
   text-align: left;  
   white-space: nowrap;  
   width: 31px;  
 }  }
   
 table#LC_top_nav td.LC_top_nav_logo img {  table#LC_menubuttons img {
   border: none;    border: none;
   vertical-align: bottom;  
 }  
   
 table#LC_top_nav td.LC_top_nav_exit,  
 table#LC_top_nav td.LC_top_nav_help {  
   width: 2.0em;  
 }  
   
 table#LC_top_nav td.LC_top_nav_login {  
   width: 4.0em;  
   text-align: center;  
 }  }
   
 .LC_breadcrumbs_component {  .LC_breadcrumbs_component {
     float: right;    float: right;
     margin: 0 1em;    margin: 0 1em;
 }  }
 .LC_breadcrumbs_component img {  .LC_breadcrumbs_component img {
     vertical-align: middle;    vertical-align: middle;
 }  }
   
 td.LC_table_cell_checkbox {  td.LC_table_cell_checkbox {
   text-align: center;    text-align: center;
 }  }
   
 table#LC_mainmenu td.LC_mainmenu_column {  
     vertical-align: top;  
 }  
   
 .LC_fontsize_small {  .LC_fontsize_small {
  font-size: 70%;    font-size: 70%;
 }  }
   
 #LC_breadcrumbs {  #LC_breadcrumbs {
  clear:both;    clear:both;
  background: $sidebg;    background: $sidebg;
  border-bottom: 1px solid $lg_border_color;    border-bottom: 1px solid $lg_border_color;
  line-height: 32px;     line-height: 2.5em;
  margin: 0;    overflow: hidden;
  padding: 0;    margin: 0;
 }    padding: 0;
     text-align: left;
 /* Preliminary fix to hide breadcrumbs inside remote control window */  }
 #LC_remote #LC_breadcrumbs {  
     display:none;  .LC_head_subbox {
 }    clear:both;
     background: #F8F8F8; /* $sidebg; */
 #LC_head_subbox {    border: 1px solid $sidebg;
  clear:both;    margin: 0 0 10px 0;      
  background: #F8F8F8; /* $sidebg; */    padding: 3px;
  border-bottom: 1px solid $lg_border_color;    text-align: left;
  margin: 0 0 10px 0;  
  padding: 5px;  
 }  }
   
 .LC_fontsize_medium {  .LC_fontsize_medium {
  font-size: 85%;    font-size: 85%;
 }  }
   
 .LC_fontsize_large {  .LC_fontsize_large {
  font-size: 120%;    font-size: 120%;
 }  }
   
 .LC_menubuttons_inline_text {  .LC_menubuttons_inline_text {
Line 4844  table#LC_mainmenu td.LC_mainmenu_column Line 5205  table#LC_mainmenu td.LC_mainmenu_column
   padding-left:3px;    padding-left:3px;
 }  }
   
   .LC_menubuttons_inline_text img{
     vertical-align: middle;
   }
   
   li.LC_menubuttons_inline_text img,a {
     cursor:pointer;
     text-decoration: none;
   }
   
 .LC_menubuttons_link {  .LC_menubuttons_link {
   text-decoration: none;    text-decoration: none;
 }  }
Line 4856  table#LC_mainmenu td.LC_mainmenu_column Line 5226  table#LC_mainmenu td.LC_mainmenu_column
 }  }
   
 td.LC_menubuttons_text {  td.LC_menubuttons_text {
   color: $font;    color: $font;
 }  }
   
 .LC_current_location {  .LC_current_location {
   background: $tabbg;    background: $tabbg;
 }  }
   
 .LC_new_mail {  table.LC_data_table {
   background: $tabbg;  
   font-weight: bold;  
 }  
   
 .LC_roleslog_note {  
   font-size: small;  
 }  
   
 table.LC_data_table,  
 table.LC_mail_list {  
   border: 1px solid #000000;    border: 1px solid #000000;
   border-collapse: separate;    border-collapse: separate;
   border-spacing: 1px;    border-spacing: 1px;
Line 4891  table.LC_nested_outer { Line 5251  table.LC_nested_outer {
   width: 100%;    width: 100%;
 }  }
   
   table.LC_innerpickbox,
 table.LC_nested {  table.LC_nested {
   border: none;    border: none;
   border-collapse: collapse;    border-collapse: collapse;
Line 4898  table.LC_nested { Line 5259  table.LC_nested {
   width: 100%;    width: 100%;
 }  }
   
 table.LC_data_table tr th,   table.LC_data_table tr th,
 table.LC_calendar tr th,   table.LC_calendar tr th,
 table.LC_mail_list tr th,  table.LC_prior_tries tr th,
 table.LC_prior_tries tr th {  table.LC_innerpickbox tr th {
   font-weight: bold;    font-weight: bold;
   background-color: $data_table_head;    background-color: $data_table_head;
   color:$fontmenu;    color:$fontmenu;
   font-size:90%;    font-size:90%;
 }  }
   
   table.LC_innerpickbox tr th,
   table.LC_innerpickbox tr td {
     vertical-align: top;
   }
   
 table.LC_data_table tr.LC_info_row > td {  table.LC_data_table tr.LC_info_row > td {
   background-color: #CCCCCC;    background-color: #CCCCCC;
   font-weight: bold;    font-weight: bold;
   text-align: left;    text-align: left;
 }  }
   
 table.LC_data_table tr.LC_odd_row > td,  table.LC_data_table tr.LC_odd_row > td {
     background-color: $data_table_light;
     padding: 2px;
     vertical-align: top;
   }
   
 table.LC_pick_box tr > td.LC_odd_row {  table.LC_pick_box tr > td.LC_odd_row {
   background-color: $data_table_light;    background-color: $data_table_light;
     vertical-align: top;
   }
   
   table.LC_data_table tr.LC_even_row > td {
     background-color: $data_table_dark;
   padding: 2px;    padding: 2px;
     vertical-align: top;
 }  }
   
 table.LC_data_table tr.LC_even_row > td,  
 table.LC_pick_box tr > td.LC_even_row {  table.LC_pick_box tr > td.LC_even_row {
   background-color: $data_table_dark;    background-color: $data_table_dark;
   padding: 2px;    vertical-align: top;
 }  }
   
 table.LC_data_table tr.LC_data_table_highlight td {  table.LC_data_table tr.LC_data_table_highlight td {
Line 4937  table.LC_data_table tr td.LC_leftcol_hea Line 5313  table.LC_data_table tr td.LC_leftcol_hea
   
 table.LC_data_table tr.LC_empty_row td,  table.LC_data_table tr.LC_empty_row td,
 table.LC_nested tr.LC_empty_row td {  table.LC_nested tr.LC_empty_row td {
   background-color: #FFFFFF;  
   font-weight: bold;    font-weight: bold;
   font-style: italic;    font-style: italic;
   text-align: center;    text-align: center;
   padding: 8px;    padding: 8px;
 }  }
   
   table.LC_data_table tr.LC_empty_row td {
     background-color: $sidebg;
   }
   
   table.LC_nested tr.LC_empty_row td {
     background-color: #FFFFFF;
   }
   
   table.LC_caption {
   }
   
 table.LC_nested tr.LC_empty_row td {  table.LC_nested tr.LC_empty_row td {
   padding: 4ex    padding: 4ex
 }  }
Line 5008  table.LC_createuser tr.LC_info_row td  { Line 5394  table.LC_createuser tr.LC_info_row td  {
 table.LC_calendar {  table.LC_calendar {
   border: 1px solid #000000;    border: 1px solid #000000;
   border-collapse: collapse;    border-collapse: collapse;
     width: 98%;
 }  }
   
 table.LC_calendar_pickdate {  table.LC_calendar_pickdate {
Line 5017  table.LC_calendar_pickdate { Line 5404  table.LC_calendar_pickdate {
 table.LC_calendar tr td {  table.LC_calendar tr td {
   border: 1px solid #000000;    border: 1px solid #000000;
   vertical-align: top;    vertical-align: top;
     width: 14%;
 }  }
   
 table.LC_calendar tr td.LC_calendar_day_empty {  table.LC_calendar tr td.LC_calendar_day_empty {
Line 5027  table.LC_calendar tr td.LC_calendar_day_ Line 5415  table.LC_calendar tr td.LC_calendar_day_
   background-color: $data_table_highlight;    background-color: $data_table_highlight;
 }  }
   
 table.LC_mail_list tr.LC_mail_new {  table.LC_data_table tr td.LC_mail_new {
   background-color: $mail_new;    background-color: $mail_new;
 }  }
   
 table.LC_mail_list tr.LC_mail_new:hover {  table.LC_data_table tr.LC_mail_new:hover {
   background-color: $mail_new_hover;    background-color: $mail_new_hover;
 }  }
   
 table.LC_mail_list tr.LC_mail_even {  table.LC_data_table tr td.LC_mail_read {
 }  
   
 table.LC_mail_list tr.LC_mail_odd {  
 }  
   
 table.LC_mail_list tr.LC_mail_read {  
   background-color: $mail_read;    background-color: $mail_read;
 }  }
   
 table.LC_mail_list tr.LC_mail_read:hover {  /*
   table.LC_data_table tr.LC_mail_read:hover {
   background-color: $mail_read_hover;    background-color: $mail_read_hover;
 }  }
   */
   
 table.LC_mail_list tr.LC_mail_replied {  table.LC_data_table tr td.LC_mail_replied {
   background-color: $mail_replied;    background-color: $mail_replied;
 }  }
   
 table.LC_mail_list tr.LC_mail_replied:hover {  /*
   table.LC_data_table tr.LC_mail_replied:hover {
   background-color: $mail_replied_hover;    background-color: $mail_replied_hover;
 }  }
   */
   
 table.LC_mail_list tr.LC_mail_other {  table.LC_data_table tr td.LC_mail_other {
   background-color: $mail_other;    background-color: $mail_other;
 }  }
   
 table.LC_mail_list tr.LC_mail_other:hover {  /*
   table.LC_data_table tr.LC_mail_other:hover {
   background-color: $mail_other_hover;    background-color: $mail_other_hover;
 }  }
   */
   
 table.LC_data_table tr > td.LC_browser_file,  table.LC_data_table tr > td.LC_browser_file,
 table.LC_data_table tr > td.LC_browser_file_published {  table.LC_data_table tr > td.LC_browser_file_published {
   background: #CCFF88;    background: #AAEE77;
 }  }
   
 table.LC_data_table tr > td.LC_browser_file_locked,  table.LC_data_table tr > td.LC_browser_file_locked,
Line 5076  table.LC_data_table tr > td.LC_browser_f Line 5464  table.LC_data_table tr > td.LC_browser_f
 }  }
   
 table.LC_data_table tr > td.LC_browser_file_obsolete {  table.LC_data_table tr > td.LC_browser_file_obsolete {
   background: #AAAAAA;    background: #888888;
 }  }
   
 table.LC_data_table tr > td.LC_browser_file_modified,  table.LC_data_table tr > td.LC_browser_file_modified,
 table.LC_data_table tr > td.LC_browser_file_metamodified {  table.LC_data_table tr > td.LC_browser_file_metamodified {
   background: #FFFF77;    background: #F8F866;
 }  }
   
 table.LC_data_table tr.LC_browser_folder > td {  table.LC_data_table tr.LC_browser_folder > td {
   background: #CCCCFF;    background: #E0E8FF;
 }  }
   
 table.LC_data_table tr > td.LC_roles_is {  table.LC_data_table tr > td.LC_roles_is {
 /*  background: #77FF77; */    /* background: #77FF77; */
 }  }
   
 table.LC_data_table tr > td.LC_roles_future {  table.LC_data_table tr > td.LC_roles_future {
   background: #FFFF77;    border-right: 8px solid #FFFF77;
 }  }
   
 table.LC_data_table tr > td.LC_roles_will {  table.LC_data_table tr > td.LC_roles_will {
   background: #FFAA77;    border-right: 8px solid #FFAA77;
 }  }
   
 table.LC_data_table tr > td.LC_roles_expired {  table.LC_data_table tr > td.LC_roles_expired {
   background: #FF7777;    border-right: 8px solid #FF7777;
 }  }
   
 table.LC_data_table tr > td.LC_roles_will_not {  table.LC_data_table tr > td.LC_roles_will_not {
   background: #AAFF77;    border-right: 8px solid #AAFF77;
 }  }
   
 table.LC_data_table tr > td.LC_roles_selected {  table.LC_data_table tr > td.LC_roles_selected {
   background: #11CC55;    border-right: 8px solid #11CC55;
 }  }
   
 span.LC_current_location {  span.LC_current_location {
Line 5137  span.LC_parm_part { Line 5525  span.LC_parm_part {
   color: blue;    color: blue;
 }  }
   
 span.LC_parm_folder, span.LC_parm_symb {  span.LC_parm_folder,
   span.LC_parm_symb {
   font-size: x-small;    font-size: x-small;
   font-family: $mono;    font-family: $mono;
   color: #AAAAAA;    color: #AAAAAA;
 }  }
   
   ul.LC_parm_parmlist li {
     display: inline-block;
     padding: 0.3em 0.8em;
     vertical-align: top;
     width: 150px;
     border-top:1px solid $lg_border_color;
   }
   
 td.LC_parm_overview_level_menu,  td.LC_parm_overview_level_menu,
 td.LC_parm_overview_map_menu,  td.LC_parm_overview_map_menu,
 td.LC_parm_overview_parm_selectors,  td.LC_parm_overview_parm_selectors,
Line 5227  table.LC_pick_box { Line 5624  table.LC_pick_box {
 table.LC_pick_box td.LC_pick_box_title {  table.LC_pick_box td.LC_pick_box_title {
   background: $sidebg;    background: $sidebg;
   font-weight: bold;    font-weight: bold;
   text-align: right;    text-align: left;
   vertical-align: top;    vertical-align: top;
   width: 184px;    width: 184px;
   padding: 8px;    padding: 8px;
Line 5265  table.LC_pick_box td.LC_oddrow_value { Line 5662  table.LC_pick_box td.LC_oddrow_value {
   background-color: $data_table_light;    background-color: $data_table_light;
 }  }
   
 table.LC_helpform_receipt {  
   width: 620px;  
   border-collapse: separate;  
   background: white;  
   border: 1px solid black;  
   border-spacing: 1px;  
 }  
   
 table.LC_helpform_receipt td.LC_pick_box_title {  
   background: $tabbg;  
   font-weight: bold;  
   text-align: right;  
   width: 184px;  
   padding: 8px;  
 }  
   
 table.LC_helpform_receipt td.LC_evenrow_value {  
   text-align: left;  
   padding: 8px;  
   background-color: $data_table_light;  
 }  
   
 table.LC_helpform_receipt td.LC_oddrow_value {  
   text-align: left;  
   padding: 8px;  
   background-color: $data_table_light;  
 }  
   
 table.LC_helpform_receipt td.LC_pick_box_separator {  
   padding: 0;  
   height: 1px;  
   background: black;  
 }  
   
 span.LC_helpform_receipt_cat {  span.LC_helpform_receipt_cat {
   font-weight: bold;    font-weight: bold;
 }  }
Line 5337  table.LC_group_priv td { Line 5700  table.LC_group_priv td {
   padding: 0;    padding: 0;
 }  }
   
 table.LC_notify_front_page {  
   background: white;  
   border: 1px solid black;  
   padding: 8px;  
 }  
   
 table.LC_notify_front_page td {  
   padding: 8px;  
 }  
   
 .LC_navbuttons {  .LC_navbuttons {
   margin: 2ex 0ex 2ex 0ex;    margin: 2ex 0ex 2ex 0ex;
 }  }
   
 .LC_topic_bar {  .LC_topic_bar {
   font-weight: bold;    font-weight: bold;
   width: 100%;  
   background: $tabbg;    background: $tabbg;
   vertical-align: middle;    margin: 1em 0em 1em 2em;
   margin: 2ex 0ex 2ex 0ex;  
   padding: 3px;    padding: 3px;
     font-size: 1.2em;
 }  }
   
 .LC_topic_bar span {  .LC_topic_bar span {
     left: 0.5em;
     position: absolute;
   vertical-align: middle;    vertical-align: middle;
 }    font-size: 1.2em;
   
 .LC_topic_bar img {  
   vertical-align: bottom;  
 }  }
   
 table.LC_course_group_status {  table.LC_course_group_status {
Line 5394  div.LC_feedback_link img { Line 5745  div.LC_feedback_link img {
   vertical-align:middle;    vertical-align:middle;
 }  }
   
 div.LC_feedback_link a{  div.LC_feedback_link a {
   text-decoration: none;    text-decoration: none;
 }  }
   
 div.LC_comblock {  div.LC_comblock {
   display:inline;     display:inline;
   color:$font;    color:$font;
   font-size:90%;    font-size:90%;
 }  }
Line 5477  span.LC_prior_string, Line 5828  span.LC_prior_string,
 span.LC_prior_custom,  span.LC_prior_custom,
 span.LC_prior_reaction,  span.LC_prior_reaction,
 span.LC_prior_math {  span.LC_prior_math {
   font-family: monospace;    font-family: $mono;
   white-space: pre;    white-space: pre;
 }  }
   
 span.LC_prior_string {  span.LC_prior_string {
   font-family: monospace;    font-family: $mono;
   white-space: pre;    white-space: pre;
 }  }
   
Line 5491  table.LC_prior_option { Line 5842  table.LC_prior_option {
   border-collapse: collapse;    border-collapse: collapse;
 }  }
   
 table.LC_prior_rank,   table.LC_prior_rank,
 table.LC_prior_match {  table.LC_prior_match {
   border-collapse: collapse;    border-collapse: collapse;
 }  }
Line 5515  span.LC_cusr_subheading { Line 5866  span.LC_cusr_subheading {
   font-size: 85%;    font-size: 85%;
 }  }
   
 table.LC_docs_documents {  
   background: #BBBBBB;  
   border-width: 0;  
   border-collapse: collapse;  
 }  
   
 table.LC_docs_documents td.LC_docs_document {  
   border: 2px solid black;  
   padding: 4px;  
 }  
   
 div.LC_docs_entry_move {  div.LC_docs_entry_move {
   border: 1px solid #BBBBBB;    border: 1px solid #BBBBBB;
   background: #DDDDDD;    background: #DDDDDD;
Line 5601  table.LC_double_column tr td.LC_right_co Line 5941  table.LC_double_column tr td.LC_right_co
   vertical-align: top;    vertical-align: top;
 }  }
   
 span.LC_role_level {  
   font-weight: bold;  
 }  
   
 div.LC_left_float {  div.LC_left_float {
   float: left;    float: left;
   padding-right: 5%;    padding-right: 5%;
Line 5621  div.LC_clear_float_footer { Line 5957  div.LC_clear_float_footer {
 }  }
   
 div.LC_grade_show_user {  div.LC_grade_show_user {
   margin-top: 20px;  /*  border-left: 5px solid $sidebg; */
   border: 1px solid black;    border-top: 5px solid #000000;
     margin: 50px 0 0 0;
     padding: 15px 0 5px 10px;
 }  }
   
 div.LC_grade_user_name {  div.LC_grade_show_user_odd_row {
   background: #DDDDEE;  /*  border-left: 5px solid #000000; */
   border-bottom: 1px solid black;  
   font-weight: bold;  
   font-size: large;  
 }  }
   
 div.LC_grade_show_user_odd_row div.LC_grade_user_name {  div.LC_grade_show_user div.LC_Box {
   background: #DDEEDD;    margin-right: 50px;
 }  }
   
 div.LC_grade_show_problem,  
 div.LC_grade_submissions,  div.LC_grade_submissions,
 div.LC_grade_message_center,  div.LC_grade_message_center,
 div.LC_grade_info_links,  div.LC_grade_info_links {
 div.LC_grade_assign {  
   margin: 5px;    margin: 5px;
   width: 99%;    width: 99%;
   background: #FFFFFF;    background: #FFFFFF;
 }  }
   
 div.LC_grade_show_problem_header,  
 div.LC_grade_submissions_header,  div.LC_grade_submissions_header,
 div.LC_grade_message_center_header,  div.LC_grade_message_center_header {
 div.LC_grade_assign_header {  
   font-weight: bold;    font-weight: bold;
   font-size: large;    font-size: large;
 }  }
   
 div.LC_grade_show_problem_problem,  
 div.LC_grade_submissions_body,  div.LC_grade_submissions_body,
 div.LC_grade_message_center_body,  div.LC_grade_message_center_body {
 div.LC_grade_assign_body {  
   border: 1px solid black;    border: 1px solid black;
   width: 99%;    width: 99%;
   background: #FFFFFF;    background: #FFFFFF;
 }  }
   
 span.LC_grade_check_note {  
   font-weight: normal;  
   font-size: medium;  
   display: inline;  
   position: absolute;  
   right: 1em;  
 }  
   
 table.LC_scantron_action {  table.LC_scantron_action {
   width: 100%;    width: 100%;
 }  }
Line 5704  div.LC_edit_problem_header_title { Line 6025  div.LC_edit_problem_header_title {
 }  }
   
 table.LC_edit_problem_header_title {  table.LC_edit_problem_header_title {
   font-size: larger;  
   font-weight:  bold;  
   width: 100%;    width: 100%;
   border-color: $pgbg;  
   border-style: solid;  
   border-width: $border;  
   background: $tabbg;    background: $tabbg;
   border-collapse: collapse;  
   padding: 0;  
 }  }
   
 div.LC_edit_problem_discards {  div.LC_edit_problem_discards {
Line 5725  div.LC_edit_problem_saves { Line 6039  div.LC_edit_problem_saves {
   padding-bottom: 5px;    padding-bottom: 5px;
 }  }
   
 img.stift{  img.stift {
   border-width: 0;    border-width: 0;
   vertical-align: middle;    vertical-align: middle;
 }  }
   
 table#LC_mainmenu{  table td.LC_mainmenu_col_fieldset {
  margin-top:10px;  
  width:80%;  
 }  
   
 table#LC_mainmenu td.LC_mainmenu_col_fieldset{  
   vertical-align: top;    vertical-align: top;
   width: 45%;  
 }  
   
 .LC_mainmenu_fieldset_category {  
   color: $font;  
   background: $pgbg;  
   font-size: small;  
   font-weight: bold;  
 }  }
   
 div.LC_createcourse {  div.LC_createcourse {
     margin: 10px 10px 10px 10px;    margin: 10px 10px 10px 10px;
 }  }
   
 /* ---- Remove when done ----  .LC_dccid {
 # The following styles is part of the redesign of LON-CAPA and are    margin: 0.2em 0 0 0;
 # subject to change during this project.    padding: 0;
 # Don't rely on their current functionality as they might be     font-size: 90%;
 # changed or removed.    display:none;
 # --------------------------*/  }
   
 a:hover,  a:hover,
 ol.LC_smallMenu a:hover,  ol.LC_primary_menu a:hover,
 ol#LC_MenuBreadcrumbs a:hover,  ol#LC_MenuBreadcrumbs a:hover,
 ol#LC_PathBreadcrumbs a:hover,  ol#LC_PathBreadcrumbs a:hover,
 ul#LC_TabMainMenuContent a:hover,  ul#LC_secondary_menu a:hover,
 .LC_FormSectionClearButton input:hover  .LC_FormSectionClearButton input:hover
 ul.LC_TabContent   li:hover a {  ul.LC_TabContent   li:hover a {
  color:#BF2317;    color:$button_hover;
         text-decoration:none;    text-decoration:none;
 }  }
   
 h1 {  h1 {
  padding: 0;    padding: 0;
  line-height:130%;    line-height:130%;
 }  }
   
 h2,h3,h4,h5,h6 {  h2,
  margin: 5px 0 5px 0;  h3,
  padding: 0;  h4,
  line-height:130%;  h5,
   h6 {
     margin: 5px 0 5px 0;
     padding: 0;
     line-height:130%;
 }  }
   
 .LC_hcell {  .LC_hcell {
         padding:3px 15px 3px 15px;    padding:3px 15px 3px 15px;
         margin: 0;    margin: 0;
  background-color:$tabbg;    background-color:$tabbg;
  color:$fontmenu;    color:$fontmenu;
  border-bottom:solid 1px $lg_border_color;    border-bottom:solid 1px $lg_border_color;
 }  }
   
 .LC_Box > .LC_hcell {  .LC_Box > .LC_hcell {
     margin: 0 -10px 10px -10px;    margin: 0 -10px 10px -10px;
 }  }
   
 .LC_noBorder {  .LC_noBorder {
         border: 0;    border: 0;
 }  
   
 .LC_Right {  
         float: right;  
         margin: 0;  
         padding: 0;  
 }  }
   
 .LC_FormSectionClearButton input {  .LC_FormSectionClearButton input {
         background-color:transparent;    background-color:transparent;
         border: none;    border: none;
         cursor:pointer;    cursor:pointer;
         text-decoration:underline;    text-decoration:underline;
 }  }
   
 .LC_help_open_topic {  .LC_help_open_topic {
         color: #FFFFFF;    color: #FFFFFF;
         background-color: #EEEEFF;    background-color: #EEEEFF;
         margin: 1px;    margin: 1px;
         padding: 4px;    padding: 4px;
         border: 1px solid #000033;    border: 1px solid #000033;
         white-space: nowrap;    white-space: nowrap;
 /* vertical-align: middle; */    /* vertical-align: middle; */
 }  }
   
 dl,ul,div,fieldset {  dl,
  margin: 10px 10px 10px 0;  ul,
 /* overflow: hidden; */  div,
   fieldset {
     margin: 10px 10px 10px 0;
     /* overflow: hidden; */
 }  }
   
 fieldset > legend {  fieldset > legend {
     font-weight: bold;    font-weight: bold;
     padding: 0 5px 0 5px;    padding: 0 5px 0 5px;
 }  }
   
 #LC_nav_bar {  #LC_nav_bar {
     float: left;    float: left;
     margin: 0.2em 0 0 0;    background-color: $pgbg_or_bgcolor;
     margin: 0 0 2px 0;
 }  }
   
 #LC_nav_bar em{  #LC_realm {
     font-weight: bold;    margin: 0.2em 0 0 0;
     font-style: normal;    padding: 0;
     font-weight: bold;
     text-align: center;
     background-color: $pgbg_or_bgcolor;
 }  }
   
 ol.LC_smallMenu {  #LC_nav_bar em {
     float: right;    font-weight: bold;
     margin: 0.2em 0 0 0;    font-style: normal;
   }
   
   ol.LC_primary_menu {
     float: right;
     margin: 0;
     background-color: $pgbg_or_bgcolor;
 }  }
   
 ol#LC_PathBreadcrumbs {  ol#LC_PathBreadcrumbs {
  margin: 0;    margin: 0;
 }  }
   
 ol.LC_smallMenu li {  ol.LC_primary_menu li {
  display: inline;    display: inline;
  padding: 5px 5px 0 10px;    padding: 5px 5px 0 10px;
  vertical-align: top;    vertical-align: top;
 }  }
   
 ol.LC_smallMenu li img {  ol.LC_primary_menu li img {
  vertical-align: bottom;    vertical-align: bottom;
     height: 1.1em;
 }  }
   
 ol.LC_smallMenu a {  ol.LC_primary_menu a {
  font-size: 90%;    color: RGB(80, 80, 80);
  color: RGB(80, 80, 80);    text-decoration: none;
  text-decoration: none;  
 }  }
   
 ul#LC_TabMainMenuContent {  ol.LC_primary_menu a.LC_new_message {
     clear: both;    font-weight:bold;
     color: $fontmenu;    color: darkred;
     background: $tabbg;  
     list-style: none;  
     padding: 0;  
     margin: 0;  
     width: 100%;  
 }  }
   
 ul#LC_TabMainMenuContent li {  ol.LC_docs_parameters {
     font-weight: bold;    margin-left: 0;
     line-height: 1.8em;    padding: 0;
     padding: 0 0.8em;     list-style: none;
     border-right: 1px solid black;  
     display: inline;  
     vertical-align: middle;  
 }  }
   
 ul.LC_TabContent {  ol.LC_docs_parameters li {
  display:block;    margin: 0;
  background: $sidebg;    padding-right: 20px;
  border-bottom: solid 1px $lg_border_color;    display: inline;
  list-style:none;  
  margin: -10px -10px 0 -10px;  
  padding: 0;  
 }  }
   
 ul.LC_TabContentBigger {  ol.LC_docs_parameters li:before {
         display:block;    content: "\\002022 \\0020";
         list-style:none;  }
         padding: 0;  
   li.LC_docs_parameters_title {
     font-weight: bold;
   }
   
   ol.LC_docs_parameters li.LC_docs_parameters_title:before {
     content: "";
   }
   
   ul#LC_secondary_menu {
     clear: both;
     color: $fontmenu;
     background: $tabbg;
     list-style: none;
     padding: 0;
     margin: 0;
     width: 100%;
     text-align: left;
 }  }
   
   ul#LC_secondary_menu li {
     font-weight: bold;
     line-height: 1.8em;
     padding: 0 0.8em;
     border-right: 1px solid black;
     display: inline;
     vertical-align: middle;
   }
   
   ul.LC_TabContent {
     display:block;
     background: $sidebg;
     border-bottom: solid 1px $lg_border_color;
     list-style:none;
     margin: -1px -10px 0 -10px;
     padding: 0;
   }
   
 ul.LC_TabContent li,  ul.LC_TabContent li,
 ul.LC_TabContentBigger li {  ul.LC_TabContentBigger li {
  display: inline;    float:left;
  border-right: solid 1px $lg_border_color;  
  float:left;  
  line-height:140%;  
  white-space:nowrap;  
 }  }
   
 ul#LC_TabMainMenuContent li a {  ul#LC_secondary_menu li a {
     color: $fontmenu;    color: $fontmenu;
  text-decoration: none;    text-decoration: none;
 }  }
   
 ul.LC_TabContent {  ul.LC_TabContent {
  min-height:1.5em;    min-height:20px;
 }  }
   
 ul.LC_TabContent li {  ul.LC_TabContent li {
  vertical-align:middle;    vertical-align:middle;
  padding: 0 10px 0 10px;    padding: 0 16px 0 10px;
  background-color:$tabbg;    background-color:$tabbg;
  border-bottom:solid 1px $lg_border_color;    border-bottom:solid 1px $lg_border_color;
     border-left: solid 1px $font;
 }  }
   
 ul.LC_TabContent .right {  ul.LC_TabContent .right {
  float:right;    float:right;
 }  }
   
 ul.LC_TabContent li a, ul.LC_TabContent li {  ul.LC_TabContent li a,
  color:rgb(47,47,47);  ul.LC_TabContent li {
  text-decoration:none;    color:rgb(47,47,47);
  font-size:95%;    text-decoration:none;
  font-weight:bold;    font-size:95%;
  padding-right: 16px;    font-weight:bold;
     min-height:20px;
 }  }
   
 ul.LC_TabContent li:hover, ul.LC_TabContent li.active {  ul.LC_TabContent li a:hover,
         background:#FFFFFF url(/adm/lonIcons/open.gif) no-repeat scroll right center;  ul.LC_TabContent li a:focus {
  border-bottom:solid 2px #FFFFFF;    color: $button_hover;
  padding-right: 16px;    background:none;
     outline:none;
 }  }
   
 ul.LC_TabContentBigger li {  ul.LC_TabContent li:hover {
  vertical-align:bottom;    color: $button_hover;
  border-top:solid 1px $lg_border_color;    cursor:pointer;
  border-left:solid 1px $lg_border_color;  }
  padding:5px 10px 5px 10px;  
  margin-left:2px;  ul.LC_TabContent li.active {
  background: #d9d9d9;    color: $font;
     background:#FFFFFF url(/adm/lonIcons/open.gif) no-repeat scroll right center;
     border-bottom:solid 1px #FFFFFF;
     cursor: default;
 }  }
   
   ul.LC_TabContent li.active a {
     color:$font;
     background:#FFFFFF;
     outline: none;
   }
 #maincoursedoc {  #maincoursedoc {
  clear:both;    clear:both;
   }
   
   ul.LC_TabContentBigger {
     display:block;
     list-style:none;
     padding: 0;
   }
   
   ul.LC_TabContentBigger li {
     vertical-align:bottom;
     height: 30px;
     font-size:110%;
     font-weight:bold;
     color: #737373;
 }  }
   
 ul.LC_TabContentBigger li:hover,   
 ul.LC_TabContentBigger li.active {  ul.LC_TabContentBigger li.active {
  background: #ffffff;    position: relative;
  color:$font;    top: 1px;
 }  }
   
 ul.LC_TabContentBigger li,   
 ul.LC_TabContentBigger li a {  ul.LC_TabContentBigger li a {
  font-size:110%;    background:url('/adm/lonIcons/tabbgleft.gif') left bottom no-repeat;
  font-weight:bold;    height: 30px;
  color: #737373;    line-height: 30px;
     text-align: center;
     display: block;
     text-decoration: none;
     outline: none;  
   }
   
   ul.LC_TabContentBigger li.active a {
     background:url('/adm/lonIcons/tabbgleft.gif') left top no-repeat;
     color:$font;
   }
   
   ul.LC_TabContentBigger li b {
     background: url('/adm/lonIcons/tabbgright.gif') no-repeat right bottom;
     display: block;
     float: left;
     padding: 0 30px;
     border-bottom: 1px solid $lg_border_color;
 }  }
   
   ul.LC_TabContentBigger li:hover b {
     color:$button_hover;
   }
   
   ul.LC_TabContentBigger li.active b {
     background:url('/adm/lonIcons/tabbgright.gif') right top no-repeat;
     color:$font;
     border: 0;
   }
   
   
 ul.LC_CourseBreadcrumbs {  ul.LC_CourseBreadcrumbs {
   background: $sidebg;    background: $sidebg;
   line-height: 32px;    height: 2em;
   padding-left: 10px;    padding-left: 10px;
   margin: 0 0 10px 0;    margin: 0;
   list-style-position: inside;    list-style-position: inside;
   
 }  }
   
 ol#LC_MenuBreadcrumbs,   ol#LC_MenuBreadcrumbs,
 ol#LC_PathBreadcrumbs {  ol#LC_PathBreadcrumbs {
  padding-left: 10px;    padding-left: 10px;
  margin: 0;    margin: 0;
  list-style-position: inside;    height: 2.5em;  /* equal to #LC_breadcrumbs line-height */
 }  }
   
 ol#LC_MenuBreadcrumbs li,   ol#LC_MenuBreadcrumbs li,
 ol#LC_PathBreadcrumbs li,   ol#LC_PathBreadcrumbs li,
 ul.LC_CourseBreadcrumbs li {  ul.LC_CourseBreadcrumbs li {
     display: inline;    display: inline;
     white-space: nowrap;    white-space: normal;  
 }  }
   
 ol#LC_MenuBreadcrumbs li a,  ol#LC_MenuBreadcrumbs li a,
 ul.LC_CourseBreadcrumbs li a {  ul.LC_CourseBreadcrumbs li a {
  text-decoration: none;    text-decoration: none;
  font-size:90%;    font-size:90%;
   }
   
   ol#LC_MenuBreadcrumbs h1 {
     display: inline;
     font-size: 90%;
     line-height: 2.5em;
     margin: 0;
     padding: 0;
 }  }
   
 ol#LC_PathBreadcrumbs li a {  ol#LC_PathBreadcrumbs li a {
  text-decoration:none;    text-decoration:none;
  font-size:100%;    font-size:100%;
  font-weight:bold;    font-weight:bold;
 }  }
   
 .LC_Box {  .LC_Box {
     border: solid 1px $lg_border_color;    border: solid 1px $lg_border_color;
     padding: 0 10px 10px 10px;    padding: 0 10px 10px 10px;
   }
   
   .LC_DocsBox {
     border: solid 1px $lg_border_color;
     padding: 0 0 10px 10px;
 }  }
   
 .LC_AboutMe_Image {  .LC_AboutMe_Image {
  float:left;    float:left;
  margin-right:10px;    margin-right:10px;
 }  }
   
 .LC_Clear_AboutMe_Image {  .LC_Clear_AboutMe_Image {
  clear:left;    clear:left;
 }  }
   
 dl.LC_ListStyleClean dt {  dl.LC_ListStyleClean dt {
  padding-right: 5px;    padding-right: 5px;
  display: table-header-group;    display: table-header-group;
 }  }
   
 dl.LC_ListStyleClean dd {  dl.LC_ListStyleClean dd {
  display: table-row;    display: table-row;
 }  }
   
 .LC_ListStyleClean,  .LC_ListStyleClean,
 .LC_ListStyleSimple,  .LC_ListStyleSimple,
 .LC_ListStyleNormal,  .LC_ListStyleNormal,
 .LC_ListStyle_Border,  
 .LC_ListStyleSpecial {  .LC_ListStyleSpecial {
  /*display:block; */    /* display:block; */
  list-style-position: inside;    list-style-position: inside;
  list-style-type: none;    list-style-type: none;
  overflow: hidden;    overflow: hidden;
  padding: 0;    padding: 0;
 }  }
   
 .LC_ListStyleSimple li,  .LC_ListStyleSimple li,
Line 6044  dl.LC_ListStyleClean dd { Line 6437  dl.LC_ListStyleClean dd {
 .LC_ListStyleNormal dd,  .LC_ListStyleNormal dd,
 .LC_ListStyleSpecial li,  .LC_ListStyleSpecial li,
 .LC_ListStyleSpecial dd {  .LC_ListStyleSpecial dd {
  margin: 0;    margin: 0;
  padding: 5px 5px 5px 10px;    padding: 5px 5px 5px 10px;
  clear: both;    clear: both;
 }  }
   
 .LC_ListStyleClean li,  .LC_ListStyleClean li,
 .LC_ListStyleClean dd {  .LC_ListStyleClean dd {
  padding-top: 0;    padding-top: 0;
  padding-bottom: 0;    padding-bottom: 0;
 }  }
   
 .LC_ListStyleSimple dd,  .LC_ListStyleSimple dd,
 .LC_ListStyleSimple li {  .LC_ListStyleSimple li {
  border-bottom: solid 1px $lg_border_color;    border-bottom: solid 1px $lg_border_color;
 }  }
   
 .LC_ListStyleSpecial li,  .LC_ListStyleSpecial li,
 .LC_ListStyleSpecial dd {  .LC_ListStyleSpecial dd {
  list-style-type: none;    list-style-type: none;
  background-color: RGB(220, 220, 220);    background-color: RGB(220, 220, 220);
  margin-bottom: 4px;    margin-bottom: 4px;
 }  }
   
 table.LC_SimpleTable {  table.LC_SimpleTable {
  margin:5px;    margin:5px;
  border:solid 1px $lg_border_color;    border:solid 1px $lg_border_color;
 }  }
   
 table.LC_SimpleTable tr {  table.LC_SimpleTable tr {
  padding: 0;    padding: 0;
  border:solid 1px $lg_border_color;    border:solid 1px $lg_border_color;
 }  }
   
 table.LC_SimpleTable thead {  table.LC_SimpleTable thead {
  background:rgb(220,220,220);    background:rgb(220,220,220);
 }  }
   
 div.LC_columnSection {  div.LC_columnSection {
  display: block;    display: block;
  clear: both;    clear: both;
  overflow: hidden;    overflow: hidden;
  margin: 0;    margin: 0;
 }  }
   
 div.LC_columnSection>* {  div.LC_columnSection>* {
  float: left;    float: left;
  margin: 10px 20px 10px 0;    margin: 10px 20px 10px 0;
  overflow:hidden;    overflow:hidden;
 }  
   
 .LC_loginpage_container {  
  text-align:left;  
  margin : 0 auto;  
  width:90%;  
  padding: 10px;  
  height: auto;  
  background-color:#FFFFFF;  
  border:1px solid #CCCCCC;  
 }  
   
   
 .LC_loginpage_loginContainer {  
  float:left;  
  width: 182px;  
  padding: 2px;  
  border:1px solid #CCCCCC;  
  background-color:$loginbg;  
 }  
   
 .LC_loginpage_loginContainer h2 {  
  margin-top: 0;  
  display:block;  
  background:$bgcol;  
  color:$textcol;  
  padding-left:5px;  
 }  
   
 .LC_loginpage_loginInfo {  
  float:left;  
  width:182px;  
  border:1px solid #CCCCCC;  
  padding:2px;  
 }  
   
 .LC_loginpage_space {  
  clear: both;  
  margin-bottom: 20px;  
  border-bottom: 1px solid #CCCCCC;  
 }  
   
 .LC_loginpage_floatLeft {  
  float: left;  
  width: 200px;  
  margin: 0;  
 }  }
   
 table em {  table em {
  font-weight: bold;    font-weight: bold;
  font-style: normal;    font-style: normal;
 }  }
   
 table.LC_tableBrowseRes,  table.LC_tableBrowseRes,
 table.LC_tableOfContent {  table.LC_tableOfContent {
         border:none;    border:none;
  border-spacing: 1px;    border-spacing: 1px;
  padding: 3px;    padding: 3px;
  background-color: #FFFFFF;    background-color: #FFFFFF;
  font-size: 90%;    font-size: 90%;
 }  }
   
 table.LC_tableOfContent{  table.LC_tableOfContent {
     border-collapse: collapse;    border-collapse: collapse;
 }  }
   
 table.LC_tableBrowseRes a,  table.LC_tableBrowseRes a,
 table.LC_tableOfContent a {  table.LC_tableOfContent a {
         background-color: transparent;    background-color: transparent;
  text-decoration: none;    text-decoration: none;
 }  
   
 table.LC_tableBrowseRes tr.LC_trOdd,  
 table.LC_tableOfContent tr.LC_trOdd{  
  background-color: #EEEEEE;  
 }  }
   
 table.LC_tableOfContent img {  table.LC_tableOfContent img {
  border: none;    border: none;
  height: 1.3em;    height: 1.3em;
  vertical-align: text-bottom;    vertical-align: text-bottom;
  margin-right: 0.3em;    margin-right: 0.3em;
 }  }
   
 a#LC_content_toolbar_firsthomework {  a#LC_content_toolbar_firsthomework {
  background-image:url(/res/adm/pages/open-first-problem.gif);    background-image:url(/res/adm/pages/open-first-problem.gif);
 }  
   
 a#LC_content_toolbar_launchnav {  
  background-image:url(/res/adm/pages/start-navigation.gif);  
 }  
   
 a#LC_content_toolbar_closenav {  
  background-image:url(/res/adm/pages/close-navigation.gif);  
 }  }
   
 a#LC_content_toolbar_everything {  a#LC_content_toolbar_everything {
  background-image:url(/res/adm/pages/show-all.gif);    background-image:url(/res/adm/pages/show-all.gif);
 }  }
   
 a#LC_content_toolbar_uncompleted {  a#LC_content_toolbar_uncompleted {
  background-image:url(/res/adm/pages/show-incomplete-problems.gif);    background-image:url(/res/adm/pages/show-incomplete-problems.gif);
 }  }
   
 #LC_content_toolbar_clearbubbles {  #LC_content_toolbar_clearbubbles {
  background-image:url(/res/adm/pages/mark-discussionentries-read.gif);    background-image:url(/res/adm/pages/mark-discussionentries-read.gif);
 }  }
   
 a#LC_content_toolbar_changefolder {  a#LC_content_toolbar_changefolder {
  background : url(/res/adm/pages/close-all-folders.gif) top center ;    background : url(/res/adm/pages/close-all-folders.gif) top center ;
 }  }
   
 a#LC_content_toolbar_changefolder_toggled {  a#LC_content_toolbar_changefolder_toggled {
  background-image:url(/res/adm/pages/open-all-folders.gif);    background-image:url(/res/adm/pages/open-all-folders.gif);
 }  }
   
 ul#LC_toolbar li a:hover {  ul#LC_toolbar li a:hover {
  background-position: bottom center;    background-position: bottom center;
 }  }
   
 ul#LC_toolbar {  ul#LC_toolbar {
  padding: 0;    padding: 0;
  margin: 2px;    margin: 2px;
  list-style:none;    list-style:none;
  position:relative;    position:relative;
  background-color:white;    background-color:white;
 }  }
   
 ul#LC_toolbar li {  ul#LC_toolbar li {
  border:1px solid white;    border:1px solid white;
  padding: 0;    padding: 0;
  margin: 0;    margin: 0;
         float: left;    float: left;
  display:inline;    display:inline;
  vertical-align:middle;    vertical-align:middle;
 }   }
   
   
 a.LC_toolbarItem {  a.LC_toolbarItem {
  display:block;    display:block;
  padding: 0;    padding: 0;
  margin: 0;    margin: 0;
  height: 32px;    height: 32px;
  width: 32px;    width: 32px;
  color:white;    color:white;
  border: none;    border: none;
  background-repeat:no-repeat;    background-repeat:no-repeat;
  background-color:transparent;    background-color:transparent;
   }
   
   ul.LC_funclist {
       margin: 0;
       padding: 0.5em 1em 0.5em 0;
   }
   
   ul.LC_funclist > li:first-child {
       font-weight:bold; 
       margin-left:0.8em;
   }
   
   ul.LC_funclist + ul.LC_funclist {
       /* 
          left border as a seperator if we have more than
          one list 
       */
       border-left: 1px solid $sidebg;
       /* 
          this hides the left border behind the border of the 
          outer box if element is wrapped to the next 'line' 
       */
       margin-left: -1px;
 }  }
   
 ul.LC_funclist li {  ul.LC_funclist li {
   float: left;    display: inline;
   white-space: nowrap;    white-space: nowrap;
   height: 35px; /* at least as high as heighest list item */    margin: 0 0 0 25px;
   margin: 0 15px 15px 10px;    line-height: 150%;
 }  }
   
   .LC_hidden {
     display: none;
   }
   
 END  END
 }  }
Line 6301  sub headtag { Line 6661  sub headtag {
     if (!$args->{'frameset'}) {      if (!$args->{'frameset'}) {
  $result .= &Apache::lonhtmlcommon::htmlareaheaders();   $result .= &Apache::lonhtmlcommon::htmlareaheaders();
     }      }
     if ($args->{'force_register'}) {      if ($args->{'force_register'} && $env{'request.noversionuri'} !~ m{^/res/adm/pages/}) {
  $result .= &Apache::lonmenu::registerurl(1);          $result .= Apache::lonxml::display_title();
     }      }
     if (!$args->{'no_nav_bar'}       if (!$args->{'no_nav_bar'} 
  && !$args->{'only_body'}   && !$args->{'only_body'}
Line 6328  ADDMETA Line 6688  ADDMETA
     $result .= '<title> LON-CAPA '.$title.'</title>'      $result .= '<title> LON-CAPA '.$title.'</title>'
  .'<link rel="stylesheet" type="text/css" href="'.$url.'" />'   .'<link rel="stylesheet" type="text/css" href="'.$url.'" />'
  .$head_extra;   .$head_extra;
     return $result;      return $result.'</head>';
 }  }
   
 =pod  =pod
Line 6363  Inputs: none Line 6723  Inputs: none
 sub xml_begin {  sub xml_begin {
     my $output='';      my $output='';
   
     if ($env{'internal.start_page'}==1) {  
  &Apache::lonhtmlcommon::init_htmlareafields();  
     }  
   
     if ($env{'browser.mathml'}) {      if ($env{'browser.mathml'}) {
  $output='<?xml version="1.0"?>'   $output='<?xml version="1.0"?>'
             #.'<?xml-stylesheet type="text/css" href="/adm/MathML/mathml.css"?>'."\n"              #.'<?xml-stylesheet type="text/css" href="/adm/MathML/mathml.css"?>'."\n"
Line 6385  sub xml_begin { Line 6741  sub xml_begin {
   
 =pod  =pod
   
 =item * &endheadtag()  
   
 Returns a uniform </head> for LON-CAPA web pages.  
   
 Inputs: none  
   
 =cut  
   
 sub endheadtag {  
     return '</head>';  
 }  
   
 =pod  
   
 =item * &head()  
   
 Returns a uniform complete <head>..</head> section for LON-CAPA web pages.  
   
 Inputs:  
   
 =over 4  
   
 $title - optional title for the page  
   
 $head_extra - optional extra HTML to put inside the <head>  
   
 =back  
   
 =cut  
   
 sub head {  
     my ($title,$head_extra,$args) = @_;  
     return &headtag($title,$head_extra,$args).&endheadtag();  
 }  
   
 =pod  
   
 =item * &start_page()  =item * &start_page()
   
 Returns a complete <html> .. <body> section for LON-CAPA web pages.  Returns a complete <html> .. <body> section for LON-CAPA web pages.
Line 6459  $args - additional optional args support Line 6778  $args - additional optional args support
              skip_phases    -> hash ref of                skip_phases    -> hash ref of 
                                     head -> skip the <html><head> generation                                      head -> skip the <html><head> generation
                                     body -> skip all <body> generation                                      body -> skip all <body> generation
              no_inline_link -> if true and in remote mode, don't show the   
                                     'Switch To Inline Menu' link  
              no_auto_mt_title -> prevent &mt()ing the title arg               no_auto_mt_title -> prevent &mt()ing the title arg
              inherit_jsmath -> when creating popup window in a page,               inherit_jsmath -> when creating popup window in a page,
                                     should it have jsmath forced on by the                                      should it have jsmath forced on by the
                                     current page                                      current page
              bread_crumbs ->             Array containing breadcrumbs               bread_crumbs ->             Array containing breadcrumbs
              bread_crumbs_components ->  if exists show it as headline else show only the breadcrumbs               bread_crumbs_component ->  if exists show it as headline else show only the breadcrumbs
   
 =back  =back
   
Line 6477  $args - additional optional args support Line 6794  $args - additional optional args support
 sub start_page {  sub start_page {
     my ($title,$head_extra,$args) = @_;      my ($title,$head_extra,$args) = @_;
     #&Apache::lonnet::logthis("start_page ".join(':',caller(0)));      #&Apache::lonnet::logthis("start_page ".join(':',caller(0)));
   #SD
   #I don't see why we copy certain elements of %$args to %head_args
   #head args is passed to headtag() and this routine only reads those
   #keys that are needed. There doesn't happen any writes or any processing
   #of other keys.
   #proposal: just pass $args to headtag instead of \%head_args and delete 
   #marked lines
   #<- MARK
     my %head_args;      my %head_args;
     foreach my $arg ('redirect','force_register','domain','function',      foreach my $arg ('redirect','force_register','domain','function',
      'bgcolor','frameset','no_nav_bar','only_body',       'bgcolor','frameset','no_nav_bar','only_body',
Line 6485  sub start_page { Line 6810  sub start_page {
     $head_args{$arg} = $args->{$arg};      $head_args{$arg} = $args->{$arg};
  }   }
     }      }
   #MARK ->
   
     $env{'internal.start_page'}++;      $env{'internal.start_page'}++;
     my $result;      my $result;
   
     if (! exists($args->{'skip_phases'}{'head'}) ) {      if (! exists($args->{'skip_phases'}{'head'}) ) {
  $result.=          $result .= 
     &xml_begin().                    &xml_begin() . &headtag($title,$head_extra,\%head_args);
     &headtag($title,$head_extra,\%head_args).&endheadtag();  #replace prev line by
   #                 &xml_begin() . &headtag($title, $head_extra, $args);
     }      }
           
     if (! exists($args->{'skip_phases'}{'body'}) ) {      if (! exists($args->{'skip_phases'}{'body'}) ) {
Line 6505  sub start_page { Line 6833  sub start_page {
                          $args->{'function'},       $args->{'add_entries'},                           $args->{'function'},       $args->{'add_entries'},
                          $args->{'only_body'},      $args->{'domain'},                           $args->{'only_body'},      $args->{'domain'},
                          $args->{'force_register'}, $args->{'no_nav_bar'},                           $args->{'force_register'}, $args->{'no_nav_bar'},
                          $args->{'bgcolor'},        $args->{'no_inline_link'},                           $args->{'bgcolor'},        $args);
                          $args);  
         }          }
     }      }
   
Line 6522  sub start_page { Line 6849  sub start_page {
     #            $result .= &build_functionlist();      #            $result .= &build_functionlist();
     #}      #}
   
     # Don't add anything more if only_body wanted      # Don't add anything more if only_body wanted or in const space
     return $result if $args->{'only_body'};      return $result if    $args->{'only_body'} 
                         || $env{'request.state'} eq 'construct';
   
     #Breadcrumbs      #Breadcrumbs
     if (exists($args->{'bread_crumbs'}) or exists($args->{'bread_crumbs_component'})) {      if (exists($args->{'bread_crumbs'}) or exists($args->{'bread_crumbs_component'})) {
Line 6545  sub start_page { Line 6873  sub start_page {
     return $result;      return $result;
 }  }
   
   
 =pod  
   
 =item * &head()  
   
 Returns a complete </body></html> section for LON-CAPA web pages.  
   
 Inputs:         $args - additional optional args supported are:  
                  js_ready     -> return a string ready for being used in   
                                  a javascript writeln  
                  html_encode  -> return a string ready for being used in   
                                  a html attribute  
                  frameset     -> if true will start with a <frameset>  
                                  rather than <body>  
                  dicsussion   -> if true will get discussion from  
                                   lonxml::xmlend  
                                  (you can pass the target and parser arguments  
                                   through optional 'target' and 'parser' args  
                                   to this routine)  
   
 =cut  
   
 sub end_page {  sub end_page {
     my ($args) = @_;      my ($args) = @_;
     $env{'internal.end_page'}++;      $env{'internal.end_page'}++;
Line 6641  sub validate_page { Line 6947  sub validate_page {
     }      }
 }  }
   
   
   sub start_scrollbox {
       my ($outerwidth,$width,$height,$id)=@_;
       unless ($outerwidth) { $outerwidth='520px'; }
       unless ($width) { $width='500px'; }
       unless ($height) { $height='200px'; }
       my ($table_id,$div_id);
       if ($id ne '') {
           $table_id = " id='table_$id'";
           $div_id = " id='div_$id'";
       }
       return "<table style='width: $outerwidth; border: 1px solid none;'$table_id><tr><td style='width: $width;' bgcolor='#FFFFFF'><div style='overflow:auto; width:$width; height: $height;'$div_id>";
   }
   
   sub end_scrollbox {
       return '</td></tr></table>';
   }
   
 sub simple_error_page {  sub simple_error_page {
     my ($r,$title,$msg) = @_;      my ($r,$title,$msg) = @_;
     my $page =      my $page =
Line 6656  sub simple_error_page { Line 6980  sub simple_error_page {
   
 {  {
     my @row_count;      my @row_count;
   
       sub start_data_table_count {
           unshift(@row_count, 0);
           return;
       }
   
       sub end_data_table_count {
           shift(@row_count);
           return;
       }
   
     sub start_data_table {      sub start_data_table {
  my ($add_class) = @_;   my ($add_class,$id) = @_;
  my $css_class = (join(' ','LC_data_table',$add_class));   my $css_class = (join(' ','LC_data_table',$add_class));
  unshift(@row_count,0);          my $table_id;
  return '<table class="'.$css_class.'">'."\n";          if (defined($id)) {
               $table_id = ' id="'.$id.'"';
           }
    &start_data_table_count();
    return '<table class="'.$css_class.'"'.$table_id.'>'."\n";
     }      }
   
     sub end_data_table {      sub end_data_table {
  shift(@row_count);   &end_data_table_count();
  return '</table>'."\n";;   return '</table>'."\n";;
     }      }
   
     sub start_data_table_row {      sub start_data_table_row {
  my ($add_class) = @_;   my ($add_class, $id) = @_;
  $row_count[0]++;   $row_count[0]++;
  my $css_class = ($row_count[0] % 2)?'LC_odd_row':'LC_even_row';   my $css_class = ($row_count[0] % 2)?'LC_odd_row':'LC_even_row';
  $css_class = (join(' ',$css_class,$add_class));   $css_class = (join(' ',$css_class,$add_class)) unless ($add_class eq '');
  return  '<tr class="'.$css_class.'">'."\n";;          $id = (' id="'.$id.'"') unless ($id eq '');
           return  '<tr class="'.$css_class.'"'.$id.'>'."\n";
     }      }
           
     sub continue_data_table_row {      sub continue_data_table_row {
  my ($add_class) = @_;   my ($add_class, $id) = @_;
  my $css_class = ($row_count[0] % 2)?'LC_odd_row':'LC_even_row';   my $css_class = ($row_count[0] % 2)?'LC_odd_row':'LC_even_row';
  $css_class = (join(' ',$css_class,$add_class));   $css_class = (join(' ',$css_class,$add_class)) unless ($add_class eq '');
  return  '<tr class="'.$css_class.'">'."\n";;          $id = (' id="'.$id.'"') unless ($id eq '');
           return  '<tr class="'.$css_class.'"'.$id.'>'."\n";
     }      }
   
     sub end_data_table_row {      sub end_data_table_row {
Line 6703  sub simple_error_page { Line 7044  sub simple_error_page {
     sub end_data_table_header_row {      sub end_data_table_header_row {
  return '</tr>'."\n";;   return '</tr>'."\n";;
     }      }
   
       sub data_table_caption {
           my $caption = shift;
           return "<caption class=\"LC_caption\">$caption</caption>";
       }
 }  }
   
 =pod  =pod
Line 6773  sub get_users_function { Line 7119  sub get_users_function {
     if ($env{'request.role'}=~/^(st)/) {      if ($env{'request.role'}=~/^(st)/) {
         $function='student';          $function='student';
     }      }
     if ($env{'request.role'}=~/^(cc|in|ta|ep)/) {      if ($env{'request.role'}=~/^(cc|co|in|ta|ep)/) {
         $function='coordinator';          $function='coordinator';
     }      }
     if ($env{'request.role'}=~/^(su|dc|ad|li)/) {      if ($env{'request.role'}=~/^(su|dc|ad|li)/) {
         $function='admin';          $function='admin';
     }      }
     if (($env{'request.role'}=~/^(au|ca|aa)/) ||      if (($env{'request.role'}=~/^(au|ca|aa)/) ||
         ($ENV{'REQUEST_URI'}=~/^(\/priv|\~)/)) {          ($ENV{'REQUEST_URI'}=~ m{/^(/priv)})) {
         $function='author';          $function='author';
     }      }
     return $function;      return $function;
Line 6838  role status: active, previous or future. Line 7184  role status: active, previous or future.
   
 sub check_user_status {  sub check_user_status {
     my ($udom,$uname,$cdom,$crs,$role,$sec) = @_;      my ($udom,$uname,$cdom,$crs,$role,$sec) = @_;
     my %userinfo = &Apache::lonnet::dump('roles',$udom,$uname);      my $extra = &Apache::lonnet::freeze_escape({'skipcheck' => 1});
       my %userinfo = &Apache::lonnet::dump('roles',$udom,$uname,'.',undef,$extra);
     my @uroles = keys %userinfo;      my @uroles = keys %userinfo;
     my $srchstr;      my $srchstr;
     my $active_chk = 'none';      my $active_chk = 'none';
     my $now = time;      my $now = time;
     if (@uroles > 0) {      if (@uroles > 0) {
         if (($role eq 'cc') || ($sec eq '') || (!defined($sec))) {          if (($role eq 'cc') || ($role eq 'co') || ($sec eq '') || (!defined($sec))) {
             $srchstr = '/'.$cdom.'/'.$crs.'_'.$role;              $srchstr = '/'.$cdom.'/'.$crs.'_'.$role;
         } else {          } else {
             $srchstr = '/'.$cdom.'/'.$crs.'/'.$sec.'_'.$role;              $srchstr = '/'.$cdom.'/'.$crs.'/'.$sec.'_'.$role;
Line 7421  sub get_secgrprole_info { Line 7768  sub get_secgrprole_info {
 }  }
   
 sub user_picker {  sub user_picker {
     my ($dom,$srch,$forcenewuser,$caller,$cancreate,$usertype) = @_;      my ($dom,$srch,$forcenewuser,$caller,$cancreate,$usertype,$context) = @_;
     my $currdom = $dom;      my $currdom = $dom;
     my %curr_selected = (      my %curr_selected = (
                         srchin => 'dom',                          srchin => 'dom',
Line 7475  sub user_picker { Line 7822  sub user_picker {
         #       loncreateuser::print_user_query_page()          #       loncreateuser::print_user_query_page()
         #       has been completed.          #       has been completed.
         next if ($option eq 'alc');          next if ($option eq 'alc');
           next if (($option eq 'crs') && ($env{'form.form'} eq 'requestcrs'));  
         next if ($option eq 'crs' && !$env{'request.course.id'});          next if ($option eq 'crs' && !$env{'request.course.id'});
         if ($curr_selected{'srchin'} eq $option) {          if ($curr_selected{'srchin'} eq $option) {
             $srchinsel .= '               $srchinsel .= ' 
Line 7511  sub user_picker { Line 7859  sub user_picker {
     $srchtypesel .= "\n  </select>\n";      $srchtypesel .= "\n  </select>\n";
   
     my ($newuserscript,$new_user_create);      my ($newuserscript,$new_user_create);
       my $context_dom = $env{'request.role.domain'};
       if ($context eq 'requestcrs') {
           if ($env{'form.coursedom'} ne '') { 
               $context_dom = $env{'form.coursedom'};
           }
       }
     if ($forcenewuser) {      if ($forcenewuser) {
         if (ref($srch) eq 'HASH') {          if (ref($srch) eq 'HASH') {
             if ($srch->{'srchby'} eq 'uname' && $srch->{'srchtype'} eq 'exact' && $srch->{'srchin'} eq 'dom' && $srch->{'srchdomain'} eq $env{'request.role.domain'}) {              if ($srch->{'srchby'} eq 'uname' && $srch->{'srchtype'} eq 'exact' && $srch->{'srchin'} eq 'dom' && $srch->{'srchdomain'} eq $context_dom) {
                 if ($cancreate) {                  if ($cancreate) {
                     $new_user_create = '<p> <input type="submit" name="forcenew" value="'.&HTML::Entities::encode(&mt('Make new user "[_1]"',$srchterm),'<>&"').'" onclick="javascript:setSearch(\'1\','.$caller.');" /> </p>';                      $new_user_create = '<p> <input type="submit" name="forcenew" value="'.&HTML::Entities::encode(&mt('Make new user "[_1]"',$srchterm),'<>&"').'" onclick="javascript:setSearch(\'1\','.$caller.');" /> </p>';
                 } else {                  } else {
Line 7553  function setSearch(createnew,callingForm Line 7906  function setSearch(createnew,callingForm
             }              }
         }          }
         for (var i=0; i<callingForm.srchdomain.length; i++) {          for (var i=0; i<callingForm.srchdomain.length; i++) {
             if (callingForm.srchdomain.options[i].value == '$env{'request.role.domain'}') {              if (callingForm.srchdomain.options[i].value == '$context_dom') {
                 callingForm.srchdomain.selectedIndex = i;                  callingForm.srchdomain.selectedIndex = i;
             }              }
         }          }
Line 7639  $newuserscript Line 7992  $newuserscript
   
 $new_user_create  $new_user_create
   
 <table>  
  <tr>  
   <td>$lt{'doma'}:</td>  
   <td>$domform</td>  
   </td>  
  </tr>  
  <tr>  
   <td>$lt{'usr'}:</td>  
   <td>$srchbysel  
       $srchtypesel   
       <input type="text" size="15" name="srchterm" value="$srchterm" />  
       $srchinsel   
   </td>  
  </tr>  
 </table>  
 <br />  
 END_BLOCK  END_BLOCK
   
       $output .= &Apache::lonhtmlcommon::start_pick_box().
                  &Apache::lonhtmlcommon::row_title($lt{'doma'}).
                  $domform.
                  &Apache::lonhtmlcommon::row_closure().
                  &Apache::lonhtmlcommon::row_title($lt{'usr'}).
                  $srchbysel.
                  $srchtypesel. 
                  '<input type="text" size="15" name="srchterm" value="'.$srchterm.'" />'.
                  $srchinsel.
                  &Apache::lonhtmlcommon::row_closure(1)
                  &Apache::lonhtmlcommon::end_pick_box().
                  '<br />';
     return $output;      return $output;
 }  }
   
Line 7880  sub get_institutional_codes { Line 8229  sub get_institutional_codes {
     return;      return;
 }  }
   
   sub get_standard_codeitems {
       return ('Year','Semester','Department','Number','Section');
   }
   
 =pod  =pod
   
 =head1 Slot Helpers  =head1 Slot Helpers
Line 8071  sub get_env_multiple { Line 8424  sub get_env_multiple {
   
 sub ask_for_embedded_content {  sub ask_for_embedded_content {
     my ($actionurl,$state,$allfiles,$codebase,$args)=@_;      my ($actionurl,$state,$allfiles,$codebase,$args)=@_;
     my $upload_output = '      my (%subdependencies,%dependencies,%mapping,%existing,%newfiles,%pathchanges);
    <form name="upload_embedded" action="'.$actionurl.'"  
                   method="post" enctype="multipart/form-data">';  
     $upload_output .= $state;  
     $upload_output .= '<b>Upload embedded files</b>:<br />'.&start_data_table();  
   
     my $num = 0;      my $num = 0;
     foreach my $embed_file (sort {lc($a) cmp lc($b)} keys(%{$allfiles})) {      my $numremref = 0;
       my $numinvalid = 0;
       my $numpathchg = 0;
       my $numexisting = 0;
       my ($output,$upload_output,$toplevel,$url,$udom,$uname,$getpropath);
       if (($actionurl eq '/adm/portfolio') || ($actionurl eq '/adm/coursegrp_portfolio')) {
           my $current_path='/';
           if ($env{'form.currentpath'}) {
               $current_path = $env{'form.currentpath'};
           }
           if ($actionurl eq '/adm/coursegrp_portfolio') {
               $udom = $env{'course.'.$env{'request.course.id'}.'.domain'};
               $uname = $env{'course.'.$env{'request.course.id'}.'.num'};
               $url = '/userfiles/groups/'.$env{'form.group'}.'/portfolio';
           } else {
               $udom = $env{'user.domain'};
               $uname = $env{'user.name'};
               $url = '/userfiles/portfolio';
           }
           $toplevel = $url.'/';
           $url .= $current_path;
           $getpropath = 1;
       } elsif (($actionurl eq '/adm/upload') || ($actionurl eq '/adm/testbank') ||
                ($actionurl eq '/adm/imsimport')) { 
           my ($udom,$uname,$rest) = ($args->{'current_path'} =~ m{/priv/($match_domain)/($match_username)/?(.*)$});
           $url = '/home/httpd/html/priv/'.$udom.'/'.$uname.'/';
           $toplevel = $url;
           if ($rest ne '') {
               $url .= $rest;
           }
       } elsif ($actionurl eq '/adm/coursedocs') {
           if (ref($args) eq 'HASH') {
              $url = $args->{'docs_url'};
              $toplevel = $url;
           }
       }
       my $now = time();
       foreach my $embed_file (keys(%{$allfiles})) {
           my $absolutepath;
           if ($embed_file =~ m{^\w+://}) {
               $newfiles{$embed_file} = 1;
               $mapping{$embed_file} = $embed_file;
           } else {
               if ($embed_file =~ m{^/}) {
                   $absolutepath = $embed_file;
                   $embed_file =~ s{^(/+)}{};
               }
               if ($embed_file =~ m{/}) {
                   my ($path,$fname) = ($embed_file =~ m{^(.+)/([^/]*)$});
                   $path = &check_for_traversal($path,$url,$toplevel);
                   my $item = $fname;
                   if ($path ne '') {
                       $item = $path.'/'.$fname;
                       $subdependencies{$path}{$fname} = 1;
                   } else {
                       $dependencies{$item} = 1;
                   }
                   if ($absolutepath) {
                       $mapping{$item} = $absolutepath;
                   } else {
                       $mapping{$item} = $embed_file;
                   }
               } else {
                   $dependencies{$embed_file} = 1;
                   if ($absolutepath) {
                       $mapping{$embed_file} = $absolutepath;
                   } else {
                       $mapping{$embed_file} = $embed_file;
                   }
               }
           }
       }
       foreach my $path (keys(%subdependencies)) {
           my %currsubfile;
           if (($actionurl eq '/adm/portfolio') || ($actionurl eq '/adm/coursegrp_portfolio')) { 
               my ($sublistref,$listerror) =
                   &Apache::lonnet::dirlist($url.$path,$udom,$uname,$getpropath);
               if (ref($sublistref) eq 'ARRAY') {
                   foreach my $line (@{$sublistref}) {
                       my ($file_name,$rest) = split(/\&/,$line,2);
                       $currsubfile{$file_name} = 1;
                   }
               }
           } elsif (($actionurl eq '/adm/upload') || ($actionurl eq '/adm/testbank')) {
               if (opendir(my $dir,$url.'/'.$path)) {
                   my @subdir_list = grep(!/^\./,readdir($dir));
                   map {$currsubfile{$_} = 1;} @subdir_list;
               }
           }
           foreach my $file (keys(%{$subdependencies{$path}})) {
               if ($currsubfile{$file}) {
                   my $item = $path.'/'.$file;
                   unless ($mapping{$item} eq $item) {
                       $pathchanges{$item} = 1;
                   }
                   $existing{$item} = 1;
                   $numexisting ++;
               } else {
                   $newfiles{$path.'/'.$file} = 1;
               }
           }
       }
       my %currfile;
       if (($actionurl eq '/adm/portfolio') || ($actionurl eq '/adm/coursegrp_portfolio')) {
           my ($dirlistref,$listerror) =
               &Apache::lonnet::dirlist($url,$udom,$uname,$getpropath);
           if (ref($dirlistref) eq 'ARRAY') {
               foreach my $line (@{$dirlistref}) {
                   my ($file_name,$rest) = split(/\&/,$line,2);
                   $currfile{$file_name} = 1;
               }
           }
       } elsif (($actionurl eq '/adm/upload') || ($actionurl eq '/adm/testbank')) {
           if (opendir(my $dir,$url)) {
               my @dir_list = grep(!/^\./,readdir($dir));
               map {$currfile{$_} = 1;} @dir_list;
           }
       }
       foreach my $file (keys(%dependencies)) {
           if ($currfile{$file}) {
               unless ($mapping{$file} eq $file) {
                   $pathchanges{$file} = 1;
               }
               $existing{$file} = 1;
               $numexisting ++;
           } else {
               $newfiles{$file} = 1;
           }
       }
       foreach my $embed_file (sort {lc($a) cmp lc($b)} keys(%newfiles)) {
         $upload_output .= &start_data_table_row().          $upload_output .= &start_data_table_row().
             '<td>'.$embed_file.'</td><td>';                            '<td><span class="LC_filename">'.$embed_file.'</span>';
           unless ($mapping{$embed_file} eq $embed_file) {
               $upload_output .= '<br /><span class="LC_info" style="font-size:smaller;">'.&mt('changed from: [_1]',$mapping{$embed_file}).'</span>';
           }
           $upload_output .= '</td><td>';
         if ($args->{'ignore_remote_references'}          if ($args->{'ignore_remote_references'}
             && $embed_file =~ m{^\w+://}) {              && $embed_file =~ m{^\w+://}) {
             $upload_output.='<span class="LC_warning">'.&mt("URL points to other server.").'</span>';              $upload_output.='<span class="LC_warning">'.&mt("URL points to other server.").'</span>';
               $numremref++;
         } elsif ($args->{'error_on_invalid_names'}          } elsif ($args->{'error_on_invalid_names'}
             && $embed_file ne &Apache::lonnet::clean_filename($embed_file,{'keep_path' => 1,})) {              && $embed_file ne &Apache::lonnet::clean_filename($embed_file,{'keep_path' => 1,})) {
   
             $upload_output.='<span class="LC_warning">'.&mt("Invalid characters").'</span>';              $upload_output.='<span class="LC_warning">'.&mt('Invalid characters').'</span>';
               $numinvalid++;
         } else {          } else {
             $upload_output .='              $upload_output .= &embedded_file_element('upload_embedded',$num,
            <input name="embedded_item_'.$num.'" type="file" value="" />                                                       $embed_file,\%mapping,
            <input name="embedded_orig_'.$num.'" type="hidden" value="'.&escape($embed_file).'" />';                                                       $allfiles,$codebase);
             my $attrib = join(':',@{$$allfiles{$embed_file}});              $num++;
             $upload_output .=          }
                 "\n\t\t".          $upload_output .= '</td>'.&Apache::loncommon::end_data_table_row()."\n";
                 '<input name="embedded_attrib_'.$num.'" type="hidden" value="'.      }
                 $attrib.'" />';      foreach my $embed_file (sort {lc($a) cmp lc($b)} keys(%existing)) {
             if (exists($$codebase{$embed_file})) {          $upload_output .= &start_data_table_row().
                 $upload_output .=                            '<td><span class="LC_filename">'.$embed_file.'</span></td>'.
                     "\n\t\t".                            '<td><span class="LC_warning">'.&mt('Already exists').'</span></td>'.
                     '<input name="codebase_'.$num.'" type="hidden" value="'.                            &Apache::loncommon::end_data_table_row()."\n";
                     &escape($$codebase{$embed_file}).'" />';      }
             }      if ($upload_output) {
         }          $upload_output = &start_data_table().
         $upload_output .= '</td>'.&Apache::loncommon::end_data_table_row();                           $upload_output.
         $num++;                           &end_data_table()."\n";
     }      }
     $upload_output .= &Apache::loncommon::end_data_table().'<br />      my $applies = 0;
    <input type ="hidden" name="number_embedded_items" value="'.$num.'" />      if ($numremref) {
    <input type ="submit" value="'.&mt('Upload Listed Files').'" />          $applies ++;
    '.&mt('(only files for which a location has been provided will be uploaded)').'      }
    </form>';      if ($numinvalid) {
     return $upload_output;          $applies ++;
       }
       if ($numexisting) {
           $applies ++;
       }
       if ($num) {
           $output = '<form name="upload_embedded" action="'.$actionurl.'"'.
                     ' method="post" enctype="multipart/form-data">'."\n".
                     $state.
                     '<h3>'.&mt('Upload embedded files').
                     ':</h3>'.$upload_output.'<br />'."\n".
                     '<input type ="hidden" name="number_embedded_items" value="'.
                     $num.'" />'."\n";
           if ($actionurl eq '') {
               $output .=  '<input type="hidden" name="phase" value="three" />';
           }
       } elsif ($applies) {
           $output = '<b>'.&mt('Referenced files').'</b>:<br />';
           if ($applies > 1) {
               $output .=  
                   &mt('No files need to be uploaded, as one of the following applies to each reference:').'<ul>';
               if ($numremref) {
                   $output .= '<li>'.&mt('reference is to a URL which points to another server').'</li>'."\n";
               }
               if ($numinvalid) {
                   $output .= '<li>'.&mt('reference is to file with a name containing invalid characters').'</li>'."\n";
               }
               if ($numexisting) {
                   $output .= '<li>'.&mt('reference is to an existing file at the specified location').'</li>'."\n";
               }
               $output .= '</ul><br />';
           } elsif ($numremref) {
               $output .= '<p>'.&mt('None to upload, as all references are to URLs pointing to another server.').'</p>';
           } elsif ($numinvalid) {
               $output .= '<p>'.&mt('None to upload, as all references are to files with names containing invalid characters.').'</p>';
           } elsif ($numexisting) {
               $output .= '<p>'.&mt('None to upload, as all references are to existing files.').'</p>';
           }
           $output .= $upload_output.'<br />';
       }
       my ($pathchange_output,$chgcount);
       $chgcount = $num;
       if (keys(%pathchanges) > 0) {
           foreach my $embed_file (sort {lc($a) cmp lc($b)} keys(%pathchanges)) {
               if ($num) {
                   $output .= &embedded_file_element('pathchange',$chgcount,
                                                     $embed_file,\%mapping,
                                                     $allfiles,$codebase);
               } else {
                   $pathchange_output .= 
                       &start_data_table_row().
                       '<td><input type ="checkbox" name="namechange" value="'.
                       $chgcount.'" checked="checked" /></td>'.
                       '<td>'.$mapping{$embed_file}.'</td>'.
                       '<td>'.$embed_file.
                       &embedded_file_element('pathchange',$numpathchg,$embed_file,
                                              \%mapping,$allfiles,$codebase).
                       '</td>'.&end_data_table_row();
               }
               $numpathchg ++;
               $chgcount ++;
           }
       }
       if ($num) {
           if ($numpathchg) {
               $output .= '<input type ="hidden" name="number_pathchange_items" value="'.
                          $numpathchg.'" />'."\n";
           }
           if (($actionurl eq '/adm/upload') || ($actionurl eq '/adm/testbank') || 
               ($actionurl eq '/adm/imsimport')) {
               $output .= '<input type="hidden" name="phase" value="three" />'."\n";
           } elsif ($actionurl eq '/adm/portfolio' || $actionurl eq '/adm/coursegrp_portfolio') {
               $output .= '<input type="hidden" name="action" value="upload_embedded" />';
           }
           $output .=  '<input type ="submit" value="'.&mt('Upload Listed Files').'" />'."\n".
                       &mt('(only files for which a location has been provided will be uploaded)').'</form>'."\n";
       } elsif ($numpathchg) {
           my %pathchange = ();
           $output .= &modify_html_form('pathchange',$actionurl,$state,\%pathchange,$pathchange_output);
           if (($actionurl eq '/adm/portfolio') || ($actionurl eq '/adm/coursegrp_portfolio')) {
               $output .= '<p>'.&mt('or').'</p>'; 
           } 
       }
       return ($output,$num,$numpathchg);
   }
   
   sub embedded_file_element {
       my ($context,$num,$embed_file,$mapping,$allfiles,$codebase) = @_;
       return unless ((ref($mapping) eq 'HASH') && (ref($allfiles) eq 'HASH') &&
                      (ref($codebase) eq 'HASH'));
       my $output;
       if ($context eq 'upload_embedded') {
          $output = '<input name="embedded_item_'.$num.'" type="file" value="" />'."\n";
       }
       $output .= '<input name="embedded_orig_'.$num.'" type="hidden" value="'.
                  &escape($embed_file).'" />';
       unless (($context eq 'upload_embedded') && 
               ($mapping->{$embed_file} eq $embed_file)) {
           $output .='
           <input name="embedded_ref_'.$num.'" type="hidden" value="'.&escape($mapping->{$embed_file}).'" />';
       }
       my $attrib;
       if (ref($allfiles->{$mapping->{$embed_file}}) eq 'ARRAY') {
           $attrib = &escape(join(':',@{$allfiles->{$mapping->{$embed_file}}}));
       }
       $output .=
           "\n\t\t".
           '<input name="embedded_attrib_'.$num.'" type="hidden" value="'.
           $attrib.'" />';
       if (exists($codebase->{$mapping->{$embed_file}})) {
           $output .=
               "\n\t\t".
               '<input name="codebase_'.$num.'" type="hidden" value="'.
               &escape($codebase->{$mapping->{$embed_file}}).'" />';
       }
       return $output;
 }  }
   
 sub upload_embedded {  sub upload_embedded {
     my ($context,$dirpath,$uname,$udom,$dir_root,$url_root,$group,$disk_quota,      my ($context,$dirpath,$uname,$udom,$dir_root,$url_root,$group,$disk_quota,
         $current_disk_usage) = @_;          $current_disk_usage,$hiddenstate,$actionurl) = @_;
     my $output;      my (%pathchange,$output,$modifyform,$footer,$returnflag);
     for (my $i=0; $i<$env{'form.number_embedded_items'}; $i++) {      for (my $i=0; $i<$env{'form.number_embedded_items'}; $i++) {
         next if (!exists($env{'form.embedded_item_'.$i.'.filename'}));          next if (!exists($env{'form.embedded_item_'.$i.'.filename'}));
         my $orig_uploaded_filename =          my $orig_uploaded_filename =
             $env{'form.embedded_item_'.$i.'.filename'};              $env{'form.embedded_item_'.$i.'.filename'};
           foreach my $type ('orig','ref','attrib','codebase') {
         $env{'form.embedded_orig_'.$i} =              if ($env{'form.embedded_'.$type.'_'.$i} ne '') {
             &unescape($env{'form.embedded_orig_'.$i});                  $env{'form.embedded_'.$type.'_'.$i} =
                       &unescape($env{'form.embedded_'.$type.'_'.$i});
               }
           }
         my ($path,$fname) =          my ($path,$fname) =
             ($env{'form.embedded_orig_'.$i} =~ m{(.*/)([^/]*)});              ($env{'form.embedded_orig_'.$i} =~ m{(.*/)([^/]*)});
         # no path, whole string is fname          # no path, whole string is fname
         if (!$fname) { $fname = $env{'form.embedded_orig_'.$i} };          if (!$fname) { $fname = $env{'form.embedded_orig_'.$i} };
   
         $path = $env{'form.currentpath'}.$path;  
         $fname = &Apache::lonnet::clean_filename($fname);          $fname = &Apache::lonnet::clean_filename($fname);
         # See if there is anything left          # See if there is anything left
         next if ($fname eq '');          next if ($fname eq '');
Line 8144  sub upload_embedded { Line 8742  sub upload_embedded {
             if ($group ne '') {              if ($group ne '') {
                 $port_path = "groups/$group/$port_path";                  $port_path = "groups/$group/$port_path";
             }              }
             ($state,$msg) = &check_for_upload($path,$fname,$group,'embedded_item_'.$i,              ($state,$msg) = &check_for_upload($env{'form.currentpath'}.$path,
                                                 $fname,$group,'embedded_item_'.$i,
                                               $dir_root,$port_path,$disk_quota,                                                $dir_root,$port_path,$disk_quota,
                                               $current_disk_usage,$uname,$udom);                                                $current_disk_usage,$uname,$udom);
             if ($state eq 'will_exceed_quota'              if ($state eq 'will_exceed_quota'
                 || $state eq 'file_locked'                  || $state eq 'file_locked') {
                 || $state eq 'file_exists' ) {  
                 $output .= $msg;                  $output .= $msg;
                 next;                  next;
             }              }
Line 8163  sub upload_embedded { Line 8761  sub upload_embedded {
         # Check if extension is valid          # Check if extension is valid
         if (($fname =~ /\.(\w+)$/) &&          if (($fname =~ /\.(\w+)$/) &&
             (&Apache::loncommon::fileembstyle($1) eq 'hdn')) {              (&Apache::loncommon::fileembstyle($1) eq 'hdn')) {
             $output .= &mt('Invalid file extension ([_1]) - reserved for LONCAPA use - rename the file with a different extension and re-upload. ',$1);              $output .= &mt('Invalid file extension ([_1]) - reserved for LONCAPA use - rename the file with a different extension and re-upload. ',$1).'<br />';
             next;              next;
         } elsif (($fname =~ /\.(\w+)$/) &&          } elsif (($fname =~ /\.(\w+)$/) &&
                  (!defined(&Apache::loncommon::fileembstyle($1)))) {                   (!defined(&Apache::loncommon::fileembstyle($1)))) {
             $output .= &mt('Unrecognized file extension ([_1]) - rename the file with a proper extension and re-upload.',$1);              $output .= &mt('Unrecognized file extension ([_1]) - rename the file with a proper extension and re-upload.',$1).'<br />';
             next;              next;
         } elsif ($fname=~/\.(\d+)\.(\w+)$/) {          } elsif ($fname=~/\.(\d+)\.(\w+)$/) {
             $output .= &mt('File name not allowed - rename the file to remove the number immediately before the file extension([_1]) and re-upload.',$2);              $output .= &mt('File name not allowed - rename the file to remove the number immediately before the file extension([_1]) and re-upload.',$2).'<br />';
             next;              next;
         }          }
   
         $env{'form.embedded_item_'.$i.'.filename'}=$fname;          $env{'form.embedded_item_'.$i.'.filename'}=$fname;
         if ($context eq 'portfolio') {          if ($context eq 'portfolio') {
             my $result=              my $result;
                 &Apache::lonnet::userfileupload('embedded_item_'.$i,'',              if ($state eq 'existingfile') {
                                                 $dirpath.$path);                  $result=
                       &Apache::lonnet::userfileupload('embedded_item_'.$i,'existingfile',
                                                       $dirpath.$env{'form.currentpath'}.$path);
               } else {
                   $result=
                       &Apache::lonnet::userfileupload('embedded_item_'.$i,'',
                                                       $dirpath.
                                                       $env{'form.currentpath'}.$path);
                   if ($result !~ m|^/uploaded/|) {
                       $output .= '<span class="LC_error">'
                                  .&mt('An error occurred ([_1]) while trying to upload [_2] for embedded element [_3].'
                                  ,$result,$orig_uploaded_filename,$env{'form.embedded_orig_'.$i})
                                  .'</span><br />';
                       next;
                   } else {
                       $output .= &mt('Uploaded [_1]','<span class="LC_filename">'.
                                  $path.$fname.'</span>').'<br />';     
                   }
               }
           } elsif ($context eq 'coursedoc') {
               my $result =
                   &Apache::lonnet::userfileupload('embedded_item_'.$i,'coursedoc',
                                                   $dirpath.'/'.$path);
             if ($result !~ m|^/uploaded/|) {              if ($result !~ m|^/uploaded/|) {
                 $output .= '<span class="LC_error">'                  $output .= '<span class="LC_error">'
                       .&mt('An error occurred ([_1]) while trying to upload [_2] for embedded element [_3].'                             .&mt('An error occurred ([_1]) while trying to upload [_2] for embedded element [_3].'
                            ,$result,$orig_uploaded_filename,$env{'form.embedded_orig_'.$i})                             ,$result,$orig_uploaded_filename,$env{'form.embedded_orig_'.$i})
                       .'</span><br />';                             .'</span><br />';
                 next;                      next;
             } else {              } else {
                 $output .= '<p>'.&mt('Uploaded [_1]','<span class="LC_filename">'.                  $output .= &mt('Uploaded [_1]','<span class="LC_filename">'.
                            $path.$fname.'</span>').'</p>';                                  $path.$fname.'</span>').'<br />';
             }              }
         } else {          } else {
 # Save the file  # Save the file
Line 8217  sub upload_embedded { Line 8837  sub upload_embedded {
                               &mt('An error occurred while writing the file [_1] for embedded element [_2].',$orig_uploaded_filename,$env{'form.embedded_orig_'.$i}).                                &mt('An error occurred while writing the file [_1] for embedded element [_2].',$orig_uploaded_filename,$env{'form.embedded_orig_'.$i}).
                               '</span><br />';                                '</span><br />';
                 } else {                  } else {
                     if ($context eq 'testbank') {                      $output .= &mt('Uploaded [_1]','<span class="LC_filename">'.
                         $output .= &mt('Embedded file uploaded successfully:').                                 $url.'</span>').'<br />';
                                    '&nbsp;<a href="'.$url.'">'.                      unless ($context eq 'testbank') {
                                    $orig_uploaded_filename.'</a><br />';                          $footer .= &mt('View embedded file: [_1]',
                     } else {                                         '<a href="'.$url.'">'.$fname.'</a>').'<br />';
                         $output .= '<span class=\"LC_fontsize_large\">'.  
                                    &mt('View embedded file: [_1]','<a href="'.$url.'">'.  
                                    $orig_uploaded_filename.'</a>').'</span><br />';  
                     }                      }
                 }                  }
                 close($fh);                  close($fh);
             }              }
         }          }
           if ($env{'form.embedded_ref_'.$i}) {
               $pathchange{$i} = 1;
           }
       }
       if ($output) {
           $output = '<p>'.$output.'</p>';
       }
       $output .= &modify_html_form('upload_embedded',$actionurl,$hiddenstate,\%pathchange);
       $returnflag = 'ok';
       if (keys(%pathchange) > 0) {
           if ($context eq 'portfolio') {
               $output .= '<p>'.&mt('or').'</p>';
           } elsif ($context eq 'testbank') {
               $output .=  '<p>'.&mt('Or [_1]continue[_2] the testbank import without modifying the reference(s).','<a href="javascript:document.testbankForm.submit();">','</a>').'</p>';
               $returnflag = 'modify_orightml';
           }
       }
       return ($output.$footer,$returnflag);
   }
   
   sub modify_html_form {
       my ($context,$actionurl,$hiddenstate,$pathchange,$pathchgtable) = @_;
       my $end = 0;
       my $modifyform;
       if ($context eq 'upload_embedded') {
           return unless (ref($pathchange) eq 'HASH');
           if ($env{'form.number_embedded_items'}) {
               $end += $env{'form.number_embedded_items'};
           }
           if ($env{'form.number_pathchange_items'}) {
               $end += $env{'form.number_pathchange_items'};
           }
           if ($end) {
               for (my $i=0; $i<$end; $i++) {
                   if ($i < $env{'form.number_embedded_items'}) {
                       next unless($pathchange->{$i});
                   }
                   $modifyform .=
                       &start_data_table_row().
                       '<td><input type ="checkbox" name="namechange" value="'.$i.'" '.
                       'checked="checked" /></td>'.
                       '<td>'.$env{'form.embedded_ref_'.$i}.
                       '<input type="hidden" name="embedded_ref_'.$i.'" value="'.
                       &escape($env{'form.embedded_ref_'.$i}).'" />'.
                       '<input type="hidden" name="embedded_codebase_'.$i.'" value="'.
                       &escape($env{'form.embedded_codebase_'.$i}).'" />'.
                       '<input type="hidden" name="embedded_attrib_'.$i.'" value="'.
                       &escape($env{'form.embedded_attrib_'.$i}).'" /></td>'.
                       '<td>'.$env{'form.embedded_orig_'.$i}.
                       '<input type="hidden" name="embedded_orig_'.$i.'" value="'.
                       &escape($env{'form.embedded_orig_'.$i}).'" /></td>'.
                       &end_data_table_row();
               } 
           }
       } else {
           $modifyform = $pathchgtable;
           if (($actionurl eq '/adm/upload') || ($actionurl eq '/adm/testbank')) {
               $hiddenstate .= '<input type="hidden" name="phase" value="four" />';
           } elsif (($actionurl eq '/adm/portfolio') || ($actionurl eq '/adm/coursegrp_portfolio')) {
               $hiddenstate .= '<input type="hidden" name="action" value="modify_orightml" />';
           }
       }
       if ($modifyform) {
           return '<h3>'.&mt('Changes in content of HTML file required').'</h3>'."\n".
                  '<p>'.&mt('Changes need to be made to the reference(s) used for one or more of the dependencies, if your HTML file is to work correctly:').'<ol>'."\n".
                  '<li>'.&mt('For consistency between the reference(s) and the location of the corresponding stored file within LON-CAPA.').'</li>'."\n".
                  '<li>'.&mt('To change absolute paths to relative paths, or replace directory traversal via "../" within the original reference.').'</li>'."\n".
                  '</ol></p>'."\n".'<p>'.
                  &mt('LON-CAPA can make the required changes to your HTML file.').'</p>'."\n".
                  '<form method="post" name="refchanger" action="'.$actionurl.'">'.
                  &start_data_table()."\n".
                  &start_data_table_header_row().
                  '<th>'.&mt('Change?').'</th>'.
                  '<th>'.&mt('Current reference').'</th>'.
                  '<th>'.&mt('Required reference').'</th>'.
                  &end_data_table_header_row()."\n".
                  $modifyform.
                  &end_data_table().'<br />'."\n".$hiddenstate.
                  '<input type="submit" name="pathchanges" value="'.&mt('Modify HTML file').'" />'.
                  '</form>'."\n";
       }
       return;
   }
   
   sub modify_html_refs {
       my ($context,$dirpath,$uname,$udom,$dir_root) = @_;
       my $container;
       if ($context eq 'portfolio') {
           $container = $env{'form.container'};
       } elsif ($context eq 'coursedoc') {
           $container = $env{'form.primaryurl'};
       } else {
           $container = $env{'form.filename'};
       }
       my (%allfiles,%codebase,$output,$content);
       my @changes = &get_env_multiple('form.namechange');
       return unless (@changes > 0);
       if (($context eq 'portfolio') || ($context eq 'coursedoc')) {
           return unless ($container =~ m{^/uploaded/\Q$udom\E/\Q$uname\E/});
           $content = &Apache::lonnet::getfile($container);
           return if ($content eq '-1');
       } else {
           return unless ($container =~ /^\Q$dir_root\E/); 
           if (open(my $fh,"<$container")) {
               $content = join('', <$fh>);
               close($fh);
           } else {
               return;
           }
       }
       my ($count,$codebasecount) = (0,0);
       my $mm = new File::MMagic;
       my $mime_type = $mm->checktype_contents($content);
       if ($mime_type eq 'text/html') {
           my $parse_result = 
               &Apache::lonnet::extract_embedded_items($container,\%allfiles,
                                                       \%codebase,\$content);
           if ($parse_result eq 'ok') {
               foreach my $i (@changes) {
                   my $orig = &unescape($env{'form.embedded_orig_'.$i});
                   my $ref = &unescape($env{'form.embedded_ref_'.$i});
                   if ($allfiles{$ref}) {
                       my $newname =  $orig;
                       my ($attrib_regexp,$codebase);
                       $attrib_regexp = &unescape($env{'form.embedded_attrib_'.$i});
                       if ($attrib_regexp =~ /:/) {
                           $attrib_regexp =~ s/\:/|/g;
                       }
                       if ($content =~ m{($attrib_regexp\s*=\s*['"]?)\Q$ref\E(['"]?)}) {
                           my $numchg = ($content =~ s{($attrib_regexp\s*=\s*['"]?)\Q$ref\E(['"]?)}{$1$newname$2}gi);
                           $count += $numchg;
                       }
                       if ($env{'form.embedded_codebase_'.$i} ne '') {
                           $codebase = &unescape($env{'form.embedded_codebase_'.$i});
                           my $numchg = ($content =~ s/(codebase\s*=\s*["']?)\Q$codebase\E(["']?)/$1.$2/i); #' stupid emacs
                           $codebasecount ++;
                       }
                   }
               }
               if ($count || $codebasecount) {
                   my $saveresult;
                   if ($context eq 'portfolio' || $context eq 'coursedoc') {
                       my $url = &Apache::lonnet::store_edited_file($container,$content,$udom,$uname,\$saveresult);
                       if ($url eq $container) {
                           my ($fname) = ($container =~ m{/([^/]+)$});
                           $output = '<p>'.&mt('Updated [quant,_1,reference] in [_2].',
                                               $count,'<span class="LC_filename">'.
                                               $fname.'</span>').'</p>'; 
                       } else {
                            $output = '<p class="LC_error">'.
                                      &mt('Error: update failed for: [_1].',
                                      '<span class="LC_filename">'.
                                      $container.'</span>').'</p>';
                       }
                   } else {
                       if (open(my $fh,">$container")) {
                           print $fh $content;
                           close($fh);
                           $output = '<p>'.&mt('Updated [quant,_1,reference] in [_2].',
                                     $count,'<span class="LC_filename">'.
                                     $container.'</span>').'</p>';
                       } else {
                            $output = '<p class="LC_error">'.
                                      &mt('Error: could not update [_1].',
                                      '<span class="LC_filename">'.
                                      $container.'</span>').'</p>';
                       }
                   }
               }
           } else {
               &logthis('Failed to parse '.$container.
                        ' to modify references: '.$parse_result);
           }
     }      }
     return $output;      return $output;
 }  }
Line 8253  sub check_for_existing { Line 9043  sub check_for_existing {
 sub check_for_upload {  sub check_for_upload {
     my ($path,$fname,$group,$element,$portfolio_root,$port_path,      my ($path,$fname,$group,$element,$portfolio_root,$port_path,
         $disk_quota,$current_disk_usage,$uname,$udom) = @_;          $disk_quota,$current_disk_usage,$uname,$udom) = @_;
     my $filesize = (length($env{'form.'.$element})) / 1000; #express in k (1024?)      my $filesize = length($env{'form.'.$element});
       if (!$filesize) {
           my $msg = '<span class="LC_error">'.
                     &mt('Unable to upload [_1]. (size = [_2] bytes)', 
                         '<span class="LC_filename">'.$fname.'</span>',
                         $filesize).'<br />'.
                     &mt('Either the file you attempted to upload was empty, or your web browser was unable to read its contents.').'<br />'.
                     '</span>';
           return ('zero_bytes',$msg);
       }
       $filesize =  $filesize/1000; #express in k (1024?)
     my $getpropath = 1;      my $getpropath = 1;
     my @dir_list = &Apache::lonnet::dirlist($portfolio_root.$path,$udom,$uname,      my ($dirlistref,$listerror) =
                                             $getpropath);           &Apache::lonnet::dirlist($portfolio_root.$path,$udom,$uname,$getpropath);
     my $found_file = 0;      my $found_file = 0;
     my $locked_file = 0;      my $locked_file = 0;
     foreach my $line (@dir_list) {      my @lockers;
         my ($file_name)=split(/\&/,$line,2);      my $navmap;
         if ($file_name eq $fname){      if ($env{'request.course.id'}) {
             $file_name = $path.$file_name;          $navmap = Apache::lonnavmaps::navmap->new();
             if ($group ne '') {      }
                 $file_name = $group.$file_name;      if (ref($dirlistref) eq 'ARRAY') {
             }          foreach my $line (@{$dirlistref}) {
             $found_file = 1;              my ($file_name,$rest)=split(/\&/,$line,2);
             if (&Apache::lonnet::is_locked($file_name,$udom,$uname) eq 'true') {              if ($file_name eq $fname){
                 $locked_file = 1;                  $file_name = $path.$file_name;
                   if ($group ne '') {
                       $file_name = $group.$file_name;
                   }
                   $found_file = 1;
                   if (&Apache::lonnet::is_locked($file_name,$udom,$uname,\@lockers) eq 'true') {
                       foreach my $lock (@lockers) {
                           if (ref($lock) eq 'ARRAY') {
                               my ($symb,$crsid) = @{$lock};
                               if ($crsid eq $env{'request.course.id'}) {
                                   if (ref($navmap)) {
                                       my $res = $navmap->getBySymb($symb);
                                       foreach my $part (@{$res->parts()}) { 
                                           my ($slot_status,$slot_time,$slot_name)=$res->check_for_slot($part);
                                           unless (($slot_status == $res->RESERVED) ||
                                                   ($slot_status == $res->RESERVED_LOCATION)) {
                                               $locked_file = 1;
                                           }
                                       }
                                   } else {
                                       $locked_file = 1;
                                   }
                               } else {
                                   $locked_file = 1;
                               }
                           }
                      }
                   } else {
                       my @info = split(/\&/,$rest);
                       my $currsize = $info[6]/1000;
                       if ($currsize < $filesize) {
                           my $extra = $filesize - $currsize;
                           if (($current_disk_usage + $extra) > $disk_quota) {
                               my $msg = '<span class="LC_error">'.
                                         &mt('Unable to upload [_1]. (size = [_2] kilobytes). Disk quota will be exceeded if existing (smaller) file with same name (size = [_3] kilobytes) is replaced.',
                                             '<span class="LC_filename">'.$fname.'</span>',$filesize,$currsize).'</span>'.
                                         '<br />'.&mt('Disk quota is [_1] kilobytes. Your current disk usage is [_2] kilobytes.',
                                                      $disk_quota,$current_disk_usage);
                               return ('will_exceed_quota',$msg);
                           }
                       }
                   }
             }              }
         }          }
     }      }
Line 8286  sub check_for_upload { Line 9127  sub check_for_upload {
             return ('file_locked',$msg);              return ('file_locked',$msg);
         } else {          } else {
             my $msg = '<span class="LC_error">';              my $msg = '<span class="LC_error">';
             $msg .= &mt('Unable to upload [_1]. A file by that name was found in [_2].','<span class="LC_filename">'.$fname.'</span>',$port_path.$env{'form.currentpath'});              $msg .= &mt(' A file by that name: [_1] was found in [_2].','<span class="LC_filename">'.$fname.'</span>',$port_path.$env{'form.currentpath'});
             $msg .= '</span>';              $msg .= '</span>';
             $msg .= '<br />';              return ('existingfile',$msg);
             $msg .= &mt('To upload, rename or delete existing [_1] in [_2].','<span class="LC_filename">'.$fname.'</span>', $port_path.$env{'form.currentpath'});  
             return ('file_exists',$msg);  
         }          }
     }      }
 }  }
   
   sub check_for_traversal {
       my ($path,$url,$toplevel) = @_;
       my @parts=split(/\//,$path);
       my $cleanpath;
       my $fullpath = $url;
       for (my $i=0;$i<@parts;$i++) {
           next if ($parts[$i] eq '.');
           if ($parts[$i] eq '..') {
               $fullpath =~ s{([^/]+/)$}{};
           } else {
               $fullpath .= $parts[$i].'/';
           }
       }
       if ($fullpath =~ /^\Q$url\E(.*)$/) {
           $cleanpath = $1;
       } elsif ($fullpath =~ /^\Q$toplevel\E(.*)$/) {
           my $curr_toprel = $1;
           my @parts = split(/\//,$curr_toprel);
           my ($url_toprel) = ($url =~ /^\Q$toplevel\E(.*)$/);
           my @urlparts = split(/\//,$url_toprel);
           my $doubledots;
           my $startdiff = -1;
           for (my $i=0; $i<@urlparts; $i++) {
               if ($startdiff == -1) {
                   unless ($urlparts[$i] eq $parts[$i]) {
                       $startdiff = $i;
                       $doubledots .= '../';
                   }
               } else {
                   $doubledots .= '../';
               }
           }
           if ($startdiff > -1) {
               $cleanpath = $doubledots;
               for (my $i=$startdiff; $i<@parts; $i++) {
                   $cleanpath .= $parts[$i].'/';
               }
           }
       }
       $cleanpath =~ s{(/)$}{};
       return $cleanpath;
   }
   
   =pod
   
   =item * &get_turnedin_filepath()
   
   Determines path in a user's portfolio file for storage of files uploaded
   to a specific essayresponse or dropbox item.
   
   Inputs: 3 required + 1 optional.
   $symb is symb for resource, $uname and $udom are for current user (required).
   $caller is optional (can be "submission", if routine is called when storing
   an upoaded file when "Submit Answer" button was pressed).
   
   Returns array containing $path and $multiresp. 
   $path is path in portfolio.  $multiresp is 1 if this resource contains more
   than one file upload item.  Callers of routine should append partid as a 
   subdirectory to $path in cases where $multiresp is 1.
   
   Called by: homework/essayresponse.pm and homework/structuretags.pm
   
   =cut
   
   sub get_turnedin_filepath {
       my ($symb,$uname,$udom,$caller) = @_;
       my ($map,$resid,$resurl)=&Apache::lonnet::decode_symb($symb);
       my $turnindir;
       my %userhash = &Apache::lonnet::userenvironment($udom,$uname,'turnindir');
       $turnindir = $userhash{'turnindir'};
       my ($path,$multiresp);
       if ($turnindir eq '') {
           if ($caller eq 'submission') {
               $turnindir = &mt('turned in');
               $turnindir =~ s/\W+/_/g;
               my %newhash = (
                               'turnindir' => $turnindir,
                             );
               &Apache::lonnet::put('environment',\%newhash,$udom,$uname);
           }
       }
       if ($turnindir ne '') {
           $path = '/'.$turnindir.'/';
           my ($multipart,$turnin,@pathitems);
           my $navmap = Apache::lonnavmaps::navmap->new();
           if (defined($navmap)) {
               my $mapres = $navmap->getResourceByUrl($map);
               if (ref($mapres)) {
                   my $pcslist = $mapres->map_hierarchy();
                   if ($pcslist ne '') {
                       foreach my $pc (split(/,/,$pcslist)) {
                           my $res = $navmap->getByMapPc($pc);
                           if (ref($res)) {
                               my $title = $res->compTitle();
                               $title =~ s/\W+/_/g;
                               if ($title ne '') {
                                   push(@pathitems,$title);
                               }
                           }
                       }
                   }
                   my $maptitle = $mapres->compTitle();
                   $maptitle =~ s/\W+/_/g;
                   if ($maptitle ne '') {
                       push(@pathitems,$maptitle);
                   }
                   unless ($env{'request.state'} eq 'construct') {
                       my $res = $navmap->getBySymb($symb);
                       if (ref($res)) {
                           my $partlist = $res->parts();
                           my $totaluploads = 0;
                           if (ref($partlist) eq 'ARRAY') {
                               foreach my $part (@{$partlist}) {
                                   my @types = $res->responseType($part);
                                   my @ids = $res->responseIds($part);
                                   for (my $i=0; $i < scalar(@ids); $i++) {
                                       if ($types[$i] eq 'essay') {
                                           my $partid = $part.'_'.$ids[$i];
                                           if (&Apache::lonnet::EXT("resource.$partid.uploadedfiletypes") ne '') {
                                               $totaluploads ++;
                                           }
                                       }
                                   }
                               }
                               if ($totaluploads > 1) {
                                   $multiresp = 1;
                               }
                           }
                       }
                   }
               } else {
                   return;
               }
           } else {
               return;
           }
           my $restitle=&Apache::lonnet::gettitle($symb);
           $restitle =~ s/\W+/_/g;
           if ($restitle eq '') {
               $restitle = ($resurl =~ m{/[^/]+$});
               if ($restitle eq '') {
                   $restitle = time;
               }
           }
           push(@pathitems,$restitle);
           $path .= join('/',@pathitems);
       }
       return ($path,$multiresp);
   }
   
 =pod  =pod
   
Line 8573  sub csv_print_select_table { Line 9561  sub csv_print_select_table {
  my ($value,$display,$defaultcol)=@{ $array_ref };   my ($value,$display,$defaultcol)=@{ $array_ref };
  $r->print(&start_data_table_row().'<td>'.$display.'</td>');   $r->print(&start_data_table_row().'<td>'.$display.'</td>');
   
  $r->print('<td><select name=f'.$i.   $r->print('<td><select name="f'.$i.'"'.
   ' onchange="javascript:flip(this.form,'.$i.');">');    ' onchange="javascript:flip(this.form,'.$i.');">');
  $r->print('<option value="none"></option>');   $r->print('<option value="none"></option>');
  foreach my $sample (sort({$a <=> $b} keys(%{ $samples->[0] }))) {   foreach my $sample (sort({$a <=> $b} keys(%{ $samples->[0] }))) {
Line 9227  sub restore_settings { Line 10215  sub restore_settings {
   
 =item * &build_recipient_list()  =item * &build_recipient_list()
   
 Build recipient lists for four types of e-mail:  Build recipient lists for five types of e-mail:
 (a) Error Reports, (b) Package Updates, (c) lonstatus warnings/errors  (a) Error Reports, (b) Package Updates, (c) lonstatus warnings/errors
 (d) Help requests, generated by  (d) Help requests, (e) Course requests needing approval,  generated by
 lonerrorhandler.pm, CHECKRPMS, loncron, and lonsupportreq.pm respectively.  lonerrorhandler.pm, CHECKRPMS, loncron, lonsupportreq.pm and
   loncoursequeueadmin.pm respectively.
   
 Inputs:  Inputs:
 defmail (scalar - email address of default recipient),   defmail (scalar - email address of default recipient), 
Line 9400  sub extract_categories { Line 10389  sub extract_categories {
                 my $trailstr;                  my $trailstr;
                 if ($name eq 'instcode') {                  if ($name eq 'instcode') {
                     $trailstr = &mt('Official courses (with institutional codes)');                      $trailstr = &mt('Official courses (with institutional codes)');
                   } elsif ($name eq 'communities') {
                       $trailstr = &mt('Communities');
                 } else {                  } else {
                     $trailstr = $name;                      $trailstr = $name;
                 }                  }
Line 9512  cathash - reference to hash of categorie Line 10503  cathash - reference to hash of categorie
   
 currcat - scalar with an & separated list of categories assigned to a course.   currcat - scalar with an & separated list of categories assigned to a course. 
   
   type    - scalar contains course type (Course or Community).
   
 Returns: $output (markup to be displayed)   Returns: $output (markup to be displayed) 
   
 =cut  =cut
   
 sub assign_categories_table {  sub assign_categories_table {
     my ($cathash,$currcat) = @_;      my ($cathash,$currcat,$type) = @_;
     my $output;      my $output;
     if (ref($cathash) eq 'HASH') {      if (ref($cathash) eq 'HASH') {
         my (@cats,@trails,%allitems,%idx,@jsarray,@path,$maxdepth);          my (@cats,@trails,%allitems,%idx,@jsarray,@path,$maxdepth);
Line 9526  sub assign_categories_table { Line 10519  sub assign_categories_table {
         if (@cats > 0) {          if (@cats > 0) {
             my $itemcount = 0;              my $itemcount = 0;
             if (ref($cats[0]) eq 'ARRAY') {              if (ref($cats[0]) eq 'ARRAY') {
                 $output = &Apache::loncommon::start_data_table();  
                 my @currcategories;                  my @currcategories;
                 if ($currcat ne '') {                  if ($currcat ne '') {
                     @currcategories = split('&',$currcat);                      @currcategories = split('&',$currcat);
                 }                  }
                   my $table;
                 for (my $i=0; $i<@{$cats[0]}; $i++) {                  for (my $i=0; $i<@{$cats[0]}; $i++) {
                     my $parent = $cats[0][$i];                      my $parent = $cats[0][$i];
                     my $css_class = $itemcount%2?' class="LC_odd_row"':'';  
                     next if ($parent eq 'instcode');                      next if ($parent eq 'instcode');
                       if ($type eq 'Community') {
                           next unless ($parent eq 'communities');
                       } else {
                           next if ($parent eq 'communities');
                       }
                       my $css_class = $itemcount%2?' class="LC_odd_row"':'';
                     my $item = &escape($parent).'::0';                      my $item = &escape($parent).'::0';
                     my $checked = '';                      my $checked = '';
                     if (@currcategories > 0) {                      if (@currcategories > 0) {
Line 9542  sub assign_categories_table { Line 10540  sub assign_categories_table {
                             $checked = ' checked="checked"';                              $checked = ' checked="checked"';
                         }                          }
                     }                      }
                     $output .= '<tr '.$css_class.'><td><span class="LC_nobreak">'.                      my $parent_title = $parent;
                                '<input type="checkbox" name="usecategory" value="'.                      if ($parent eq 'communities') {
                                $item.'"'.$checked.' />'.$parent.'</span>'.                          $parent_title = &mt('Communities');
                                '<input type="hidden" name="catname" value="'.$parent.'" /></td>';                      }
                       $table .= '<tr '.$css_class.'><td><span class="LC_nobreak">'.
                                 '<input type="checkbox" name="usecategory" value="'.
                                 $item.'"'.$checked.' />'.$parent_title.'</span>'.
                                 '<input type="hidden" name="catname" value="'.$parent.'" /></td>';
                     my $depth = 1;                      my $depth = 1;
                     push(@path,$parent);                      push(@path,$parent);
                     $output .= &assign_category_rows($itemcount,\@cats,$depth,$parent,\@path,\@currcategories);                      $table .= &assign_category_rows($itemcount,\@cats,$depth,$parent,\@path,\@currcategories);
                     pop(@path);                      pop(@path);
                     $output .= '</tr><tr><td colspan="'.$maxdepth.'" class="LC_row_separator"></td></tr>';                      $table .= '</tr><tr><td colspan="'.$maxdepth.'" class="LC_row_separator"></td></tr>';
                     $itemcount ++;                      $itemcount ++;
                 }                  }
                 $output .= &Apache::loncommon::end_data_table();                  if ($itemcount) {
                       $output = &Apache::loncommon::start_data_table().
                                 $table.
                                 &Apache::loncommon::end_data_table();
                   }
             }              }
         }          }
     }      }
Line 9798  sub check_clone { Line 10804  sub check_clone {
     my $clonehome=&Apache::lonnet::homeserver($clonecrsunum,$clonecrsudom);      my $clonehome=&Apache::lonnet::homeserver($clonecrsunum,$clonecrsudom);
     my $clonemsg;      my $clonemsg;
     my $can_clone = 0;      my $can_clone = 0;
       my $lctype = lc($args->{'crstype'});
       if ($lctype ne 'community') {
           $lctype = 'course';
       }
     if ($clonehome eq 'no_host') {      if ($clonehome eq 'no_host') {
         $clonemsg = &mt('No new course created.').$linefeed.&mt('A new course could not be cloned from the specified original - [_1] - because it is a non-existent course.',$args->{'clonecourse'}.':'.$args->{'clonedomain'});               if ($args->{'crstype'} eq 'Community') {
               $clonemsg = &mt('No new community created.').$linefeed.&mt('A new community could not be cloned from the specified original - [_1] - because it is a non-existent community.',$args->{'clonecourse'}.':'.$args->{'clonedomain'});
           } else {
               $clonemsg = &mt('No new course created.').$linefeed.&mt('A new course could not be cloned from the specified original - [_1] - because it is a non-existent course.',$args->{'clonecourse'}.':'.$args->{'clonedomain'});
           }     
     } else {      } else {
  my %clonedesc = &Apache::lonnet::coursedescription($cloneid,{'one_time' => 1});   my %clonedesc = &Apache::lonnet::coursedescription($cloneid,{'one_time' => 1});
  if ($env{'request.role.domain'} eq $args->{'clonedomain'}) {          if ($args->{'crstype'} eq 'Community') {
               if ($clonedesc{'type'} ne 'Community') {
                    $clonemsg = &mt('No new community created.').$linefeed.&mt('A new community could not be cloned from the specified original - [_1] - because it is a course not a community.',$args->{'clonecourse'}.':'.$args->{'clonedomain'});
                   return ($can_clone, $clonemsg, $cloneid, $clonehome);
               }
           }
    if (($env{'request.role.domain'} eq $args->{'clonedomain'}) && 
               (&Apache::lonnet::allowed('ccc',$env{'request.role.domain'}))) {
     $can_clone = 1;      $can_clone = 1;
  } else {   } else {
     my %clonehash = &Apache::lonnet::get('environment',['cloners'],      my %clonehash = &Apache::lonnet::get('environment',['cloners'],
Line 9814  sub check_clone { Line 10834  sub check_clone {
             } elsif (grep(/^\*\:\Q$args->{'ccdomain'}\E$/,@cloners)) {              } elsif (grep(/^\*\:\Q$args->{'ccdomain'}\E$/,@cloners)) {
                 $can_clone = 1;                  $can_clone = 1;
             } else {              } else {
                   my $ccrole = 'cc';
                   if ($args->{'crstype'} eq 'Community') {
                       $ccrole = 'co';
                   }
         my %roleshash =          my %roleshash =
     &Apache::lonnet::get_my_roles($args->{'ccuname'},      &Apache::lonnet::get_my_roles($args->{'ccuname'},
  $args->{'ccdomain'},   $args->{'ccdomain'},
                                          'userroles',['active'],['cc'],                                           'userroles',['active'],[$ccrole],
  [$args->{'clonedomain'}]);   [$args->{'clonedomain'}]);
         if (($roleshash{$args->{'clonecourse'}.':'.$args->{'clonedomain'}.':cc'}) || (grep(/^\Q$args->{'ccuname'}\E:\Q$args->{'ccdomain'}\E$/,@cloners))) {          if (($roleshash{$args->{'clonecourse'}.':'.$args->{'clonedomain'}.':'.$ccrole}) || (grep(/^\Q$args->{'ccuname'}\E:\Q$args->{'ccdomain'}\E$/,@cloners))) {
     $can_clone = 1;                      $can_clone = 1;
         } else {                  } elsif (&Apache::lonnet::is_course_owner($args->{'clonedomain'},$args->{'clonecourse'},$args->{'ccuname'},$args->{'ccdomain'})) {
                     $clonemsg = &mt('No new course created.').$linefeed.&mt('The new course could not be cloned from the existing course because the new course owner ([_1]) does not have cloning rights in the existing course ([_2]).',$args->{'ccuname'}.':'.$args->{'ccdomain'},$clonedesc{'description'});                      $can_clone = 1;
                   } else {
                       if ($args->{'crstype'} eq 'Community') {
                           $clonemsg = &mt('No new community created.').$linefeed.&mt('The new community could not be cloned from the existing community because the new community owner ([_1]) does not have cloning rights in the existing community ([_2]).',$args->{'ccuname'}.':'.$args->{'ccdomain'},$clonedesc{'description'});
                       } else {
                           $clonemsg = &mt('No new course created.').$linefeed.&mt('The new course could not be cloned from the existing course because the new course owner ([_1]) does not have cloning rights in the existing course ([_2]).',$args->{'ccuname'}.':'.$args->{'ccdomain'},$clonedesc{'description'});
                       }
         }          }
     }      }
         }          }
Line 9831  sub check_clone { Line 10861  sub check_clone {
 }  }
   
 sub construct_course {  sub construct_course {
     my ($args,$logmsg,$courseid,$crsudom,$crsunum,$udom,$uname,$context) = @_;      my ($args,$logmsg,$courseid,$crsudom,$crsunum,$udom,$uname,$context,$cnum,$category) = @_;
     my $outcome;      my $outcome;
     my $linefeed =  '<br />'."\n";      my $linefeed =  '<br />'."\n";
     if ($context eq 'auto') {      if ($context eq 'auto') {
Line 9869  sub construct_course { Line 10899  sub construct_course {
                                              $args->{'crscode'},                                               $args->{'crscode'},
                                              $args->{'ccuname'}.':'.                                               $args->{'ccuname'}.':'.
                                              $args->{'ccdomain'},                                               $args->{'ccdomain'},
                                              $args->{'crstype'});                                               $args->{'crstype'},
                                                $cnum,$context,$category);
   
     # Note: The testing routines depend on this being output; see       # Note: The testing routines depend on this being output; see 
     # Utils::Course. This needs to at least be output as a comment      # Utils::Course. This needs to at least be output as a comment
     # if anyone ever decides to not show this, and Utils::Course::new      # if anyone ever decides to not show this, and Utils::Course::new
     # will need to be suitably modified.      # will need to be suitably modified.
     $outcome .= &mt('New LON-CAPA [_1] ID: [_2]',$crstype,$$courseid).$linefeed;      $outcome .= &mt('New LON-CAPA [_1] ID: [_2]',$crstype,$$courseid).$linefeed;
       if ($$courseid =~ /^error:/) {
           return (0,$outcome);
       }
   
 #  #
 # Check if created correctly  # Check if created correctly
 #  #
     ($$crsudom,$$crsunum)= &LONCAPA::split_courseid($$courseid);      ($$crsudom,$$crsunum)= &LONCAPA::split_courseid($$courseid);
     my $crsuhome=&Apache::lonnet::homeserver($$crsunum,$$crsudom);      my $crsuhome=&Apache::lonnet::homeserver($$crsunum,$$crsudom);
       if ($crsuhome eq 'no_host') {
           $outcome .= &mt('Course creation failed, unrecognized course home server.').$linefeed;
           return (0,$outcome);
       }
     $outcome .= &mt('Created on').': '.$crsuhome.$linefeed;      $outcome .= &mt('Created on').': '.$crsuhome.$linefeed;
   
 #  #
Line 9899  sub construct_course { Line 10938  sub construct_course {
  $cenv{'url'}=$oldcenv{'url'};   $cenv{'url'}=$oldcenv{'url'};
 # Restore title  # Restore title
  $cenv{'description'}=$oldcenv{'description'};   $cenv{'description'}=$oldcenv{'description'};
   # Restore creation date, creator and creation context.
           $cenv{'internal.created'}=$oldcenv{'internal.created'};
           $cenv{'internal.creator'}=$oldcenv{'internal.creator'};
           $cenv{'internal.creationcontext'}=$oldcenv{'internal.creationcontext'};
 # Mark as cloned  # Mark as cloned
  $cenv{'clonedfrom'}=$cloneid;   $cenv{'clonedfrom'}=$cloneid;
 # Need to clone grading mode  # Need to clone grading mode
Line 10145  sub construct_course { Line 11188  sub construct_course {
     $title=&mt('Syllabus');      $title=&mt('Syllabus');
             $url='/public/'.$$crsudom.'/'.$$crsunum.'/syllabus';              $url='/public/'.$$crsudom.'/'.$$crsunum.'/syllabus';
         } else {          } else {
             $title=&mt('Navigate Contents');              $title=&mt('Table of Contents');
             $url='/adm/navmaps';              $url='/adm/navmaps';
         }          }
   
Line 10162  sub construct_course { Line 11205  sub construct_course {
 ############################################################  ############################################################
 ############################################################  ############################################################
   
   #SD
   # only Community and Course, or anything else?
 sub course_type {  sub course_type {
     my ($cid) = @_;      my ($cid) = @_;
     if (!defined($cid)) {      if (!defined($cid)) {
Line 10183  sub group_term { Line 11228  sub group_term {
     return $names{$crstype};      return $names{$crstype};
 }  }
   
   sub course_types {
       my @types = ('official','unofficial','community');
       my %typename = (
                            official   => 'Official course',
                            unofficial => 'Unofficial course',
                            community  => 'Community',
                      );
       return (\@types,\%typename);
   }
   
 sub icon {  sub icon {
     my ($file)=@_;      my ($file)=@_;
     my $curfext = lc((split(/\./,$file))[-1]);      my $curfext = lc((split(/\./,$file))[-1]);
Line 10317  sub init_user_environment { Line 11372  sub init_user_environment {
     my %userenv = &Apache::lonnet::dump('environment',$domain,$username);      my %userenv = &Apache::lonnet::dump('environment',$domain,$username);
     my ($tmp) = keys(%userenv);      my ($tmp) = keys(%userenv);
     if ($tmp !~ /^(con_lost|error|no_such_host)/i) {      if ($tmp !~ /^(con_lost|error|no_such_host)/i) {
  # default remote control to off  
  if ($userenv{'remote'} ne 'on') { $userenv{'remote'} = 'off'; }  
     } else {      } else {
  undef(%userenv);   undef(%userenv);
     }      }
     if (($userenv{'interface'}) && (!$form->{'interface'})) {      if (($userenv{'interface'}) && (!$form->{'interface'})) {
  $form->{'interface'}=$userenv{'interface'};   $form->{'interface'}=$userenv{'interface'};
     }      }
     $env{'environment.remote'}=$userenv{'remote'};  
     if ($userenv{'texengine'} eq 'ttm') { $clientmathml=1; }      if ($userenv{'texengine'} eq 'ttm') { $clientmathml=1; }
   
 # --------------- Do not trust query string to be put directly into environment  # --------------- Do not trust query string to be put directly into environment
Line 10357  sub init_user_environment { Line 11409  sub init_user_environment {
     $initial_env{"browser.localres"}   = $form->{'localres'};      $initial_env{"browser.localres"}   = $form->{'localres'};
         }          }
   
  if ($public) {  
     $initial_env{"environment.remote"} = "off";  
  }  
  if ($form->{'interface'}) {   if ($form->{'interface'}) {
     $form->{'interface'}=~s/\W//gs;      $form->{'interface'}=~s/\W//gs;
     $initial_env{"browser.interface"} = $form->{'interface'};      $initial_env{"browser.interface"} = $form->{'interface'};
     $env{'browser.interface'}=$form->{'interface'};      $env{'browser.interface'}=$form->{'interface'};
  }   }
   
           my %is_adv = ( is_adv => $env{'user.adv'} );
           my %domdef;
           unless ($domain eq 'public') {
               %domdef = &Apache::lonnet::get_domain_defaults($domain);
           }
   
         foreach my $tool ('aboutme','blog','portfolio') {          foreach my $tool ('aboutme','blog','portfolio') {
             $userenv{'availabletools.'.$tool} =               $userenv{'availabletools.'.$tool} = 
                 &Apache::lonnet::usertools_access($username,$domain,$tool,'reload');                  &Apache::lonnet::usertools_access($username,$domain,$tool,'reload',
                                                     undef,\%userenv,\%domdef,\%is_adv);
         }          }
   
         foreach my $crstype ('official','unofficial','community') {          foreach my $crstype ('official','unofficial','community') {
             $userenv{'canrequest.'.$crstype} =              $userenv{'canrequest.'.$crstype} =
                 &Apache::lonnet::usertools_access($username,$domain,$crstype,                  &Apache::lonnet::usertools_access($username,$domain,$crstype,
                                                   'reload','requestcourses');                                                    'reload','requestcourses',
                                                     \%userenv,\%domdef,\%is_adv);
         }          }
   
  $env{'user.environment'} = "$lonids/$cookie.id";   $env{'user.environment'} = "$lonids/$cookie.id";
Line 10453  sub clean_symb { Line 11510  sub clean_symb {
     return ($symb,$enc);      return ($symb,$enc);
 }  }
   
   sub build_release_hashes {
       my ($checkparms,$checkresponsetypes,$checkcrstypes,$anonsurvey,$randomizetry) = @_;
       return unless((ref($checkparms) eq 'HASH') && (ref($checkresponsetypes) eq 'HASH') &&
                     (ref($checkcrstypes) eq 'HASH') && (ref($anonsurvey) eq 'HASH') &&
                     (ref($randomizetry) eq 'HASH'));
       foreach my $key (keys(%Apache::lonnet::needsrelease)) {
           my ($item,$name,$value) = split(/:/,$key);
           if ($item eq 'parameter') {
               if (ref($checkparms->{$name}) eq 'ARRAY') {
                   unless(grep(/^\Q$name\E$/,@{$checkparms->{$name}})) {
                       push(@{$checkparms->{$name}},$value);
                   }
               } else {
                   push(@{$checkparms->{$name}},$value);
               }
           } elsif ($item eq 'resourcetag') {
               if ($name eq 'responsetype') {
                   $checkresponsetypes->{$value} = $Apache::lonnet::needsrelease{$key}
               }
           } elsif ($item eq 'course') {
               if ($name eq 'crstype') {
                   $checkcrstypes->{$value} = $Apache::lonnet::needsrelease{$key};
               }
           }
       }
       ($anonsurvey->{major},$anonsurvey->{minor}) = split(/\./,$Apache::lonnet::needsrelease{'parameter:type:anonsurvey'});
       ($randomizetry->{major},$randomizetry->{minor}) = split(/\./,$Apache::lonnet::needsrelease{'parameter:type:randomizetry'});
       return;
   }
   
 =pod  =pod
   
 =back  =back

Removed from v.1.867  
changed lines
  Added in v.1.1025


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