--- loncom/interface/Attic/lonspreadsheet.pm	2002/09/05 14:38:57	1.107
+++ loncom/interface/Attic/lonspreadsheet.pm	2002/10/16 16:35:42	1.117
@@ -1,5 +1,5 @@
 #
-# $Id: lonspreadsheet.pm,v 1.107 2002/09/05 14:38:57 matthew Exp $
+# $Id: lonspreadsheet.pm,v 1.117 2002/10/16 16:35:42 matthew Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -26,16 +26,6 @@
 # The LearningOnline Network with CAPA
 # Spreadsheet/Grades Display Handler
 #
-# 11/11,11/15,11/27,12/04,12/05,12/06,12/07,
-# 12/08,12/09,12/11,12/12,12/15,12/16,12/18,12/19,12/30,
-# 01/01/01,02/01,03/01,19/01,20/01,22/01,
-# 03/05,03/08,03/10,03/12,03/13,03/15,03/17,
-# 03/19,03/20,03/21,03/27,04/05,04/09,
-# 07/09,07/14,07/21,09/01,09/10,9/11,9/12,9/13,9/14,9/17,
-# 10/16,10/17,10/20,11/05,11/28,12/27 Gerd Kortemeyer
-# 01/14/02 Matthew
-# 02/04/02 Matthew
-
 # POD required stuff:
 
 =head1 NAME
@@ -54,7 +44,6 @@ not the grades of their peers.  The spre
 offering the ability to use Perl code to manipulate data, as well as many
 built-in functions.
 
-
 =head2 Functions available to user of lonspreadsheet
 
 =over 4
@@ -73,6 +62,11 @@ use GDBM_File;
 use HTML::TokeParser;
 use Apache::lonhtmlcommon;
 #
+# Caches for coursewide information 
+#
+my %Section;
+
+#
 # Caches for previously calculated spreadsheets
 #
 
@@ -167,7 +161,7 @@ $chome= '';
 $cnum = '';
 $cdom = '';
 $cid  = '';
-$cfn  = '';
+$coursefilename  = '';
 
 # symb
 
@@ -863,7 +857,7 @@ sub sett {
     }
     # Deal with the normal cells
     foreach (keys(%f)) {
-	if (($f{$_}) && ($_!~/template\_/)) {
+	if (exists($f{$_}) && ($_!~/template\_/)) {
             my $matches=($_=~/^$pattern(\d+)/);
             if  (($matches) && ($1)) {
 	        unless ($f{$_}=~/^\!/) {
@@ -1012,168 +1006,48 @@ ENDDEFS
 }
 
 # ------------------------------------------------ Add or change formula values
-
 sub setformulas {
     my ($safeeval,%f)=@_;
     %{$safeeval->varglob('f')}=%f;
 }
 
 # ------------------------------------------------ Add or change formula values
-
 sub setconstants {
     my ($safeeval,%c)=@_;
     %{$safeeval->varglob('c')}=%c;
 }
 
 # --------------------------------------------- Set names of other spreadsheets
-
 sub setothersheets {
     my ($safeeval,@os)=@_;
     @{$safeeval->varglob('os')}=@os;
 }
 
 # ------------------------------------------------ Add or change formula values
-
 sub setrowlabels {
     my ($safeeval,%rowlabel)=@_;
     %{$safeeval->varglob('rowlabel')}=%rowlabel;
 }
 
 # ------------------------------------------------------- Calculate spreadsheet
-
 sub calcsheet {
     my $safeeval=shift;
     return $safeeval->reval('&calc();');
 }
 
-# ------------------------------------------------------------------ Get values
-
-sub getvalues {
-    my $safeeval=shift;
-    return $safeeval->reval('%sheet_values');
-}
-
 # ---------------------------------------------------------------- Get formulas
-
 sub getformulas {
     my $safeeval=shift;
     return %{$safeeval->varglob('f')};
 }
 
 # ----------------------------------------------------- Get value of $f{'A'.$n}
-
 sub getfa {
     my ($safeeval,$n)=@_;
     return $safeeval->reval('$f{"A'.$n.'"}');
 }
 
-# -------------------------------------------------------------------- Get type
-
-sub gettype {
-    my $safeeval=shift;
-    return $safeeval->reval('$sheettype');
-}
-
-# ------------------------------------------------------------------ Set maxrow
-
-sub setmaxrow {
-    my ($safeeval,$row)=@_;
-    $safeeval->reval('$maxrow='.$row.';');
-}
-
-# ------------------------------------------------------------------ Get maxrow
-
-sub getmaxrow {
-    my $safeeval=shift;
-    return $safeeval->reval('$maxrow');
-}
-
-# ---------------------------------------------------------------- Set filename
-
-sub setfilename {
-    my ($safeeval,$fn)=@_;
-    $safeeval->reval('$filename="'.$fn.'";');
-}
-
-# ---------------------------------------------------------------- Get filename
-
-sub getfilename {
-    my $safeeval=shift;
-    return $safeeval->reval('$filename');
-}
-
-# --------------------------------------------------------------- Get course ID
-
-sub getcid {
-    my $safeeval=shift;
-    return $safeeval->reval('$cid');
-}
-
-# --------------------------------------------------------- Get course filename
-
-sub getcfn {
-    my $safeeval=shift;
-    return $safeeval->reval('$cfn');
-}
-
-# ----------------------------------------------------------- Get course number
-
-sub getcnum {
-    my $safeeval=shift;
-    return $safeeval->reval('$cnum');
-}
-
-# ------------------------------------------------------------- Get course home
-
-sub getchome {
-    my $safeeval=shift;
-    return $safeeval->reval('$chome');
-}
-
-# ----------------------------------------------------------- Get course domain
-
-sub getcdom {
-    my $safeeval=shift;
-    return $safeeval->reval('$cdom');
-}
-
-# ---------------------------------------------------------- Get course section
-
-sub getcsec {
-    my $safeeval=shift;
-    return $safeeval->reval('$csec');
-}
-
-# --------------------------------------------------------------- Get user name
-
-sub getuname {
-    my $safeeval=shift;
-    return $safeeval->reval('$uname');
-}
-
-# ------------------------------------------------------------- Get user domain
-
-sub getudom {
-    my $safeeval=shift;
-    return $safeeval->reval('$udom');
-}
-
-# --------------------------------------------------------------- Get user home
-
-sub getuhome {
-    my $safeeval=shift;
-    return $safeeval->reval('$uhome');
-}
-
-# -------------------------------------------------------------------- Get symb
-
-sub getusymb {
-    my $safeeval=shift;
-    return $safeeval->reval('$usymb');
-}
-
 # ------------------------------------------------------------- Export of A-row
-
 sub exportdata {
     my $safeeval=shift;
     return $safeeval->reval('&exportrowa()');
@@ -1189,7 +1063,7 @@ sub exportdata {
 # --------------------------------------------- Produce output row n from sheet
 
 sub rown {
-    my ($safeeval,$n)=@_;
+    my ($safeeval,$n,$sheetdata)=@_;
     my $defaultbg;
     my $rowdata='';
     my $dataflag=0;
@@ -1206,7 +1080,7 @@ sub rown {
     my $showf=0;
     my $proc;
     my $maxred=1;
-    my $sheettype=&gettype($safeeval);
+    my $sheettype=$sheetdata->{'sheettype'};
     if ($sheettype eq 'studentcalc') {
         $proc='&outrowassess';
         $maxred=26;
@@ -1237,8 +1111,14 @@ sub rown {
                 if ($vl eq '') {
                     $vl='<font size=+2 color='.$bgcolor.'>&#35;</font>';
                 }
-                $rowdata.='<td bgcolor='.$bgcolor.'>'.
-                    '<a href="javascript:celledit('.$fm.');">'.$vl.'</a></td>';
+                $rowdata.='<td bgcolor='.$bgcolor.'>';
+                if ($ENV{'request.role'} =~ /^st\./) {
+                    $rowdata.=$vl;
+                } else {
+                    $rowdata.='<a href="javascript:celledit('.$fm.');">'.
+                        $vl.'</a>';
+                }
+                $rowdata.='</td>';
             } else {
                 $rowdata.='<td bgcolor='.$bgcolor.'>&nbsp;'.$vl.'&nbsp;</td>';
             }
@@ -1296,13 +1176,14 @@ sub outsheet {
             }
             $tabledata.="<b><font size=+1>$_</font></b></td>";
         }
-        $tabledata.='</tr>'.&rown($safeeval,'-').&rown($safeeval,0);
+        $tabledata.='</tr>'.&rown($safeeval,'-',$sheetdata).
+            &rown($safeeval,0,$sheetdata);
     }
     $r->print($tabledata);
     #
     # Prepare to output rows
     my $row;
-    my $maxrow=&getmaxrow($safeeval);
+    my $maxrow=$sheetdata->{'maxrow'};
     #
     my @sortby=();
     my @sortidx=();
@@ -1310,7 +1191,7 @@ sub outsheet {
         push (@sortby, $safeeval->reval('$f{"A'.$row.'"}'));
         push (@sortidx, $row-1);
     }
-    @sortidx=sort { $sortby[$a] cmp $sortby[$b]; } @sortidx;
+    @sortidx=sort { lc($sortby[$a]) cmp lc($sortby[$b]); } @sortidx;
     #
     # Determine the type of child spreadsheets
     my $what='Student';
@@ -1323,7 +1204,7 @@ sub outsheet {
     # Loop through the rows and output them one at a time
     my $n=0;
     for ($row=0;$row<$maxrow;$row++) {
-        my $thisrow=&rown($safeeval,$sortidx[$row]+1);
+        my $thisrow=&rown($safeeval,$sortidx[$row]+1,$sheetdata);
         if ($thisrow) {
             if (($n/25==int($n/25)) && (!$ENV{'form.showcsv'})) {
                 $r->print("</table>\n<br>\n");
@@ -1346,11 +1227,11 @@ sub outsheet {
 # ----------------------------------------------- Read list of available sheets
 # 
 sub othersheets {
-    my ($safeeval,$stype)=@_;
+    my ($safeeval,$stype,$sheetdata)=@_;
     #
-    my $cnum  = &getcnum($safeeval);
-    my $cdom  = &getcdom($safeeval);
-    my $chome = &getchome($safeeval);
+    my $cnum  = $sheetdata->{'cnum'};
+    my $cdom  = $sheetdata->{'cdom'};
+    my $chome = $sheetdata->{'chome'};
     #
     my @alternatives=();
     my %results=&Apache::lonnet::dump($stype.'_spreadsheets',$cdom,$cnum);
@@ -1393,7 +1274,6 @@ sub parse_sheet {
 #
 # -------------------------------------- Read spreadsheet formulas for a course
 #
-
 sub readsheet {
     my ($safeeval,$sheetdata,$fn)=@_;
     #
@@ -1421,7 +1301,7 @@ sub readsheet {
         }
     }
     # $fn now has a value
-    &setfilename($safeeval,$fn);
+    $sheetdata->{'filename'} = $fn;
     # see if sheet is cached
     my $fstring='';
     if ($fstring=$spreadsheets{$cnum.'_'.$cdom.'_'.$stype.'_'.$fn}) {
@@ -1465,7 +1345,6 @@ sub readsheet {
 }
 
 # -------------------------------------------------------- Make new spreadsheet
-
 sub makenewsheet {
     my ($uname,$udom,$stype,$usymb)=@_;
     my %sheetdata=();
@@ -1474,15 +1353,16 @@ sub makenewsheet {
     $sheetdata{'sheettype'} = $stype;
     $sheetdata{'usymb'} = $usymb;
     $sheetdata{'cid'}   = $ENV{'request.course.id'};
-    $sheetdata{'csec'}  = &Apache::lonnet::usection
-                               ($udom,$uname,$ENV{'request.course.id'});
-    $sheetdata{'cfn'}   = $ENV{'request.course.fn'};
+    $sheetdata{'csec'}  = $Section{$uname.':'.$udom};
+    $sheetdata{'coursefilename'}   = $ENV{'request.course.fn'};
     $sheetdata{'cnum'}  = $ENV{'course.'.$ENV{'request.course.id'}.'.num'};
     $sheetdata{'cdom'}  = $ENV{'course.'.$ENV{'request.course.id'}.'.domain'};
     $sheetdata{'chome'} = $ENV{'course.'.$ENV{'request.course.id'}.'.home'};
     $sheetdata{'uhome'} = &Apache::lonnet::homeserver($uname,$udom);
     
     my $safeeval=initsheet($stype);
+    #
+    # Place all the %sheetdata items into the safe space
     my $initstring = '';
     foreach (keys(%sheetdata)) {
         $initstring.= qq{\$$_="$sheetdata{$_}";};
@@ -1492,17 +1372,16 @@ sub makenewsheet {
 }
 
 # ------------------------------------------------------------ Save spreadsheet
-
 sub writesheet {
-    my ($safeeval,$makedef)=@_;
-    my $cid=&getcid($safeeval);
+    my ($safeeval,$makedef,$sheetdata)=@_;
+    my $cid=$sheetdata->{'cid'};
     if (&Apache::lonnet::allowed('opa',$cid)) {
         my %f=&getformulas($safeeval);
-        my $stype=&gettype($safeeval);
-        my $cnum=&getcnum($safeeval);
-        my $cdom=&getcdom($safeeval);
-        my $chome=&getchome($safeeval);
-        my $fn=&getfilename($safeeval);
+        my $stype= $sheetdata->{'sheettype'};
+        my $cnum = $sheetdata->{'cnum'};
+        my $cdom = $sheetdata->{'cdom'};
+        my $chome= $sheetdata->{'chome'};
+        my $fn   = $sheetdata->{'filename'};
         # Cache new sheet
         $spreadsheets{$cnum.'_'.$cdom.'_'.$stype.'_'.$fn}=join('___;___',%f);
         # Write sheet
@@ -1544,12 +1423,11 @@ sub writesheet {
 # ----------------------------------------------- Make a temp copy of the sheet
 # "Modified workcopy" - interactive only
 #
-
 sub tmpwrite {
-    my $safeeval=shift;
+    my ($safeeval,$sheetdata) = @_;
     my $fn=$ENV{'user.name'}.'_'.
-        $ENV{'user.domain'}.'_spreadsheet_'.&getusymb($safeeval).'_'.
-           &getfilename($safeeval);
+        $ENV{'user.domain'}.'_spreadsheet_'.$sheetdata->{'usymb'}.'_'.
+           $sheetdata->{'filename'};
     $fn=~s/\W/\_/g;
     $fn=$tmpdir.$fn.'.tmp';
     my $fh;
@@ -1559,12 +1437,11 @@ sub tmpwrite {
 }
 
 # ---------------------------------------------------------- Read the temp copy
-
 sub tmpread {
-    my ($safeeval,$nfield,$nform)=@_;
+    my ($safeeval,$sheetdata,$nfield,$nform)=@_;
     my $fn=$ENV{'user.name'}.'_'.
-           $ENV{'user.domain'}.'_spreadsheet_'.&getusymb($safeeval).'_'.
-           &getfilename($safeeval);
+           $ENV{'user.domain'}.'_spreadsheet_'.$sheetdata->{'usymb'}.'_'.
+           $sheetdata->{'filename'};
     $fn=~s/\W/\_/g;
     $fn=$tmpdir.$fn.'.tmp';
     my $fh;
@@ -1656,35 +1533,38 @@ sub parmval {
     my $courselevelr = $usercourseprefix.'.'.$symbparm;
     my $courselevelm = $usercourseprefix.'.'.$mapparm;
     # fourth, check user
-    if ($uname) { 
-        return $useropt{$courselevelr} if ($useropt{$courselevelr});
-        return $useropt{$courselevelm} if ($useropt{$courselevelm});
-        return $useropt{$courselevel}  if ($useropt{$courselevel});
+    if (defined($uname)) {
+        return $useropt{$courselevelr} if (defined($useropt{$courselevelr}));
+        return $useropt{$courselevelm} if (defined($useropt{$courselevelm}));
+        return $useropt{$courselevel}  if (defined($useropt{$courselevel}));
     }
     # third, check course
-    if ($csec) {
-        return $courseopt{$seclevelr} if ($courseopt{$seclevelr});
-        return $courseopt{$seclevelm} if ($courseopt{$seclevelm});
-        return $courseopt{$seclevel}  if ($courseopt{$seclevel});
+    if (defined($csec)) {
+        return $courseopt{$seclevelr} if (defined($courseopt{$seclevelr}));
+        return $courseopt{$seclevelm} if (defined($courseopt{$seclevelm}));
+        return $courseopt{$seclevel}  if (defined($courseopt{$seclevel}));
     }
     #
-    return $courseopt{$courselevelr} if ($courseopt{$courselevelr});
-    return $courseopt{$courselevelm} if ($courseopt{$courselevelm});
-    return $courseopt{$courselevel}  if ($courseopt{$courselevel});
+    return $courseopt{$courselevelr} if (defined($courseopt{$courselevelr}));
+    return $courseopt{$courselevelm} if (defined($courseopt{$courselevelm}));
+    return $courseopt{$courselevel}  if (defined($courseopt{$courselevel}));
     # second, check map parms
     my $thisparm = $parmhash{$symbparm};
-    return $thisparm if ($thisparm);
+    return $thisparm if (defined($thisparm));
     # first, check default
     return &Apache::lonnet::metadata($fn,$rwhat.'.default');
 }
 
 # ---------------------------------------------- Update rows for course listing
 sub updateclasssheet {
-    my $safeeval=shift;
-    my $cnum=&getcnum($safeeval);
-    my $cdom=&getcdom($safeeval);
-    my $cid=&getcid($safeeval);
-    my $chome=&getchome($safeeval);
+    my ($safeeval,$sheetdata) = @_;
+    my $cnum  =$sheetdata->{'cnum'};
+    my $cdom  =$sheetdata->{'cdom'};
+    my $cid   =$sheetdata->{'cid'};
+    my $chome =$sheetdata->{'chome'};
+    #
+    %Section = ();
+
     #
     # Read class list and row labels
     my %classlist;
@@ -1709,15 +1589,16 @@ sub updateclasssheet {
             my ($studentName,$studentDomain)=split(/\:/,$student);
             my $studentSection=&Apache::lonnet::usection($studentDomain,
                                                          $studentName,$cid);
-            if ($studentSection==-1) {
-                unless ($ENV{'form.showcsv'}) {
-                    $rowlabel='<font color=red>Data not available: '.
-                        $studentName.'</font>';
-                } else {
-                    $rowlabel='ERROR","'.$studentName.
-                        '","Data not available","","","';
-                }
-            } else {
+            $Section{$studentName.':'.$studentDomain} = $studentSection;
+#            if ($studentSection==-1) {
+#                unless ($ENV{'form.showcsv'}) {
+#                    $rowlabel='<font color=red>Data not available: '.
+#                        $studentName.'</font>';
+#                } else {
+#                    $rowlabel='ERROR","'.$studentName.
+#                        '","Data not available","","","';
+#                }
+#            } else {
                 my %reply=&Apache::lonnet::idrget($studentDomain,$studentName);
                 my %studentInformation=&Apache::lonnet::get
                     ('environment',
@@ -1742,7 +1623,7 @@ sub updateclasssheet {
                                          $studentInformation{'generation'})
                                         ).'"';
                 }
-            }
+ #           }
             $currentlist{$student}=$rowlabel;
         } # end of if ($active)
     } # end of foreach my $student (keys(%classlist))
@@ -1778,19 +1659,23 @@ sub updateclasssheet {
     }
     if ($changed) { &setformulas($safeeval,%f); }
     #
-    &setmaxrow($safeeval,$maxrow);
+    $sheetdata->{'maxrow'} = $maxrow;
     &setrowlabels($safeeval,%currentlist);
 }
 
 # ----------------------------------- Update rows for student and assess sheets
 sub updatestudentassesssheet {
-    my $safeeval=shift;
+    my ($safeeval,$sheetdata) = @_;
     my %bighash;
-    my $stype=&gettype($safeeval);
+    my $stype=$sheetdata->{'sheettype'};
+    my $uname=$sheetdata->{'uname'};
+    my $udom =$sheetdata->{'udom'};
     my %current=();
-    if  ($updatedata{$ENV{'request.course.fn'}.'_'.$stype}) {
+    if  ($updatedata
+         {$ENV{'request.course.fn'}.'_'.$stype.'_'.$uname.'_'.$udom}) {
         %current=split(/\_\_\_\;\_\_\_/,
-		       $updatedata{$ENV{'request.course.fn'}.'_'.$stype});
+                       $updatedata{$ENV{'request.course.fn'}.
+                                       '_'.$stype.'_'.$uname.'_'.$udom});
     } else {
         # Tie hash
         tie(%bighash,'GDBM_File',$ENV{'request.course.fn'}.'.db',
@@ -1808,10 +1693,8 @@ sub updatestudentassesssheet {
                      'totalpoints' =>
                      'Total Points Granted<br>totalpoints');
         my $adduserstr='';
-        if ((&getuname($safeeval) ne $ENV{'user.name'}) ||
-            (&getudom($safeeval) ne $ENV{'user.domain'})) {
-            $adduserstr='&uname='.&getuname($safeeval).
-                '&udom='.&getudom($safeeval);
+        if (($uname ne $ENV{'user.name'}) || ($udom ne $ENV{'user.domain'})){
+            $adduserstr='&uname='.$uname.'&udom='.$udom;
         }
         my %allassess =
             ('_feedback' =>'<a href="/adm/assesscalc?usymb=_feedback'.
@@ -1862,7 +1745,7 @@ sub updatestudentassesssheet {
         } elsif ($stype eq 'studentcalc') {
             %current=%allassess;
         }
-        $updatedata{$ENV{'request.course.fn'}.'_'.$stype}=
+        $updatedata{$ENV{'request.course.fn'}.'_'.$stype.'_'.$uname.'_'.$udom}=
             join('___;___',%current);
         # Get current from cache
     }
@@ -1897,7 +1780,7 @@ sub updatestudentassesssheet {
         }
     }
     if ($changed) { &setformulas($safeeval,%f); }
-    &setmaxrow($safeeval,$maxrow);
+    $sheetdata->{'maxrow'} = $maxrow;
     &setrowlabels($safeeval,%current);
     #
     undef %current;
@@ -1954,7 +1837,7 @@ sub loadstudent {
 }
 
 # --------------------------------------------------- Load data for one student
-
+#
 sub loadcourse {
     my ($safeeval,$sheetdata,$r)=@_;
     my %c=();
@@ -2016,7 +1899,7 @@ ENDPOP
 }
 
 # ------------------------------------------------ Load data for one assessment
-
+#
 sub loadassessment {
     my ($safeeval,$sheetdata)=@_;
 
@@ -2048,30 +1931,23 @@ sub loadassessment {
         #
         # restore individual
         #
-        my $answer=&Apache::lonnet::reply(
-                                          "restore:$udom:$uname:".
-                                          &Apache::lonnet::escape($namespace).":".
-                                          &Apache::lonnet::escape($symb),$uhome);
-        foreach (split(/\&/,$answer)) {
-            my ($name,$value)=split(/\=/,$_);
-            $returnhash{&Apache::lonnet::unescape($name)}=
-                &Apache::lonnet::unescape($value);
-        }
-        my $version;
-        for ($version=1;$version<=$returnhash{'version'};$version++) {
+        %returnhash = &Apache::lonnet::restore($symb,$namespace,$udom,$uname);
+        for (my $version=1;$version<=$returnhash{'version'};$version++) {
             foreach (split(/\:/,$returnhash{$version.':keys'})) {
                 $returnhash{$_}=$returnhash{$version.':'.$_};
             } 
         }
     }
+    #
     # returnhash now has all stores for this resource
     # convert all "_" to "." to be able to use libraries, multiparts, etc
+    #
+    # This is dumb.  It is also necessary :(
     my @oldkeys=keys %returnhash;
-
-    foreach (@oldkeys) {
-        my $name=$_;
-        my $value=$returnhash{$_};
-        delete $returnhash{$_};
+    #
+    foreach my $name (@oldkeys) {
+        my $value=$returnhash{$name};
+        delete $returnhash{$name};
         $name=~s/\_/\./g;
         $returnhash{$name}=$value;
     }
@@ -2080,36 +1956,28 @@ sub loadassessment {
     undef %useropt;
 
     my $userprefix=$uname.'_'.$udom.'_';
-    
+
     unless ($uhome eq 'no_host') { 
         # Get coursedata
         unless ((time-$courserdatas{$cid.'.last_cache'})<240) {
-            my $reply=&Apache::lonnet::reply('dump:'.$cdom.':'.$cnum.
-                                             ':resourcedata',$chome);
-            if ($reply!~/^error\:/) {
-                $courserdatas{$cid}=$reply;
-                $courserdatas{$cid.'.last_cache'}=time;
-            }
+            my %Tmp = &Apache::lonnet::dump('resourcedata',$cdom,$cnum);
+            $courserdatas{$cid}=\%Tmp;
+            $courserdatas{$cid.'.last_cache'}=time;
         }
-        foreach (split(/\&/,$courserdatas{$cid})) {
-            my ($name,$value)=split(/\=/,$_);
-            $courseopt{$userprefix.&Apache::lonnet::unescape($name)}=
-                &Apache::lonnet::unescape($value);  
+        while (my ($name,$value) = each(%{$courserdatas{$cid}})) {
+            $courseopt{$userprefix.$name}=$value;
         }
         # Get userdata (if present)
-        unless
-            ((time-$userrdatas{$uname.'___'.$udom.'.last_cache'})<240) {
-                my $reply=
-                    &Apache::lonnet::reply('dump:'.$udom.':'.$uname.':resourcedata',$uhome);
-                if ($reply!~/^error\:/) {
-                    $userrdatas{$uname.'___'.$udom}=$reply;
-                    $userrdatas{$uname.'___'.$udom.'.last_cache'}=time;
-                }
-            }
-        foreach (split(/\&/,$userrdatas{$uname.'___'.$udom})) {
-            my ($name,$value)=split(/\=/,$_);
-            $useropt{$userprefix.&Apache::lonnet::unescape($name)}=
-                &Apache::lonnet::unescape($value);
+        unless ((time-$userrdatas{$uname.'@'.$udom.'.last_cache'})<240) {
+            my %Tmp = &Apache::lonnet::dump('resourcedata',$udom,$uname);
+            $userrdatas{$cid} = \%Tmp;
+            # Most of the time the user does not have a 'resourcedata.db' 
+            # file.  We need to cache that we got nothing instead of bothering
+            # with requesting it every time.
+            $userrdatas{$uname.'@'.$udom.'.last_cache'}=time;
+        }
+        while (my ($name,$value) = each(%{$userrdatas{$cid}})) {
+            $useropt{$userprefix.$name}=$value;
         }
     }
     # now courseopt, useropt initialized for this user and course
@@ -2127,7 +1995,7 @@ sub loadassessment {
     #
     my %c=();
     if (tie(%parmhash,'GDBM_File',
-            &getcfn($safeeval).'_parms.db',&GDBM_READER(),0640)) {
+            $sheetdata->{'coursefilename'}.'_parms.db',&GDBM_READER(),0640)) {
         my %f=&getformulas($safeeval);
         foreach (keys(%f))  {
             next if ($_!~/^A/);
@@ -2185,9 +2053,9 @@ sub updatesheet {
     my ($safeeval,$sheetdata)=@_;
     my $stype=$sheetdata->{'sheettype'};
     if ($stype eq 'classcalc') {
-	return &updateclasssheet($safeeval);
+	return &updateclasssheet($safeeval,$sheetdata);
     } else {
-        return &updatestudentassesssheet($safeeval);
+        return &updatestudentassesssheet($safeeval,$sheetdata);
     }
 }
 
@@ -2296,8 +2164,8 @@ sub exportsheet {
         &readsheet($thissheet,$sheetdata,$fn);
         &updatesheet($thissheet,$sheetdata);
         &loadrows($thissheet,$sheetdata);
-        &calcsheet($thissheet,$sheetdata); 
-        @exportarr=&exportdata($thissheet,$sheetdata);
+        &calcsheet($thissheet); 
+        @exportarr=&exportdata($thissheet);
         #
         # Store now
         #
@@ -2433,10 +2301,17 @@ sub cachedssheets {
 # Interactive call to screen
 #
 #
-
-
 sub handler {
     my $r=shift;
+
+    # Check this server
+    my $loaderror=&Apache::lonnet::overloaderror($r);
+    if ($loaderror) { return $loaderror; }
+    # Check the course homeserver
+    $loaderror= &Apache::lonnet::overloaderror($r,
+                      $ENV{'course.'.$ENV{'request.course.id'}.'.home'});
+    if ($loaderror) { return $loaderror; } 
+    
     if ($r->header_only) {
         $r->content_type('text/html');
         $r->send_http_header;
@@ -2455,6 +2330,10 @@ sub handler {
     # Get query string for limited number of parameters
     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                                             ['uname','udom','usymb','ufn']);
+    if ($ENV{'request.role'} =~ /^st\./) {
+        delete $ENV{'form.unewfield'}   if (exists($ENV{'form.unewfield'}));
+        delete $ENV{'form.unewformula'} if (exists($ENV{'form.unewformula'}));
+    }
     if (($ENV{'form.usymb'}=~/^\_(\w+)/) && (!$ENV{'form.ufn'})) {
         $ENV{'form.ufn'}='default_'.$1;
     }
@@ -2481,7 +2360,8 @@ sub handler {
     $r->send_http_header;
     # Screen output
     $r->print('<html><head><title>LON-CAPA Spreadsheet</title>');
-    $r->print(<<ENDSCRIPT);
+    if ($ENV{'request.role'} !~ /^st\./) {
+        $r->print(<<ENDSCRIPT);
 <script language="JavaScript">
 
     function celledit(cn,cf) {
@@ -2507,6 +2387,7 @@ sub handler {
 
 </script>
 ENDSCRIPT
+    }
     $r->print('</head>'.&Apache::loncommon::bodytag('Grades Spreadsheet').
               '<form action="'.$r->uri.'" name=sheet method=post>');
     $r->print(&hiddenfield('uname',$ENV{'form.uname'}).
@@ -2527,7 +2408,7 @@ ENDSCRIPT
     }
     # Read new sheet or modified worksheet
     $r->uri=~/\/(\w+)$/;
-    my ($asheet,$asheetdata)=&makenewsheet($aname,$adom,$1,$ENV{'form.usymb'});
+    my ($sheet,$sheetdata)=&makenewsheet($aname,$adom,$1,$ENV{'form.usymb'});
     #
     # If a new formula had been entered, go from work copy
     if ($ENV{'form.unewfield'}) {
@@ -2535,24 +2416,20 @@ ENDSCRIPT
         $ENV{'form.unewformula'}=~s/\'/\"/g;
         $r->print('<p>New formula: '.$ENV{'form.unewfield'}.'='.
                   $ENV{'form.unewformula'}.'<p>');
-        &setfilename($asheet,$ENV{'form.ufn'});
-        &tmpread($asheet,$ENV{'form.unewfield'},$ENV{'form.unewformula'});
+        $sheetdata->{'filename'} = $ENV{'form.ufn'};
+        &tmpread($sheet,$sheetdata,
+                 $ENV{'form.unewfield'},$ENV{'form.unewformula'});
     } elsif ($ENV{'form.saveas'}) {
-        &setfilename($asheet,$ENV{'form.ufn'});
-        &tmpread($asheet);
+        $sheetdata->{'filename'} = $ENV{'form.ufn'};
+        &tmpread($sheet,$sheetdata);
     } else {
-        &readsheet($asheet,$asheetdata,$ENV{'form.ufn'});
+        &readsheet($sheet,$sheetdata,$ENV{'form.ufn'});
     }
     # Print out user information
-    unless ($asheetdata->{'sheettype'} eq 'classcalc') {
-        $r->print('<p><b>User:</b> '.$asheetdata->{'uname'}.
-                  '<br><b>Domain:</b> '.$asheetdata->{'udom'});
-        if (&getcsec($asheet) eq '-1') {
-            $r->print('<h3><font color=red>'.
-                      'Not a student in this course</font></h3>');
-        } else {
-            $r->print('<br><b>Section/Group:</b> '.$asheetdata->{'csec'});
-        }
+    unless ($sheetdata->{'sheettype'} eq 'classcalc') {
+        $r->print('<p><b>User:</b> '.$sheetdata->{'uname'}.
+                  '<br><b>Domain:</b> '.$sheetdata->{'udom'});
+        $r->print('<br><b>Section/Group:</b> '.$sheetdata->{'csec'});
         if ($ENV{'form.usymb'}) {
             $r->print('<br><b>Assessment:</b> <tt>'.
                       $ENV{'form.usymb'}.'</tt>');
@@ -2560,10 +2437,10 @@ ENDSCRIPT
     }
     #
     # Check user permissions
-    if (($asheetdata->{'sheettype'} eq 'classcalc'       ) || 
-        ($asheetdata->{'uname'}     ne $ENV{'user.name'} ) ||
-        ($asheetdata->{'udom'}      ne $ENV{'user.domain'})) {
-        unless (&Apache::lonnet::allowed('vgr',$asheetdata->{'cid'})) {
+    if (($sheetdata->{'sheettype'} eq 'classcalc'       ) || 
+        ($sheetdata->{'uname'}     ne $ENV{'user.name'} ) ||
+        ($sheetdata->{'udom'}      ne $ENV{'user.domain'})) {
+        unless (&Apache::lonnet::allowed('vgr',$sheetdata->{'cid'})) {
             $r->print('<h1>Access Permission Denied</h1>'.
                       '</form></body></html>');
             return OK;
@@ -2573,15 +2450,15 @@ ENDSCRIPT
     $r->print('<br />'.
               '<input type="submit" name="forcerecalc" '.
               'value="Completely Recalculate Sheet"><p>');
-    if ($asheetdata->{'sheettype'} eq 'assesscalc') {
+    if ($sheetdata->{'sheettype'} eq 'assesscalc') {
         $r->print('<p><font size=+2>'.
                   '<a href="/adm/studentcalc?'.
-                  'uname='.$asheetdata->{'uname'}.
-                  '&udom='.$asheetdata->{'udom'}.'">'.
+                  'uname='.$sheetdata->{'uname'}.
+                  '&udom='.$sheetdata->{'udom'}.'">'.
                   'Level up: Student Sheet</a></font><p>');
     }
-    if (($asheetdata->{'sheettype'} eq 'studentcalc') && 
-        (&Apache::lonnet::allowed('vgr',$asheetdata->{'cid'}))) {
+    if (($sheetdata->{'sheettype'} eq 'studentcalc') && 
+        (&Apache::lonnet::allowed('vgr',$sheetdata->{'cid'}))) {
         $r->print ('<p><font size=+2><a href="/adm/classcalc">'.
                    'Level up: Course Sheet</a></font><p>');
     }
@@ -2594,13 +2471,13 @@ ENDSCRIPT
                   '<input type=text size=20 name=newfn value="'.$fname.'">'.
                   'make default: <input type=checkbox name="makedefufn"><p>');
     }
-    $r->print(&hiddenfield('ufn',&getfilename($asheet)));
+    $r->print(&hiddenfield('ufn',$sheetdata->{'filename'}));
     # Load dialog
     if (&Apache::lonnet::allowed('opa',$ENV{'request.course.id'})) {
         $r->print('<p><input type=submit name=load value="Load ...">'.
                   '<select name="loadthissheet">'.
                   '<option name="default">Default</option>');
-        foreach (&othersheets($asheet,$asheetdata->{'sheettype'})) {
+        foreach (&othersheets($sheet,$sheetdata->{'sheettype'},$sheetdata)) {
             $r->print('<option name="'.$_.'"');
             if ($ENV{'form.ufn'} eq $_) {
                 $r->print(' selected');
@@ -2608,37 +2485,38 @@ ENDSCRIPT
             $r->print('>'.$_.'</option>');
         } 
         $r->print('</select><p>');
-        if (&gettype($asheet) eq 'studentcalc') {
-            &setothersheets($asheet,&othersheets($asheet,'assesscalc'));
+        if ($sheetdata->{'sheettype'} eq 'studentcalc') {
+            &setothersheets($sheet,
+                            &othersheets($sheet,'assesscalc',$sheetdata));
         }
     }
     # Cached sheets
     &expirationdates();
     undef %oldsheets;
     undef %loadedcaches;
-    if ($asheetdata->{'sheettype'} eq 'classcalc') {
+    if ($sheetdata->{'sheettype'} eq 'classcalc') {
         $r->print("Loading previously calculated student sheets ...\n");
         $r->rflush();
         &cachedcsheets();
-    } elsif ($asheetdata->{'sheettype'} eq 'studentcalc') {
+    } elsif ($sheetdata->{'sheettype'} eq 'studentcalc') {
         $r->print("Loading previously calculated assessment sheets ...\n");
         $r->rflush();
-        &cachedssheets($asheetdata->{'uname'},$asheetdata->{'udom'},
-                       $asheetdata->{'uhome'});
+        &cachedssheets($sheetdata->{'uname'},$sheetdata->{'udom'},
+                       $sheetdata->{'uhome'});
     }
     # Update sheet, load rows
     $r->print("Loaded sheet(s), updating rows ...<br>\n");
     $r->rflush();
     #
-    &updatesheet($asheet,$asheetdata);
+    &updatesheet($sheet,$sheetdata);
     $r->print("Updated rows, loading row data ...\n");
     $r->rflush();
     #
-    &loadrows($asheet,$asheetdata,$r);
+    &loadrows($sheet,$sheetdata,$r);
     $r->print("Loaded row data, calculating sheet ...<br>\n");
     $r->rflush();
     #
-    my $calcoutput=&calcsheet($asheet);
+    my $calcoutput=&calcsheet($sheet);
     $r->print('<h3><font color=red>'.$calcoutput.'</h3></font>');
     # See if something to save
     if (&Apache::lonnet::allowed('opa',$ENV{'request.course.id'})) {
@@ -2646,18 +2524,19 @@ ENDSCRIPT
         if ($ENV{'form.saveas'} && ($fname=$ENV{'form.newfn'})) {
             $fname=~s/\W/\_/g;
             if ($fname eq 'default') { $fname='course_default'; }
-            $fname.='_'.$asheetdata->{'sheettype'};
-            &setfilename($asheet,$fname);
+            $fname.='_'.$sheetdata->{'sheettype'};
+            $sheetdata->{'filename'} = $fname;
             $ENV{'form.ufn'}=$fname;
             $r->print('<p>Saving spreadsheet: '.
-                      &writesheet($asheet,$ENV{'form.makedefufn'}).'<p>');
+                      &writesheet($sheet,$ENV{'form.makedefufn'},$sheetdata).
+                      '<p>');
         }
     }
     #
-    #Write the modified worksheet
-    $r->print('<b>Current sheet:</b> '.&getfilename($asheet).'<p>');
-    &tmpwrite($asheet);
-    if ($asheetdata->{'sheettype'} eq 'studentcalc') {
+    # Write the modified worksheet
+    $r->print('<b>Current sheet:</b> '.$sheetdata->{'filename'}.'<p>');
+    &tmpwrite($sheet,$sheetdata);
+    if ($sheetdata->{'sheettype'} eq 'studentcalc') {
         $r->print('<br>Show rows with empty A column: ');
     } else {
         $r->print('<br>Show empty rows: ');
@@ -2680,7 +2559,7 @@ ENDSCRIPT
     $r->print('>');
     #
     # CSV format checkbox (classcalc sheets only)
-    if ($asheetdata->{'sheettype'} eq 'classcalc') {
+    if ($sheetdata->{'sheettype'} eq 'classcalc') {
         $r->print(' Output CSV format: <input type="checkbox" '.
                   'name="showcsv" onClick="submit()"');
         if ($ENV{'form.showcsv'}) { $r->print(' checked'); }
@@ -2699,7 +2578,7 @@ value='Insert Row Top'>
 value='Insert Row Bottom'><br>
 ENDINSERTBUTTONS
     # Print out sheet
-    &outsheet($r,$asheet,$asheetdata);
+    &outsheet($r,$sheet,$sheetdata);
     $r->print('</form></body></html>');
     #  Done
     return OK;