Diff for /loncom/interface/lonhtmlcommon.pm between versions 1.9 and 1.61

version 1.9, 2002/08/30 15:35:08 version 1.61, 2004/03/09 15:06:48
Line 25 Line 25
 #  #
 # http://www.lon-capa.org/  # http://www.lon-capa.org/
 #  #
   ######################################################################
   ######################################################################
   
   =pod
   
   =head1 NAME
   
   Apache::lonhtmlcommon - routines to do common html things
   
   =head1 SYNOPSIS
   
   Referenced by other mod_perl Apache modules.
   
   =head1 INTRODUCTION
   
   lonhtmlcommon is a collection of subroutines used to present information
   in a consistent html format, or provide other functionality related to
   html.
   
   =head2 General Subroutines
   
   =over 4
   
   =cut 
   
   ######################################################################
   ######################################################################
   
 package Apache::lonhtmlcommon;  package Apache::lonhtmlcommon;
   
   use Time::Local;
   use Time::HiRes;
   use Apache::lonlocal;
 use strict;  use strict;
   
 sub AscendOrderOptions {  ##############################################
     my ($order, $page, $formName)=@_;  ##############################################
   
     my $OpSel1 = '';  =pod
     my $OpSel2 = '';  
   
     if($order eq 'Ascending') {  =item authorbombs
         $OpSel1 = ' selected';  
     } else {  =cut
         $OpSel2 = ' selected';  
   ##############################################
   ##############################################
   
   sub authorbombs {
       my $url=shift;
       $url=&Apache::lonnet::declutter($url);
       my ($udom,$uname)=($url=~/^(\w+)\/(\w+)\//);
       my %bombs=&Apache::lonmsg::all_url_author_res_msg($uname,$udom);
       foreach (keys %bombs) {
    if ($_=~/^$udom\/$uname\//) {
       return '<a href="/adm/bombs/'.$url.
    '"><img src="/adm/lonMisc/bomb.gif" border="0" /></a>'.
    &Apache::loncommon::help_open_topic('About_Bombs');
    }
     }      }
       return '';
   }
   
     my $Str = '';  ##############################################
     $Str .= '<select name="'.(($page)?$page:'').'Ascend"';  ##############################################
     if($formName) {  
         $Str .= ' onchange="document.'.$formName.'.submit()"';  sub recent_filename {
       my $area=shift;
       return 'nohist_recent_'.&Apache::lonnet::escape($area);
   }
   
   sub store_recent {
       my ($area,$name,$value)=@_;
       my $file=&recent_filename($area);
       my %recent=&Apache::lonnet::dump($file);
       if (scalar(keys(%recent))>10) {
   # remove oldest value
    my $oldest=time;
    my $delkey='';
    foreach (keys %recent) {
       my $thistime=(split(/\&/,$recent{$_}))[0];
       if ($thistime<$oldest) {
    $oldest=$thistime;
    $delkey=$_;
       }
    }
    &Apache::lonnet::del($file,[$delkey]);
     }      }
     $Str .= '>'."\n";  # store new value
     $Str .= '<option'.$OpSel1.'>Ascending</option>'."\n".      &Apache::lonnet::put($file,{ $name => 
     '<option'.$OpSel2.'>Descending</option>'."\n";   time.'&'.&Apache::lonnet::escape($value) });
     $Str .= '</select>'."\n";  }
   
   sub select_recent {
       my ($area,$fieldname,$event)=@_;
       my %recent=&Apache::lonnet::dump(&recent_filename($area));
       my $return="\n<select name='$fieldname'".
    ($event?" onChange='$event'":'').
    ">\n<option value=''>--- ".&mt('Recent')." ---</option>";
       foreach (sort keys %recent) {
    unless ($_=~/^error\:/) {
       $return.="\n<option value='$_'>".
    &Apache::lonnet::unescape((split(/\&/,$recent{$_}))[1]).
    '</option>';
    }
       }
       $return.="\n</select>\n";
       return $return;
   }
   
   
   =pod
   
   =item textbox
   
   =cut
   
   ##############################################
   ##############################################
   sub textbox {
       my ($name,$value,$size,$special) = @_;
       $size = 40 if (! defined($size));
       my $Str = '<input type="text" name="'.$name.'" size="'.$size.'" '.
           'value="'.$value.'" '.$special.' />';
     return $Str;      return $Str;
 }  }
   
 sub MapOptions {  ##############################################
     my ($data, $page, $formName)=@_;  ##############################################
     my $Str = '';  
     $Str .= '<select name="';  
     $Str .= (($page)?$page:'').'Maps"';  
     if($formName) {  
         $Str .= ' onchange="document.'.$formName.'.submit()"';  
     }  
     $Str .= '>'."\n";  
   
     my $selected = 0;  =pod
     foreach my $sequence (split(':',$data->{'orderedSequences'})) {  
  $Str .= '<option';  
         if($data->{$page.'Maps'} eq $data->{$sequence.':title'}) {  
             $Str .= ' selected';  
             $selected = 1;  
         }  
  $Str .= '>'.$data->{$sequence.':title'}.'</option>'."\n";       
     }  
     $Str .= '<option';  
     if(!$selected) {  
         $Str .= ' selected';  
     }  
     $Str .= '>All Maps</option>'."\n";  
   
     $Str .= '</select>'."\n";  =item checkbox
   
   =cut
   
   ##############################################
   ##############################################
   sub checkbox {
       my ($name,$value) = @_;
       my $Str = '<input type="checkbox" name="'.$name.'"'.
    ($value?' checked="1"':'').' />';
     return $Str;      return $Str;
 }  }
   
 sub ProblemOptions {  ##############################################
     my ($data, $page, $map, $formName)=@_;  ##############################################
     my $Str = '';  
     $Str .= '<select name="';  
     $Str .= (($page)?$page:'').'ProblemSelect"';  
     if($formName) {  
         $Str .= ' onchange="document.'.$formName.'.submit()"';  
     }  
     $Str .= '>'."\n";  
   
     my $selected = 0;  =pod
     foreach my $sequence (split(':',$data->{'orderedSequences'})) {  
  if($data->{$sequence.':title'} eq $map || $map eq 'All Maps') {  =item &date_setter
     foreach my $problem (split(':', $data->{$sequence.':problems'})) {  
  $Str .= '<option';  &date_setter returns html and javascript for a compact date-setting form.
  if($data->{$page.'ProblemSelect'} eq   To retrieve values from it, use &get_date_from_form().
    $data->{$problem.':title'}) {  
     $Str .= ' selected';  Inputs
     $selected = 1;  
  }  =over 4
  $Str .= '>'.$data->{$problem.':title'}.'</option>'."\n";  
     }  =item $dname 
   
   The name to prepend to the form elements.  
   The form elements defined will be dname_year, dname_month, dname_day,
   dname_hour, dname_min, and dname_sec.
   
   =item $currentvalue
   
   The current setting for this time parameter.  A unix format time
   (time in seconds since the beginning of Jan 1st, 1970, GMT.  
   An undefined value is taken to indicate the value is the current time.
   Also, to be explicit, a value of 'now' also indicates the current time.
   
   =item $special
   
   Additional html/javascript to be associated with each element in
   the date_setter.  See lonparmset for example usage.
   
   =item $includeempty 
   
   =item $state
   
   Specifies the initial state of the form elements.  Either 'disabled' or empty.
   Defaults to empty, which indiciates the form elements are not disabled. 
   
   =back
   
   Bugs
   
   The method used to restrict user input will fail in the year 2400.
   
   =cut
   
   ##############################################
   ##############################################
   sub date_setter {
       my ($formname,$dname,$currentvalue,$special,$includeempty,$state) = @_;
       if (! defined($state) || $state ne 'disabled') {
           $state = '';
       }
       if (! defined($currentvalue) || $currentvalue eq 'now') {
    unless ($includeempty) {
       $currentvalue = time;
    } else {
       $currentvalue = 0;
  }   }
     }      }
     $Str .= '<option';      # other potentially useful values:     wkday,yrday,is_daylight_savings
     if(!$selected) {      my ($sec,$min,$hour,$mday,$month,$year)=('','','','','','');
         $Str .= ' selected';      if ($currentvalue) {
    ($sec,$min,$hour,$mday,$month,$year,undef,undef,undef) = 
       localtime($currentvalue);
    $year += 1900;
       }
       my $result = "\n<!-- $dname date setting form -->\n";
       $result .= <<ENDJS;
   <script language="Javascript">
       function $dname\_checkday() {
           var day   = document.$formname.$dname\_day.value;
           var month = document.$formname.$dname\_month.value;
           var year  = document.$formname.$dname\_year.value;
           var valid = true;
           if (day < 1) {
               document.$formname.$dname\_day.value = 1;
           } 
           if (day > 31) {
               document.$formname.$dname\_day.value = 31;
           }
           if ((month == 1)  || (month == 3)  || (month == 5)  ||
               (month == 7)  || (month == 8)  || (month == 10) ||
               (month == 12)) {
               if (day > 31) {
                   document.$formname.$dname\_day.value = 31;
                   day = 31;
               }
           } else if (month == 2 ) {
               if ((year % 4 == 0) && (year % 100 != 0)) {
                   if (day > 29) {
                       document.$formname.$dname\_day.value = 29;
                   }
               } else if (day > 29) {
                   document.$formname.$dname\_day.value = 28;
               }
           } else if (day > 30) {
               document.$formname.$dname\_day.value = 30;
           }
     }      }
     $Str .= '>All Problems</option>'."\n";  
   
     $Str .= '</select>'."\n";      function $dname\_disable() {
           document.$formname.$dname\_month.disabled=true;
           document.$formname.$dname\_day.disabled=true;
           document.$formname.$dname\_year.disabled=true;
           document.$formname.$dname\_hour.disabled=true;
           document.$formname.$dname\_minute.disabled=true;
           document.$formname.$dname\_second.disabled=true;
       }
   
       function $dname\_enable() {
           document.$formname.$dname\_month.disabled=false;
           document.$formname.$dname\_day.disabled=false;
           document.$formname.$dname\_year.disabled=false;
           document.$formname.$dname\_hour.disabled=false;
           document.$formname.$dname\_minute.disabled=false;
           document.$formname.$dname\_second.disabled=false;        
       }
   
       function $dname\_opencalendar() {
           if (! document.$formname.$dname\_month.disabled) {
               var calwin=window.open(
   "/adm/announcements?pickdate=yes&formname=$formname&element=$dname&month="+
   document.$formname.$dname\_month.value+"&year="+
   document.$formname.$dname\_year.value,
                "LONCAPAcal",
                 "height=350,width=350,scrollbars=yes,resizable=yes,menubar=no");
           }
   
     return $Str;      }
   </script>
   ENDJS
       $result .= "  <nobr><select name=\"$dname\_month\" ".$special.' '.
           $state.' '.
           "onChange=\"javascript:$dname\_checkday()\" >\n";
       my @Months = qw/January February  March     April   May      June 
                       July    August    September October November December/;
       # Pad @Months with a bogus value to make indexing easier
       unshift(@Months,'If you can read this an error occurred');
       if ($includeempty) { $result.="<option value=''></option>"; }
       for(my $m = 1;$m <=$#Months;$m++) {
           $result .= "      <option value=\"$m\" ";
           $result .= "selected " if ($m-1 eq $month);
           $result .= "> ".&mt($Months[$m])." </option>\n";
       }
       $result .= "  </select>\n";
       $result .= "  <input type=\"text\" name=\"$dname\_day\" ".$state.' '.
               "value=\"$mday\" size=\"3\" ".$special.' '.
               "onChange=\"javascript:$dname\_checkday()\" />\n";
       $result .= "  <input type=\"year\" name=\"$dname\_year\" ".$state.' '.
               "value=\"$year\" size=\"5\" ".$special.' '.
               "onChange=\"javascript:$dname\_checkday()\" />\n";
       $result .= "&nbsp;&nbsp;";
       $result .= "  <select name=\"$dname\_hour\" ".$special." ".$state.' '.">\n";
       if ($includeempty) { $result.="<option value=''></option>"; }
       for (my $h = 0;$h<24;$h++) {
           $result .= "      <option value=\"$h\" ";
           $result .= "selected " if ($hour == $h);
           $result .= "> ";
    my $timest='';
           if ($h == 0) {
               $timest .= "12 am";
           } elsif($h == 12) {
               $timest .= "12 noon";
           } elsif($h < 12) {
               $timest .= "$h am";
           } else {
               $timest .= $h-12 ." pm";
           }
    $timest=&mt($timest);
           $result .= $timest." </option>\n";
       } 
       $result .= "  </select>\n";
       $result .= "  <input type=\"text\" name=\"$dname\_minute\" ".$special.' '.
           $state.' '.
           "value=\"$min\" size=\"3\" /> m\n";
       $result .= "  <input type=\"text\" name=\"$dname\_second\" ".$special.' '.
           $state.' '.
           "value=\"$sec\" size=\"3\" /> s\n";
       $result .= "<a href=\"javascript:$dname\_opencalendar()\">".
       &mt('Select Date')."</a></nobr>\n<!-- end $dname date setting form -->\n";
       return $result;
 }  }
   
 sub PartOptions {  ##############################################
     my ($data, $page, $parts, $formName)=@_;  ##############################################
     my $Str = '';  
   
     if(!defined($parts)) {  =pod
  return '';  
     }  
   
     $Str .= '<select name="';  =item &get_date_from_form
     $Str .= (($page)?$page:'').'PartSelect"';  
     if($formName) {  
         $Str .= ' onchange="document.'.$formName.'.submit()"';  
     }  
     $Str .= '>'."\n";  
   
     my $selected = 0;  get_date_from_form retrieves the date specified in an &date_setter form.
     foreach my $part (@$parts) {  
  $Str .= '<option';  Inputs:
  if($data->{$page.'PartSelect'} eq $part) {  
     $Str .= ' selected';  =over 4
     $selected = 1;  
  }  =item $dname
  $Str .= '>'.$part.'</option>'."\n";       
   The name passed to &datesetter, which prefixes the form elements.
   
   =item $defaulttime
   
   The unix time to use as the default in case of poor inputs.
   
   =back
   
   Returns: Unix time represented in the form.
   
   =cut
   
   ##############################################
   ##############################################
   sub get_date_from_form {
       my ($dname) = @_;
       my ($sec,$min,$hour,$day,$month,$year);
       #
       if (defined($ENV{'form.'.$dname.'_second'})) {
           my $tmpsec = $ENV{'form.'.$dname.'_second'};
           if (($tmpsec =~ /^\d+$/) && ($tmpsec >= 0) && ($tmpsec < 60)) {
               $sec = $tmpsec;
           }
       }
       if (defined($ENV{'form.'.$dname.'_minute'})) {
           my $tmpmin = $ENV{'form.'.$dname.'_minute'};
           if (($tmpmin =~ /^\d+$/) && ($tmpmin >= 0) && ($tmpmin < 60)) {
               $min = $tmpmin;
           }
       }
       if (defined($ENV{'form.'.$dname.'_hour'})) {
           my $tmphour = $ENV{'form.'.$dname.'_hour'};
           if (($tmphour =~ /^\d+$/) && ($tmphour >= 0) && ($tmphour < 24)) {
               $hour = $tmphour;
           }
       }
       if (defined($ENV{'form.'.$dname.'_day'})) {
           my $tmpday = $ENV{'form.'.$dname.'_day'};
           if (($tmpday =~ /^\d+$/) && ($tmpday > 0) && ($tmpday < 32)) {
               $day = $tmpday;
           }
       }
       if (defined($ENV{'form.'.$dname.'_month'})) {
           my $tmpmonth = $ENV{'form.'.$dname.'_month'};
           if (($tmpmonth =~ /^\d+$/) && ($tmpmonth > 0) && ($tmpmonth < 13)) {
               $month = $tmpmonth - 1;
           }
       }
       if (defined($ENV{'form.'.$dname.'_year'})) {
           my $tmpyear = $ENV{'form.'.$dname.'_year'};
           if (($tmpyear =~ /^\d+$/) && ($tmpyear > 1900)) {
               $year = $tmpyear - 1900;
           }
     }      }
     $Str .= '<option';      if (($year<70) || ($year>137)) { return undef; }
     if(!$selected) {      if (defined($sec) && defined($min)   && defined($hour) &&
         $Str .= ' selected';          defined($day) && defined($month) && defined($year) &&
           eval(&timelocal($sec,$min,$hour,$day,$month,$year))) {
           return &timelocal($sec,$min,$hour,$day,$month,$year);
       } else {
           return undef;
     }      }
     $Str .= '>All Parts</option>'."\n";  }
   
     $Str .= '</select>'."\n";  ##############################################
   ##############################################
   
   =pod
   
   =item &pjump_javascript_definition()
   
   Returns javascript defining the 'pjump' function, which opens up a
   parameter setting wizard.
   
   =cut
   
   ##############################################
   ##############################################
   sub pjump_javascript_definition {
       my $Str = <<END;
       function pjump(type,dis,value,marker,ret,call) {
           parmwin=window.open("/adm/rat/parameter.html?type="+escape(type)
                    +"&value="+escape(value)+"&marker="+escape(marker)
                    +"&return="+escape(ret)
                    +"&call="+escape(call)+"&name="+escape(dis),"LONCAPAparms",
                    "height=350,width=350,scrollbars=no,menubar=no");
       }
   END
     return $Str;      return $Str;
 }  }
   
 sub StudentOptions {  ##############################################
     my ($cache, $students, $selectedName, $page, $formName)=@_;  ##############################################
   
     my $Str = '';  =pod
     $Str .= '<select name="'.(($page)?$page:'').'Student"';  
     if($formName) {  
         $Str .= ' onchange="document.'.$formName.'.submit()"';  
     }  
     $Str .= '>'."\n";  
   
     my $selected=0;  =item &javascript_nothing()
   
     foreach (@$students) {  Return an appropriate null for the users browser.  This is used
  $Str .= '<option';  as the first arguement for window.open calls when you want a blank
  if($selectedName eq $_) {  window that you can then write to.
             $Str .= ' selected';  
             $selected = 1;  
         }  
         $Str .= '>';  
         $Str .= $cache->{$_.':fullname'};  
         $Str .= '</option>'."\n";       
     }  
   
     $Str .= '<option';  =cut
     if($selectedName eq 'No Student Selected') {  
         $Str .= ' selected';  
         $selected = 1;  
     }  
     $Str .= '>No Student Selected</option>'."\n";  
   
     $Str .= '<option';  ##############################################
     if(!$selected) {  ##############################################
         $Str .= ' selected';  sub javascript_nothing {
       # mozilla and other browsers work with "''", but IE on mac does not.
       my $nothing = "''";
       my $user_browser;
       my $user_os;
       $user_browser = $ENV{'browser.type'} if (exists($ENV{'browser.type'}));
       $user_os      = $ENV{'browser.os'}   if (exists($ENV{'browser.os'}));
       if (! defined($user_browser) || ! defined($user_os)) {
           (undef,$user_browser,undef,undef,undef,$user_os) = 
                              &Apache::loncommon::decode_user_agent();
       }
       if ($user_browser eq 'explorer' && $user_os =~ 'mac') {
           $nothing = "'javascript:void(0);'";
     }      }
     $Str .= '>All Students</option>'."\n";      return $nothing;
   }
   
     $Str .= '</select>'."\n";  
   
     return $Str;  ##############################################
 }  ##############################################
   
   =pod
   
   =item &StatusOptions()
   
   Returns html for a selection box which allows the user to choose the
   enrollment status of students.  The selection box name is 'Status'.
   
   Inputs:
   
   $status: the currently selected status.  If undefined the value of
   $ENV{'form.Status'} is taken.  If that is undefined, a value of 'Active'
   is used.
   
   $formname: The name of the form.  If defined the onchange attribute of
   the selection box is set to document.$formname.submit().
   
   $size: the size (number of lines) of the selection box.
   
   $onchange: javascript to use when the value is changed.  Enclosed in 
   double quotes, ""s, not single quotes.
   
   Returns: a perl string as described.
   
   =cut
   
   ##############################################
   ##############################################
 sub StatusOptions {  sub StatusOptions {
     my ($status, $formName)=@_;      my ($status, $formName,$size,$onchange)=@_;
       $size = 1 if (!defined($size));
       if (! defined($status)) {
           $status = 'Active';
           $status = $ENV{'form.Status'} if (exists($ENV{'form.Status'}));
       }
   
     my $OpSel1 = '';      my $OpSel1 = '';
     my $OpSel2 = '';      my $OpSel2 = '';
Line 209  sub StatusOptions { Line 541  sub StatusOptions {
   
     my $Str = '';      my $Str = '';
     $Str .= '<select name="Status"';      $Str .= '<select name="Status"';
     if(defined($formName) && $formName ne '') {      if(defined($formName) && $formName ne '' && ! defined($onchange)) {
         $Str .= ' onchange="document.'.$formName.'.submit()"';          $Str .= ' onchange="document.'.$formName.'.submit()"';
     }      }
       if (defined($onchange)) {
           $Str .= ' onchange="'.$onchange.'"';
       }
       $Str .= ' size="'.$size.'" ';
     $Str .= '>'."\n";      $Str .= '>'."\n";
     $Str .= '<option'.$OpSel1.'>Active</option>'."\n";      $Str .= '<option value="Active" '.$OpSel1.'>'.
     $Str .= '<option'.$OpSel2.'>Expired</option>'."\n";          &mt('Currently Enrolled').'</option>'."\n";
     $Str .= '<option'.$OpSel3.'>Any</option>'."\n";      $Str .= '<option value="Expired" '.$OpSel2.'>'.
           &mt('Previously Enrolled').'</option>'."\n";
       $Str .= '<option value="Any" '.$OpSel3.'>'.
           &mt('Any Enrollment Status').'</option>'."\n";
     $Str .= '</select>'."\n";      $Str .= '</select>'."\n";
 }  }
   
 sub MultipleSectionSelect {  ########################################################
     my ($sections,$selectedSections)=@_;  ########################################################
   
     my $Str = '';  
     $Str .= '<select name="Section" multiple="true" size="4">'."\n";  
   
     foreach (@$sections) {  
         $Str .= '<option';  
         foreach my $selected (@$selectedSections) {  
             if($_ eq $selected) {  
                 $Str .= ' selected=""';  
             }  
         }  
         $Str .= '>'.$_.'</option>'."\n";  
     }  
     $Str .= '</select>'."\n";  
   
     return $Str;  =pod
 }  
   
 sub Title {  =item Progess Window Handling Routines
     my ($pageName)=@_;  
   
     my $Str = '';  These routines handle the creation, update, increment, and closure of 
   progress windows.  The progress window reports to the user the number
   of items completed and an estimate of the time required to complete the rest.
   
     $Str .= '<html><head><title>'.$pageName.'</title></head>'."\n";  =over 4
     $Str .= &Apache::loncommon::bodytag($pageName)."\n";  
     $Str .= '<script>window.focus(); window.width=500;window.height=500;';  
     $Str .= '</script>'."\n";  
   
     return $Str;  
 }  
   
 =pod  =item &Create_PrgWin
   
 =item &CreateTableHeadings()  Writes javascript to the client to open a progress window and returns a
   data structure used for bookkeeping.
   
 This function generates the column headings for the chart.  Inputs
   
 =over 4  =over 4
   
 Inputs: $CacheData, $keyID, $headings, $spacePadding  =item $r Apache request
   
 $CacheData: pointer to a hash tied to the cached data database  =item $title The title of the progress window
   
 $keyID: a pointer to an array containing the names of the data   =item $heading A description (usually 1 line) of the process being initiated.
 held in a column and is used as part of a key into $CacheData  
   
 $headings: The names of the headings for the student information  =item $number_to_do The total number of items being processed.
   
 $spacePadding: The spaces to go between columns  =item $type Either 'popup' or 'inline' (popup is assumed if nothing is
          specified)
   
 Output: $Str  =item $width Specify the width in charaters of the input field.
   
 $Str: A formatted string of the table column headings.  =item $formname Only useful in the inline case, if a form already exists, this needs to be used and specfiy the name of the form, otherwise the Progress line will be created in a new form of it's own
   
   =item $inputname Only useful in the inline case, if a form and an input of type text exists, use this to specify the name of the input field 
   
 =back  =back
   
 =cut  Returns a hash containing the progress state data structure.
   
 sub CreateHeadings {  
     my ($data,$keyID,$headings,$displayString,$format)=@_;  
     my $Str='';  
     my $formatting = '';  
   
     for(my $index=0; $index<(scalar @$headings); $index++) {  
   my $currentHeading=$headings->[$index];  
         if($format eq 'preformatted') {  
             my @dataLength=split(//,$currentHeading);  
             my $length=scalar @dataLength;  
             $formatting = (' 'x  
                       ($data->{$keyID->[$index].':columnWidth'}-$length));  
         }  
         my $linkdata=$keyID->[$index];  
   
         my $tempString = $displayString;  
         $tempString =~ s/LINKDATA/$linkdata/;  
         $tempString =~ s/DISPLAYDATA/$currentHeading/;  
         $tempString =~ s/FORMATTING/$formatting/;  
   
         $Str .= $tempString;  =item &Update_PrgWin
     }  
   
     return $Str;  Updates the text in the progress indicator.  Does not increment the count.
 }  See &Increment_PrgWin.
   
 =pod  Inputs:
   
 =item &FormatStudentInformation()  =over 4
   
 This function produces a formatted string of the student's information:  =item $r Apache request
 username, domain, section, full name, and PID.  
   
 =over 4  =item $prog_state Pointer to the data structure returned by &Create_PrgWin
   
   =item $displaystring The string to write to the status indicator
   
   =back
   
   Returns: none
   
 Input: $cache, $name, $keyID, $spacePadding  
   
 $cache: This is a pointer to a hash that is tied to the cached data  =item Increment_PrgWin
   
 $name:  The name and domain of the current student in name:domain format  Increment the count of items completed for the progress window by 1.  
   
 $keyID: A pointer to an array holding the names used to  Inputs:
   
 remove data from the hash.  They represent the name of the data to be removed.  =over 4
   
 $spacePadding: Extra spaces that represent the space between columns  =item $r Apache request
   
 Output: $Str  =item $prog_state Pointer to the data structure returned by Create_PrgWin
   
 $Str: Formatted string.  =item $extraInfo A description of the items being iterated over.  Typically
   'student'.
   
 =back  =back
   
 =cut  Returns: none
   
 sub FormatStudentInformation {  
     my ($data,$name,$keyID,$displayString,$format)=@_;  
     my $Str='';  
     my $currentColumn;  
   
     for(my $index=0; $index<(scalar @$keyID); $index++) {  =item Close_PrgWin
         $currentColumn=$data->{$name.':'.$keyID->[$index]};  
   
         if($format eq 'preformatted') {  Closes the progress window.
             my @dataLength=split(//,$currentColumn);  
             my $length=scalar @dataLength;  
             $currentColumn.= (' 'x  
                      ($data->{$keyID->[$index].':columnWidth'}-$length));  
         }  
   
         my $tempString = $displayString;  Inputs:
         $tempString =~ s/DISPLAYDATA/$currentColumn/;  
   
         $Str .= $tempString;  =over 4 
     }  
   
     return $Str;  =item $r Apache request
   
   =item $prog_state Pointer to the data structure returned by Create_PrgWin
   
   =back
   
   Returns: none
   
   =back
   
   =cut
   
   ########################################################
   ########################################################
   
   my $uniq=0;
   sub get_uniq_name {
       $uniq++;
       return 'uniquename'.$uniq;
 }  }
   
 # Create progress  # Create progress
 sub Create_PrgWin {  sub Create_PrgWin {
     my ($r, $title, $heading)=@_;      my ($r, $title, $heading, $number_to_do,$type,$width,$formname,
     $r->print('<script>'.   $inputname)=@_;
     "popwin=open(\'\',\'popwin\',\'width=400,height=100\');".      if (!defined($type)) { $type='popup'; }
     "popwin.document.writeln(\'<html><body bgcolor=\"#88DDFF\">".      if (!defined($width)) { $width=55; }
               "<title>$title</title>".      my %prog_state;
       $prog_state{'type'}=$type;
       if ($type eq 'popup') {
    $prog_state{'window'}='popwin';
    #the whole function called through timeout is due to issues
    #in mozilla Read BUG #2665 if you want to know the whole story
    &r_print($r,'<script>'.
           "var popwin;
            function openpopwin () {
            popwin=open(\'\',\'popwin\',\'width=400,height=100\');".
           "popwin.document.writeln(\'<html><head><title>$title</title></head>".
         "<body bgcolor=\"#88DDFF\">".
               "<h4>$heading</h4>".                "<h4>$heading</h4>".
               "<form name=popremain>".                "<form name=popremain>".
               "<input type=text size=35 name=remaining value=Starting></form>".                '<input type="text" size="'.$width.'" name="remaining" value="'.
         &mt('Starting').'"></form>'.
               "</body></html>\');".                "</body></html>\');".
     "popwin.document.close();".          "popwin.document.close();}".
     "</script>");          "\nwindow.setTimeout(openpopwin,0)</script>");
    $prog_state{'formname'}='popremain';
    $prog_state{'inputname'}="remaining";
       } elsif ($type eq 'inline') {
    $prog_state{'window'}='window';
    if (!$formname) {
       $prog_state{'formname'}=&get_uniq_name();
       &r_print($r,'<form name="'.$prog_state{'formname'}.'">');
    } else {
       $prog_state{'formname'}=$formname;
    }
    if (!$inputname) {
       $prog_state{'inputname'}=&get_uniq_name();
       &r_print($r,$heading.' <input type="text" name="'.$prog_state{'inputname'}.
        '" size="'.$width.'" />');
    } else {
       $prog_state{'inputname'}=$inputname;
       
    }
    if (!$formname) { &r_print($r,'</form>'); }
    &Update_PrgWin($r,\%prog_state,&mt('Starting'));
       }
   
     $r->rflush();      $prog_state{'done'}=0;
       $prog_state{'firststart'}=&Time::HiRes::time();
       $prog_state{'laststart'}=&Time::HiRes::time();
       $prog_state{'max'}=$number_to_do;
       
       return %prog_state;
 }  }
   
 # update progress  # update progress
 sub Update_PrgWin {  sub Update_PrgWin {
     my ($displayString,$r)=@_;      my ($r,$prog_state,$displayString)=@_;
     $r->print('<script>popwin.document.popremain.remaining.value="'.      &r_print($r,'<script>'.$$prog_state{'window'}.'.document.'.
               $displayString.'";</script>');       $$prog_state{'formname'}.'.'.
     $r->rflush();       $$prog_state{'inputname'}.'.value="'.
        $displayString.'";</script>');
       $$prog_state{'laststart'}=&Time::HiRes::time();
   }
   
   # increment progress state
   sub Increment_PrgWin {
       my ($r,$prog_state,$extraInfo)=@_;
       $$prog_state{'done'}++;
       my $time_est= (&Time::HiRes::time() - $$prog_state{'firststart'})/
           $$prog_state{'done'} *
    ($$prog_state{'max'}-$$prog_state{'done'});
       $time_est = int($time_est);
       if (int ($time_est/60) > 0) {
    my $min = int($time_est/60);
    my $sec = $time_est % 60;
    $time_est = $min.' '.&mt('minutes');
           if ($min < 10)  {
               if ($sec > 1) {
                   $time_est.= ', '.$sec.' '.&mt('seconds');
               } elsif ($sec > 0) {
                   $time_est.= ', '.$sec.' '.&mt('second');
               }
           }
       } else {
    $time_est .= ' '.&mt('seconds');
       }
       my $lasttime = &Time::HiRes::time()-$$prog_state{'laststart'};
       if ($lasttime > 9) {
           $lasttime = int($lasttime);
       } elsif ($lasttime < 0.01) {
           $lasttime = 0;
       } else {
           $lasttime = sprintf("%3.2f",$lasttime);
       }
       if ($lasttime == 1) {
           $lasttime = '('.$lasttime.' '.&mt('second for').' '.$extraInfo.')';
       } else {
           $lasttime = '('.$lasttime.' '.&mt('seconds for').' '.$extraInfo.')';
       }
       #
       my $user_browser = $ENV{'browser.type'} if (exists($ENV{'browser.type'}));
       my $user_os      = $ENV{'browser.os'}   if (exists($ENV{'browser.os'}));
       if (! defined($user_browser) || ! defined($user_os)) {
           (undef,$user_browser,undef,undef,undef,$user_os) = 
                              &Apache::loncommon::decode_user_agent();
       }
       if ($user_browser eq 'explorer' && $user_os =~ 'mac') {
           $lasttime = '';
       }
       &r_print($r,'<script>'.$$prog_state{'window'}.'.document.'.
        $$prog_state{'formname'}.'.'.
        $$prog_state{'inputname'}.'.value="'.
        $$prog_state{'done'}.'/'.$$prog_state{'max'}.
        ': '.$time_est.' '.&mt('remaining').' '.$lasttime.'";'.'</script>');
       $$prog_state{'laststart'}=&Time::HiRes::time();
 }  }
   
 # close Progress Line  # close Progress Line
 sub Close_PrgWin {  sub Close_PrgWin {
     my ($r)=@_;      my ($r,$prog_state)=@_;
     $r->print('<script>popwin.close()</script>'."\n");      if ($$prog_state{'type'} eq 'popup') {
     $r->rflush();    &r_print($r,'<script>popwin.close()</script>'."\n");
       } elsif ($$prog_state{'type'} eq 'inline') {
    &Update_PrgWin($r,$prog_state,&mt('Done'));
       }
       undef(%$prog_state);
 }  }
   
   sub r_print {
       my ($r,$to_print)=@_;
       if ($r) {
    $r->print($to_print);
    $r->rflush();
       } else {
    print($to_print);
       }
   }
   
   # ------------------------------------------------------- Puts directory header
   
   sub crumbs {
       my ($uri,$target,$prefix,$form)=@_;
       my $output='<br /><tt><b><font size="+2">'.$prefix.'/';
       if ($ENV{'user.adv'}) {
    my $path=$prefix.'/';
    foreach (split('/',$uri)) {
       unless ($_) { next; }
       $path.=$_;
       unless ($path eq $uri) { $path.='/'; }
       my $linkpath=$path;
       if ($form) {
    $linkpath="javascript:$form.action='$path';$form.submit();";
       }
       $output.='<a href="'.$linkpath.'"'.($target?' target="'.$target.'"':'').'>'.$_.'</a>/';
    }
       } else {
    $output.=$uri;
       }
       unless ($uri=~/\/$/) { $output=~s/\/$//; }
       return $output.'</font></b></tt><br />';
   }
   
   # ------------------------------------------------- Output headers for HTMLArea
   
   sub htmlareaheaders {
       unless (&htmlareablocked()) { return ''; }
       my $lang='en';
       return (<<ENDHEADERS);
   <script type="text/javascript">
       _editor_url="/htmlarea/";
   </script>
   <script type="text/javascript" src="/htmlarea/htmlarea.js"></script>
   <script type="text/javascript" src="/htmlarea/lang/$lang.js"></script>
   <script type="text/javascript" src="/htmlarea/dialog.js"></script>
   <style type="text/css">
   \@import url(/htmlarea/htmlarea.css);
   </style>
   ENDHEADERS
   }
   
   # ---------------------------------------------------------- Script to activate
   
   sub htmlareaactive {
       unless (&htmlareablocked()) { return ''; }
       return (<<ENDSCRIPT);
   <script type="text/javascript" defer="1">
       HTMLArea.replaceAll();
   </script>
   ENDSCRIPT
   }
   
   # --------------------------------------------------------------------- Blocked
   
   sub htmlareablocked {
       unless (&htmlareabrowser()) { return ''; }
       return 1;
   }
   
   # ---------------------------------------- Browser capable of running HTMLArea?
   
   sub htmlareabrowser {
       return 1;
   }
   
   ############################################################
   ############################################################
   
   =pod
   
   =item breadcrumbs
   
   Compiles the previously registered breadcrumbs into an series of links.
   FAQ and BUG links will be placed on the left side of the table if they
   are defined for the last registered breadcrumb.  
   Additionally supports a 'component', which will be displayed on the
   right side of the table (without a link).
   A link to help for the component will be included if one is specified.
   
   All inputs can be undef without problems.
   
   Inputs: $color (the background color of the table returned),
           $component (the large text on the right side of the table),
           $component_help
   
   Returns a string containing breadcrumbs for the current page.
   
   =item clear_breadcrumbs
   
   Clears the previously stored breadcrumbs.
   
   =item add_breadcrumb
   
   Pushes a breadcrumb on the stack of crumbs.
   
   input: $breadcrumb, a hash reference.  The keys 'href','title', and 'text'
   are required.  If present the keys 'faq' and 'bug' will be used to provide
   links to the FAQ and bug sites.
   
   returns: nothing    
   
   =cut
   
   ############################################################
   ############################################################
   {
       my @Crumbs;
       
       sub breadcrumbs {
           my ($color,$component,$component_help,$function,$domain) = @_;
           if (! defined($color)) {
               if (! defined($function)) {
                   $function = &Apache::loncommon::get_users_function();
               }
               $color = &Apache::loncommon::designparm($function.'.tabbg',
                                                       $domain);
           }
           #
           my $Str = "\n".
               '<table width="100%" border="0" cellpadding="0" cellspacing="0">'.
               '<tr><td bgcolor="'.$color.'">'.
               '<font size="-1">';
           #
           # Make the faq and bug data cascade
           my $faq = '';
           my $bug = '';
           # The last breadcrumb does not have a link, so handle it separately.
           my $last = pop(@Crumbs);
           #
           # The first one should be the course, I guess.
           if (exists($ENV{'request.course.id'})) {
               my $cid = $ENV{'request.course.id'};
               unshift(@Crumbs,{
                                href=>'/adm/menu',
                                title=>'Go to main menu',
                                text=>$ENV{'course.'.$cid.'.description'},
                               });
           }
           my $links .= 
               join('-&gt;',
                    map {
                        $faq = $_->{'faq'} if (exists($_->{'faq'}));
                        $bug = $_->{'bug'} if (exists($_->{'bug'}));
                        '<a href="'.$_->{'href'}.'" title="'.&mt($_->{'title'}).'">'.
                            &mt($_->{'text'}).'</a>' 
                        } @Crumbs
                    );
           $links .= '-&gt;' if ($links ne '');
           $links .= '<b>'.$last->{'text'}.'</b>';
           #
           my $icons = '';
           $faq = $last->{'faq'} if (exists($last->{'faq'}));
           $bug = $last->{'bug'} if (exists($last->{'bug'}));
           if ($faq ne '') {
               $icons .= &Apache::loncommon::help_open_faq($faq);
           }
           if ($bug ne '') {
               $icons .= &Apache::loncommon::help_open_bug($bug);
           }
           if ($icons ne '') {
               $Str .= $icons.'&nbsp;';
           }
           #
           $Str .= $links.'</font></td>';
           #
           if (defined($component)) {
               $Str .= '<td align="right" bgcolor="'.$color.'">'.
                   '<font size="+1">'.&mt($component).'</font>';
               if (defined($component_help)) {
                   $Str .= 
                       &Apache::loncommon::help_open_topic($component_help);
               }
               $Str.= '</td>';
           }
           $Str .= '</tr></table>'."\n";
           #
           # Return the @Crumbs stack to what we started with
           push(@Crumbs,$last);
           shift(@Crumbs);
           #
           return $Str;
       }
   
       sub clear_breadcrumbs {
           undef(@Crumbs);
       }
   
       sub add_breadcrumb {
           push (@Crumbs,@_);
       }
   
   } # End of scope for @Crumbs
   
   ############################################################
   ############################################################
   
   
 1;  1;
   
 __END__  __END__

Removed from v.1.9  
changed lines
  Added in v.1.61


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