Annotation of loncom/interface/lonhtmlcommon.pm, revision 1.25
1.2 www 1: # The LearningOnline Network with CAPA
2: # a pile of common html routines
3: #
1.25 ! matthew 4: # $Id: lonhtmlcommon.pm,v 1.24 2003/06/18 15:02:20 www Exp $
1.2 www 5: #
6: # Copyright Michigan State University Board of Trustees
7: #
8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
9: #
10: # LON-CAPA is free software; you can redistribute it and/or modify
11: # it under the terms of the GNU General Public License as published by
12: # the Free Software Foundation; either version 2 of the License, or
13: # (at your option) any later version.
14: #
15: # LON-CAPA is distributed in the hope that it will be useful,
16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18: # GNU General Public License for more details.
19: #
20: # You should have received a copy of the GNU General Public License
21: # along with LON-CAPA; if not, write to the Free Software
22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23: #
24: # /home/httpd/html/adm/gpl.txt
25: #
26: # http://www.lon-capa.org/
27: #
1.10 matthew 28: ######################################################################
29: ######################################################################
30:
31: =pod
32:
33: =head1 NAME
34:
35: Apache::lonhtmlcommon - routines to do common html things
36:
37: =head1 SYNOPSIS
38:
39: Referenced by other mod_perl Apache modules.
40:
41: =head1 INTRODUCTION
42:
43: lonhtmlcommon is a collection of subroutines used to present information
44: in a consistent html format, or provide other functionality related to
45: html.
46:
47: =head2 General Subroutines
48:
49: =over 4
50:
51: =cut
52:
53: ######################################################################
54: ######################################################################
1.2 www 55:
1.1 stredwic 56: package Apache::lonhtmlcommon;
57:
1.10 matthew 58: use Time::Local;
1.1 stredwic 59: use strict;
60:
1.10 matthew 61: ##############################################
62: ##############################################
63:
64: =pod
65:
66: =item &date_setter
67:
1.22 matthew 68: &date_setter returns html and javascript for a compact date-setting form.
69: To retrieve values from it, use &get_date_from_form().
70:
1.10 matthew 71: Inputs
72:
73: =over 4
74:
75: =item $dname
76:
77: The name to prepend to the form elements.
78: The form elements defined will be dname_year, dname_month, dname_day,
79: dname_hour, dname_min, and dname_sec.
80:
81: =item $currentvalue
82:
83: The current setting for this time parameter. A unix format time
84: (time in seconds since the beginning of Jan 1st, 1970, GMT.
85: An undefined value is taken to indicate the value is the current time.
86: Also, to be explicit, a value of 'now' also indicates the current time.
87:
1.22 matthew 88: =back
89:
90: Bugs
91:
92: The method used to restrict user input will fail in the year 2400.
93:
1.10 matthew 94: =cut
95:
96: ##############################################
97: ##############################################
98: sub date_setter {
99: my ($formname,$dname,$currentvalue) = @_;
100: if (! defined($currentvalue) || $currentvalue eq 'now') {
101: $currentvalue = time;
102: }
103: # other potentially useful values: wkday,yrday,is_daylight_savings
104: my ($sec,$min,$hour,$mday,$month,$year,undef,undef,undef) =
105: localtime($currentvalue);
106: $year += 1900;
107: my $result = "\n<!-- $dname date setting form -->\n";
108: $result .= <<ENDJS;
109: <script language="Javascript">
110: function $dname\_checkday() {
111: var day = document.$formname.$dname\_day.value;
112: var month = document.$formname.$dname\_month.value;
113: var year = document.$formname.$dname\_year.value;
114: var valid = true;
115: if (day < 1) {
116: document.$formname.$dname\_day.value = 1;
117: }
118: if (day > 31) {
119: document.$formname.$dname\_day.value = 31;
120: }
121: if ((month == 1) || (month == 3) || (month == 5) ||
122: (month == 7) || (month == 8) || (month == 10) ||
123: (month == 12)) {
124: if (day > 31) {
125: document.$formname.$dname\_day.value = 31;
126: day = 31;
127: }
128: } else if (month == 2 ) {
129: if ((year % 4 == 0) && (year % 100 != 0)) {
130: if (day > 29) {
131: document.$formname.$dname\_day.value = 29;
132: }
133: } else if (day > 29) {
134: document.$formname.$dname\_day.value = 28;
135: }
136: } else if (day > 30) {
137: document.$formname.$dname\_day.value = 30;
138: }
139: }
140: </script>
141: ENDJS
142: $result .= " <select name=\"$dname\_month\" ".
143: "onChange=\"javascript:$dname\_checkday()\" >\n";
144: my @Months = qw/January February March April May June
145: July August September October November December/;
146: # Pad @Months with a bogus value to make indexing easier
147: unshift(@Months,'If you can read this an error occurred');
148: for(my $m = 1;$m <=$#Months;$m++) {
149: $result .= " <option value=\"$m\" ";
150: $result .= "selected " if ($m-1 == $month);
151: $result .= "> $Months[$m] </option>\n";
152: }
153: $result .= " </select>\n";
154: $result .= " <input type=\"text\" name=\"$dname\_day\" ".
155: "value=\"$mday\" size=\"3\" ".
156: "onChange=\"javascript:$dname\_checkday()\" />\n";
157: $result .= " <input type=\"year\" name=\"$dname\_year\" ".
158: "value=\"$year\" size=\"5\" ".
159: "onChange=\"javascript:$dname\_checkday()\" />\n";
160: $result .= " ";
161: $result .= " <select name=\"$dname\_hour\" >\n";
162: for (my $h = 0;$h<24;$h++) {
163: $result .= " <option value=\"$h\" ";
164: $result .= "selected " if ($hour == $h);
165: $result .= "> ";
166: if ($h == 0) {
167: $result .= "12 am";
168: } elsif($h == 12) {
169: $result .= "12 noon";
170: } elsif($h < 12) {
171: $result .= "$h am";
172: } else {
173: $result .= $h-12 ." pm";
174: }
175: $result .= " </option>\n";
176: }
177: $result .= " </select>\n";
178: $result .= " <input type=\"text\" name=\"$dname\_minute\" ".
179: "value=\"$min\" size=\"3\" /> m\n";
180: $result .= " <input type=\"text\" name=\"$dname\_second\" ".
181: "value=\"$sec\" size=\"3\" /> s\n";
182: $result .= "<!-- end $dname date setting form -->\n";
183: return $result;
184: }
185:
186: ##############################################
187: ##############################################
188:
1.22 matthew 189: =pod
190:
1.10 matthew 191: =item &get_date_from_form
1.22 matthew 192:
193: get_date_from_form retrieves the date specified in an &date_setter form.
1.10 matthew 194:
195: Inputs:
196:
197: =over 4
198:
199: =item $dname
200:
201: The name passed to &datesetter, which prefixes the form elements.
202:
203: =item $defaulttime
204:
205: The unix time to use as the default in case of poor inputs.
206:
207: =back
208:
209: Returns: Unix time represented in the form.
210:
211: =cut
212:
213: ##############################################
214: ##############################################
215: sub get_date_from_form {
216: my ($dname) = @_;
217: my ($sec,$min,$hour,$day,$month,$year);
218: #
219: if (defined($ENV{'form.'.$dname.'_second'})) {
220: my $tmpsec = $ENV{'form.'.$dname.'_second'};
221: if (($tmpsec =~ /^\d+$/) && ($tmpsec >= 0) && ($tmpsec < 60)) {
222: $sec = $tmpsec;
223: }
224: }
225: if (defined($ENV{'form.'.$dname.'_minute'})) {
226: my $tmpmin = $ENV{'form.'.$dname.'_minute'};
227: if (($tmpmin =~ /^\d+$/) && ($tmpmin >= 0) && ($tmpmin < 60)) {
228: $min = $tmpmin;
229: }
230: }
231: if (defined($ENV{'form.'.$dname.'_hour'})) {
232: my $tmphour = $ENV{'form.'.$dname.'_hour'};
233: if (($tmphour =~ /^\d+$/) && ($tmphour > 0) && ($tmphour < 32)) {
234: $hour = $tmphour;
235: }
236: }
237: if (defined($ENV{'form.'.$dname.'_day'})) {
238: my $tmpday = $ENV{'form.'.$dname.'_day'};
239: if (($tmpday =~ /^\d+$/) && ($tmpday > 0) && ($tmpday < 32)) {
240: $day = $tmpday;
241: }
242: }
243: if (defined($ENV{'form.'.$dname.'_month'})) {
244: my $tmpmonth = $ENV{'form.'.$dname.'_month'};
245: if (($tmpmonth =~ /^\d+$/) && ($tmpmonth > 0) && ($tmpmonth < 13)) {
246: $month = $tmpmonth - 1;
247: }
248: }
249: if (defined($ENV{'form.'.$dname.'_year'})) {
250: my $tmpyear = $ENV{'form.'.$dname.'_year'};
251: if (($tmpyear =~ /^\d+$/) && ($tmpyear > 1900)) {
252: $year = $tmpyear - 1900;
253: }
254: }
1.24 www 255: if (($year<70) || ($year>137)) { return undef; }
1.10 matthew 256: if (eval(&timelocal($sec,$min,$hour,$day,$month,$year))) {
257: return &timelocal($sec,$min,$hour,$day,$month,$year);
258: } else {
259: return undef;
260: }
1.20 matthew 261: }
262:
263: ##############################################
264: ##############################################
265:
266: =pod
267:
268: =item &pjump_javascript_definition()
269:
270: Returns javascript defining the 'pjump' function, which opens up a
271: parameter setting wizard.
272:
273: =cut
274:
275: ##############################################
276: ##############################################
277: sub pjump_javascript_definition {
278: my $Str = <<END;
279: function pjump(type,dis,value,marker,ret,call) {
280: parmwin=window.open("/adm/rat/parameter.html?type="+escape(type)
281: +"&value="+escape(value)+"&marker="+escape(marker)
282: +"&return="+escape(ret)
283: +"&call="+escape(call)+"&name="+escape(dis),"LONCAPAparms",
284: "height=350,width=350,scrollbars=no,menubar=no");
285: }
286: END
287: return $Str;
1.10 matthew 288: }
289:
290: ##############################################
291: ##############################################
1.17 matthew 292:
293: =pod
294:
295: =item &javascript_nothing()
296:
297: Return an appropriate null for the users browser. This is used
298: as the first arguement for window.open calls when you want a blank
299: window that you can then write to.
300:
301: =cut
302:
303: ##############################################
304: ##############################################
305: sub javascript_nothing {
306: # mozilla and other browsers work with "''", but IE on mac does not.
307: my $nothing = "''";
308: my $user_browser;
309: my $user_os;
310: $user_browser = $ENV{'browser.type'} if (exists($ENV{'browser.type'}));
311: $user_os = $ENV{'browser.os'} if (exists($ENV{'browser.os'}));
312: if (! defined($user_browser) || ! defined($user_os)) {
313: (undef,$user_browser,undef,undef,undef,$user_os) =
314: &Apache::loncommon::decode_user_agent();
315: }
316: if ($user_browser eq 'explorer' && $user_os =~ 'mac') {
317: $nothing = "'javascript:void(0);'";
318: }
319: return $nothing;
320: }
321:
1.21 matthew 322:
1.17 matthew 323: ##############################################
324: ##############################################
325:
1.21 matthew 326: =pod
1.17 matthew 327:
1.21 matthew 328: =item &StatusOptions()
1.10 matthew 329:
1.21 matthew 330: Returns html for a selection box which allows the user to choose the
331: enrollment status of students. The selection box name is 'Status'.
1.6 stredwic 332:
1.21 matthew 333: Inputs:
1.6 stredwic 334:
1.21 matthew 335: $status: the currently selected status. If undefined the value of
336: $ENV{'form.Status'} is taken. If that is undefined, a value of 'Active'
337: is used.
1.6 stredwic 338:
1.21 matthew 339: $formname: The name of the form. If defined the onchange attribute of
340: the selection box is set to document.$formname.submit().
1.6 stredwic 341:
1.21 matthew 342: $size: the size (number of lines) of the selection box.
1.6 stredwic 343:
1.21 matthew 344: Returns: a perl string as described.
1.1 stredwic 345:
1.21 matthew 346: =cut
1.9 stredwic 347:
1.21 matthew 348: ##############################################
349: ##############################################
350: sub StatusOptions {
351: my ($status, $formName,$size)=@_;
352: $size = 1 if (!defined($size));
353: if (! defined($status)) {
354: $status = 'Active';
355: $status = $ENV{'form.Status'} if (exists($ENV{'form.Status'}));
1.9 stredwic 356: }
1.1 stredwic 357:
358: my $OpSel1 = '';
359: my $OpSel2 = '';
360: my $OpSel3 = '';
361:
362: if($status eq 'Any') { $OpSel3 = ' selected'; }
363: elsif($status eq 'Expired' ) { $OpSel2 = ' selected'; }
364: else { $OpSel1 = ' selected'; }
365:
366: my $Str = '';
367: $Str .= '<select name="Status"';
368: if(defined($formName) && $formName ne '') {
369: $Str .= ' onchange="document.'.$formName.'.submit()"';
370: }
1.21 matthew 371: $Str .= ' size="'.$size.'" ';
1.1 stredwic 372: $Str .= '>'."\n";
1.21 matthew 373: $Str .= '<option value="Active" '.$OpSel1.'>'.
374: 'Currently Enrolled</option>'."\n";
375: $Str .= '<option value="Expired" '.$OpSel2.'>'.
376: 'Previously Enrolled</option>'."\n";
377: $Str .= '<option value="Any" '.$OpSel3.'>'.
378: 'Any Enrollment Status</option>'."\n";
1.1 stredwic 379: $Str .= '</select>'."\n";
380: }
381:
1.12 matthew 382:
383: ########################################################
384: ########################################################
385:
386: =pod
387:
388: =item &MultipleSectionSelect()
389:
390: Inputs:
391:
392: =over 4
393:
394: =item $sections A references to an array containing the names of all the
395: sections used in a class.
396:
397: =item $selectedSections A reference to an array containing the names of the
398: currently selected sections.
399:
400: =back
401:
402: Returns: a string containing HTML for a multiple select box for
403: selecting sections of a course.
404:
405: The form element name is 'Section'. @$sections is sorted prior to output.
406:
407: =cut
408:
409: ########################################################
410: ########################################################
1.5 stredwic 411: sub MultipleSectionSelect {
412: my ($sections,$selectedSections)=@_;
413:
414: my $Str = '';
1.7 stredwic 415: $Str .= '<select name="Section" multiple="true" size="4">'."\n";
1.5 stredwic 416:
1.11 minaeibi 417: foreach (sort @$sections) {
1.5 stredwic 418: $Str .= '<option';
419: foreach my $selected (@$selectedSections) {
420: if($_ eq $selected) {
421: $Str .= ' selected=""';
422: }
423: }
424: $Str .= '>'.$_.'</option>'."\n";
425: }
426: $Str .= '</select>'."\n";
1.12 matthew 427:
1.5 stredwic 428: return $Str;
429: }
430:
1.12 matthew 431: ########################################################
432: ########################################################
433:
434: =pod
435:
436: =item &Title()
437:
438: Inputs: $pageName a string containing the name of the page to be sent
439: to &Apache::loncommon::bodytag.
440:
441: Returns: string containing being <html> and complete <head> and <title>
442: as well as a <script> to focus the current window and change its width
443: and height to 500. Why? I do not know. If you find out, please update
444: this documentation.
445:
446: =cut
447:
448: ########################################################
449: ########################################################
1.1 stredwic 450: sub Title {
451: my ($pageName)=@_;
452:
453: my $Str = '';
454:
455: $Str .= '<html><head><title>'.$pageName.'</title></head>'."\n";
1.8 www 456: $Str .= &Apache::loncommon::bodytag($pageName)."\n";
1.1 stredwic 457: $Str .= '<script>window.focus(); window.width=500;window.height=500;';
458: $Str .= '</script>'."\n";
459:
460: return $Str;
461: }
462:
1.12 matthew 463: ########################################################
464: ########################################################
465:
1.1 stredwic 466: =pod
467:
1.13 matthew 468: =item &CreateHeadings()
1.1 stredwic 469:
470: This function generates the column headings for the chart.
471:
472: =over 4
473:
1.4 stredwic 474: Inputs: $CacheData, $keyID, $headings, $spacePadding
1.1 stredwic 475:
476: $CacheData: pointer to a hash tied to the cached data database
477:
1.4 stredwic 478: $keyID: a pointer to an array containing the names of the data
1.1 stredwic 479: held in a column and is used as part of a key into $CacheData
480:
481: $headings: The names of the headings for the student information
482:
483: $spacePadding: The spaces to go between columns
484:
485: Output: $Str
486:
487: $Str: A formatted string of the table column headings.
488:
489: =back
490:
491: =cut
492:
1.12 matthew 493: ########################################################
494: ########################################################
1.4 stredwic 495: sub CreateHeadings {
496: my ($data,$keyID,$headings,$displayString,$format)=@_;
1.1 stredwic 497: my $Str='';
1.4 stredwic 498: my $formatting = '';
1.1 stredwic 499:
500: for(my $index=0; $index<(scalar @$headings); $index++) {
1.4 stredwic 501: my $currentHeading=$headings->[$index];
502: if($format eq 'preformatted') {
503: my @dataLength=split(//,$currentHeading);
504: my $length=scalar @dataLength;
505: $formatting = (' 'x
506: ($data->{$keyID->[$index].':columnWidth'}-$length));
507: }
508: my $linkdata=$keyID->[$index];
509:
1.1 stredwic 510: my $tempString = $displayString;
511: $tempString =~ s/LINKDATA/$linkdata/;
1.4 stredwic 512: $tempString =~ s/DISPLAYDATA/$currentHeading/;
513: $tempString =~ s/FORMATTING/$formatting/;
514:
1.1 stredwic 515: $Str .= $tempString;
516: }
517:
518: return $Str;
519: }
520:
1.12 matthew 521: ########################################################
522: ########################################################
523:
1.1 stredwic 524: =pod
525:
526: =item &FormatStudentInformation()
527:
1.10 matthew 528: This function produces a formatted string of the student\'s information:
1.1 stredwic 529: username, domain, section, full name, and PID.
530:
531: =over 4
532:
1.4 stredwic 533: Input: $cache, $name, $keyID, $spacePadding
1.1 stredwic 534:
535: $cache: This is a pointer to a hash that is tied to the cached data
536:
537: $name: The name and domain of the current student in name:domain format
538:
1.4 stredwic 539: $keyID: A pointer to an array holding the names used to
1.1 stredwic 540:
541: remove data from the hash. They represent the name of the data to be removed.
542:
543: $spacePadding: Extra spaces that represent the space between columns
544:
545: Output: $Str
546:
547: $Str: Formatted string.
548:
549: =back
550:
551: =cut
552:
1.12 matthew 553: ########################################################
554: ########################################################
1.1 stredwic 555: sub FormatStudentInformation {
1.4 stredwic 556: my ($data,$name,$keyID,$displayString,$format)=@_;
1.1 stredwic 557: my $Str='';
1.4 stredwic 558: my $currentColumn;
559:
560: for(my $index=0; $index<(scalar @$keyID); $index++) {
561: $currentColumn=$data->{$name.':'.$keyID->[$index]};
1.1 stredwic 562:
1.4 stredwic 563: if($format eq 'preformatted') {
564: my @dataLength=split(//,$currentColumn);
565: my $length=scalar @dataLength;
566: $currentColumn.= (' 'x
567: ($data->{$keyID->[$index].':columnWidth'}-$length));
1.1 stredwic 568: }
569:
1.4 stredwic 570: my $tempString = $displayString;
571: $tempString =~ s/DISPLAYDATA/$currentColumn/;
572:
573: $Str .= $tempString;
1.1 stredwic 574: }
575:
576: return $Str;
1.7 stredwic 577: }
1.12 matthew 578:
579: ########################################################
580: ########################################################
1.7 stredwic 581:
1.23 matthew 582: =pod
583:
584: =item Progess Window Handling Routines
585:
586: These routines handle the creation, update, increment, and closure of
587: progress windows. The progress window reports to the user the number
588: of items completed and an estimate of the time required to complete the rest.
589:
590: =over 4
591:
592:
593: =item &Create_PrgWin
594:
595: Writes javascript to the client to open a progress window and returns a
596: data structure used for bookkeeping.
597:
598: Inputs
599:
600: =over 4
601:
602: =item $r Apache request
603:
604: =item $title The title of the progress window
605:
606: =item $heading A description (usually 1 line) of the process being initiated.
607:
608: =item $number_to_do The total number of items being processed.
609:
610: =back
611:
612: Returns a hash containing the progress state data structure.
613:
614:
615: =item &Update_PrgWin
616:
617: Updates the text in the progress indicator. Does not increment the count.
618: See &Increment_PrgWin.
619:
620: Inputs:
621:
622: =over 4
623:
624: =item $r Apache request
625:
626: =item $prog_state Pointer to the data structure returned by &Create_PrgWin
627:
628: =item $displaystring The string to write to the status indicator
629:
630: =back
631:
632: Returns: none
633:
634:
635: =item Increment_PrgWin
636:
637: Increment the count of items completed for the progress window by 1.
638:
639: Inputs:
640:
641: =over 4
642:
643: =item $r Apache request
644:
645: =item $prog_state Pointer to the data structure returned by Create_PrgWin
646:
647: =item $extraInfo A description of the items being iterated over. Typically
648: 'student'.
649:
650: =back
651:
652: Returns: none
653:
654:
655: =item Close_PrgWin
656:
657: Closes the progress window.
658:
659: Inputs:
660:
661: =over 4
662:
663: =item $r Apache request
664:
665: =item $prog_state Pointer to the data structure returned by Create_PrgWin
666:
667: =back
668:
669: Returns: none
670:
671: =back
672:
673: =cut
674:
675: ########################################################
676: ########################################################
677:
1.7 stredwic 678: # Create progress
679: sub Create_PrgWin {
1.14 albertel 680: my ($r, $title, $heading, $number_to_do)=@_;
1.7 stredwic 681: $r->print('<script>'.
682: "popwin=open(\'\',\'popwin\',\'width=400,height=100\');".
1.14 albertel 683: "popwin.document.writeln(\'<html><head><title>$title</title></head>".
684: "<body bgcolor=\"#88DDFF\">".
1.7 stredwic 685: "<h4>$heading</h4>".
686: "<form name=popremain>".
1.14 albertel 687: "<input type=text size=55 name=remaining value=Starting></form>".
1.7 stredwic 688: "</body></html>\');".
689: "popwin.document.close();".
690: "</script>");
691:
1.14 albertel 692: my %prog_state;
1.16 albertel 693: $prog_state{'done'}=0;
1.23 matthew 694: $prog_state{'firststart'}=&Time::HiRes::time();
695: $prog_state{'laststart'}=&Time::HiRes::time();
1.16 albertel 696: $prog_state{'max'}=$number_to_do;
1.14 albertel 697:
1.7 stredwic 698: $r->rflush();
1.14 albertel 699: return %prog_state;
1.7 stredwic 700: }
701:
702: # update progress
703: sub Update_PrgWin {
1.14 albertel 704: my ($r,$prog_state,$displayString)=@_;
1.7 stredwic 705: $r->print('<script>popwin.document.popremain.remaining.value="'.
706: $displayString.'";</script>');
1.23 matthew 707: $$prog_state{'laststart'}=&Time::HiRes::time();
1.14 albertel 708: $r->rflush();
709: }
710:
711: # increment progress state
712: sub Increment_PrgWin {
713: my ($r,$prog_state,$extraInfo)=@_;
1.16 albertel 714: $$prog_state{'done'}++;
1.23 matthew 715: my $time_est= (&Time::HiRes::time() - $$prog_state{'firststart'})/
716: $$prog_state{'done'} *
1.16 albertel 717: ($$prog_state{'max'}-$$prog_state{'done'});
718: $time_est = int($time_est);
719: if (int ($time_est/60) > 0) {
720: my $min = int($time_est/60);
721: my $sec = $time_est % 60;
722: $time_est = $min.' minutes';
1.25 ! matthew 723: if ($min < 10) {
! 724: if ($sec > 1) {
! 725: $time_est.= ', '.$sec.' seconds';
! 726: } elsif ($sec > 0) {
! 727: $time_est.= ', '.$sec.' second';
! 728: }
! 729: }
1.16 albertel 730: } else {
731: $time_est .= ' seconds';
732: }
1.23 matthew 733: my $lasttime = &Time::HiRes::time()-$$prog_state{'laststart'};
734: if ($lasttime > 9) {
735: $lasttime = int($lasttime);
736: } elsif ($lasttime < 0.01) {
737: $lasttime = 0;
738: } else {
739: $lasttime = sprintf("%3.2f",$lasttime);
740: }
1.19 matthew 741: if ($lasttime == 1) {
742: $lasttime = '('.$lasttime.' second for '.$extraInfo.')';
743: } else {
744: $lasttime = '('.$lasttime.' seconds for '.$extraInfo.')';
745: }
1.14 albertel 746: $r->print('<script>popwin.document.popremain.remaining.value="'.
1.16 albertel 747: $$prog_state{'done'}.'/'.$$prog_state{'max'}.
1.19 matthew 748: ': '.$time_est.' remaining '.$lasttime.'";'.'</script>');
1.23 matthew 749: $$prog_state{'laststart'}=&Time::HiRes::time();
1.7 stredwic 750: $r->rflush();
751: }
752:
753: # close Progress Line
754: sub Close_PrgWin {
1.14 albertel 755: my ($r,$prog_state)=@_;
1.7 stredwic 756: $r->print('<script>popwin.close()</script>'."\n");
1.14 albertel 757: undef(%$prog_state);
1.7 stredwic 758: $r->rflush();
1.1 stredwic 759: }
760:
761: 1;
1.23 matthew 762:
1.1 stredwic 763: __END__
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>