--- loncom/interface/spreadsheet/Spreadsheet.pm 2005/08/26 20:46:46 1.54
+++ loncom/interface/spreadsheet/Spreadsheet.pm 2007/01/25 22:00:07 1.73.2.1
@@ -1,5 +1,5 @@
#
-# $Id: Spreadsheet.pm,v 1.54 2005/08/26 20:46:46 albertel Exp $
+# $Id: Spreadsheet.pm,v 1.73.2.1 2007/01/25 22:00:07 albertel Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -60,6 +60,9 @@ use HTML::TokeParser;
use Spreadsheet::WriteExcel;
use Time::HiRes;
use Apache::lonlocal;
+use lib '/home/httpd/lib/perl/';
+use LONCAPA;
+
##
## Package Variables
@@ -85,7 +88,7 @@ sub new {
my $class = ref($this) || $this;
my ($stype) = ($class =~ /Apache::(.*)$/);
#
- my ($name,$domain,$filename,$usymb)=@_;
+ my ($name,$domain,$filename,$usymb,$section,$groups)=@_;
if (defined($usymb) && ref($usymb)) {
$usymb = $usymb->symb;
}
@@ -95,10 +98,22 @@ sub new {
if (! defined($domain) || $domain eq '') {
$domain = $env{'user.domain'};
}
+ if (! defined($section) || $section eq '') {
+ $section = &Apache::lonnet::getsection($domain,$name,
+ $env{'request.course.id'});
+ }
+ if (! defined($groups)) {
+
+ my @usersgroups = &Apache::lonnet::get_users_groups($domain,$name,
+ $env{'request.course.id'});
+ $groups = \@usersgroups;
+ }
#
my $self = {
name => $name,
domain => $domain,
+ section => $section,
+ groups => $groups,
type => $stype,
symb => $usymb,
errorlog => '',
@@ -157,16 +172,20 @@ sub filename {
$newfilename = 'default_'.$self->{'type'};
}
}
- if ($newfilename !~ /\w/ || $newfilename =~ /^\W*$/) {
- $newfilename = 'default_'.$self->{'type'};
- }
- if ($newfilename !~ /^default\.$self->{'type'}$/ &&
- $newfilename !~ /^\/res\/(.*)spreadsheet$/) {
- if ($newfilename !~ /_$self->{'type'}$/) {
- $newfilename =~ s/[\s_]*$//;
- $newfilename .= '_'.$self->{'type'};
- }
- }
+ if ($newfilename eq &mt('LON-CAPA Standard')) {
+ undef($newfilename);
+ } else {
+ if ($newfilename !~ /\w/ || $newfilename =~ /^\W*$/) {
+ $newfilename = 'default_'.$self->{'type'};
+ }
+ if ($newfilename !~ /^default\.$self->{'type'}$/ &&
+ $newfilename !~ /^\/res\/(.*)spreadsheet$/) {
+ if ($newfilename !~ /_$self->{'type'}$/) {
+ $newfilename =~ s/[\s_]*$//;
+ $newfilename .= '_'.$self->{'type'};
+ }
+ }
+ }
$self->{'filename'} = $newfilename;
return;
}
@@ -191,6 +210,8 @@ sub make_default {
{'spreadsheet_default_'.$self->{'type'} => $self->filename()},
$self->{'cdom'},$self->{'cnum'});
return $result if ($result ne 'ok');
+ &Apache::lonnet::appenv('course.'.$self->{'cid'}.'.spreadsheet_default_'.
+ $self->{'type'} => $self->filename());
my $symb = $self->{'symb'};
$symb = '' if (! defined($symb));
&Apache::lonnet::expirespread('','',$self->{'type'},$symb);
@@ -211,16 +232,8 @@ course environment. Returns 0 otherwise
sub is_default {
my $self = shift;
# Check to find out if we are the default spreadsheet (filenames match)
- my $default_filename = '';
- my %tmphash = &Apache::lonnet::get('environment',
- ['spreadsheet_default_'.
- $self->{'type'}],
- $self->{'cdom'},
- $self->{'cnum'});
- my ($tmp) = keys(%tmphash);
- if ($tmp !~ /^(con_lost|error|no_such_host)/i) {
- $default_filename = $tmphash{'spreadsheet_default_'.$self->{'type'}};
- }
+ my $default_filename = $env{'course.'.$self->{'cid'}.
+ '.spreadsheet_default_'.$self->{'type'}};
if ($default_filename =~ /^\s*$/) {
$default_filename = 'default_'.$self->{'type'};
}
@@ -384,10 +397,12 @@ Calls the system EXT function to determi
#-------------------------------------------------------
sub EXT {
- my ($parameter) = @_;
+ my ($parameter,$specific_symb) = @_;
return '' if (! defined($parameter) || $parameter eq '');
$parameter =~ s/^parameter\./resource\./;
- my $value = &Apache::lonnet::EXT($parameter,$symb,$domain,$name,$usection);
+ if ($specific_symb eq '') { $specific_symb = $symb; }
+ my $value = &Apache::lonnet::EXT($parameter,$specific_symb,$domain,$name,
+ $usection);
return $value;
}
@@ -703,7 +718,7 @@ sub get_values {
}
return \@values;
} else {
- $num = '(\d+)';
+ $num = '([1-9]\d*)';
}
if (($la eq '*') || ($ua eq '*')) {
$alpha='[A-z]';
@@ -792,6 +807,8 @@ sub expandnamed {
if ($expression=~/^\&/) {
my ($func,$var,$formula)=($expression=~/^\&(\w+)\(([^\;]+)\;(.*)\)/);
my @vars=split(/\W+/,$formula);
+ # make the list uniq
+ @vars = keys(%{{ map { $_ => 1 } @vars }});
my %values=();
foreach my $varname ( @vars ) {
if ($varname=~/^(parameter|stores|timestamp)/) {
@@ -812,7 +829,7 @@ sub expandnamed {
$result.=$thissum.'+';
}
$result=~s/\+$//;
- return $result;
+ return '('.$result.')';
} else {
return 0;
}
@@ -1199,12 +1216,19 @@ sub display {
last;
}
}
+ $self->{outputmode} = $outputmode;
if ($outputmode eq 'html') {
$self->compute($r);
$self->outsheet_html($r);
} elsif ($outputmode eq 'htmlclasslist') {
# No computation neccessary... This is kludgy
$self->outsheet_htmlclasslist($r);
+ } elsif ($outputmode eq 'source') {
+ # No computation necessary. Rumor has it that this is some
+ # sort of kludge w.r.t. not "computing". It's also
+ # a bit of of a kludge that we call "outsheet_html" and
+ # let the 'outputmode' cause the outputting of source.
+ $self->outsheet_html($r);
} elsif ($outputmode eq 'excel') {
$self->compute($r);
$self->outsheet_excel($r);
@@ -1244,10 +1268,12 @@ sub html_export_row {
foreach my $cell (@rowdata) {
if ($cell->{'name'} =~ /^[A-Z]/) {
$row_html .= '
'.
- &html_editable_cell($cell,$color,$allowed).' | ';
+ &html_editable_cell($cell,$color,$allowed,
+ $self->{outputmode} eq 'source').'';
} else {
$row_html .= ''.
- &html_editable_cell($cell,'#DDCCFF',$allowed).' | ';
+ &html_editable_cell($cell,'#DDCCFF',$allowed,
+ $self->{outputmode} eq 'source').'';
}
}
return $row_html;
@@ -1266,15 +1292,16 @@ sub html_template_row {
$row_html .= ''.
&html_uneditable_cell($cell,'#FFDDDD',$allowed).' | ';
} else {
- $row_html .= ''.
- &html_editable_cell($cell,'#EOFFDD',$allowed).' | ';
+ $row_html .= ''.
+ &html_editable_cell($cell,'#E0FFDD',$allowed,
+ $self->{outputmode} eq 'source').' | ';
}
}
return $row_html;
}
sub html_editable_cell {
- my ($cell,$bgcolor,$allowed) = @_;
+ my ($cell,$bgcolor,$allowed,$showsource) = @_;
my $result;
my ($name,$formula,$value);
if (defined($cell)) {
@@ -1284,7 +1311,13 @@ sub html_editable_cell {
}
$name = '' if (! defined($name));
$formula = '' if (! defined($formula));
- if (! defined($value)) {
+ if ($showsource) {
+ if (!defined($formula) || $formula =~ /^\s*$/) {
+ $value = '#';
+ } else {
+ $value = &HTML::Entities::encode($formula, '<>&"');
+ }
+ } elsif (! defined($value)) {
$value = '#';
if ($formula ne '') {
$value = 'undefined value';
@@ -1336,8 +1369,9 @@ sub html_row {
$row_html .= '';
$row_html .= &html_uneditable_cell($cell,'#FFDDDD');
} else {
- $row_html .= ' | ';
- $row_html .= &html_editable_cell($cell,'#E0FFDD',$allowed);
+ $row_html .= ' | ';
+ $row_html .= &html_editable_cell($cell,'#E0FFDD',$allowed,
+ $self->{outputmode} eq 'source');
}
$row_html .= ' | ';
}
@@ -1361,6 +1395,8 @@ sub output_options {
description => 'HTML'},
{value => 'excel',
description => 'Excel'},
+ {value => 'source',
+ description => 'Show Source'},
# {value => 'xml',
# description => 'XML'},
{value => 'csv',
@@ -1629,7 +1665,7 @@ sub load {
$self->{'row_source'}=$spreadsheets{$cachekey}->{'row_source'};
$self->{'row_numbers'}=$spreadsheets{$cachekey}->{'row_numbers'};
$self->{'maxrow'}=$spreadsheets{$cachekey}->{'maxrow'};
- } else {
+ } else {
# Not cached, need to read
if (! defined($filename)) {
$formulas = $self->load_system_default_sheet();
@@ -1654,7 +1690,8 @@ sub load {
# Load the spreadsheet definition file from the save file
my %tmphash = &Apache::lonnet::dump($filename,$cdom,$cnum);
my ($tmp) = keys(%tmphash);
- if ($tmp !~ /^(con_lost|error|no_such_host)/i) {
+ if (%tmphash
+ && $tmp !~ /^(con_lost|error|no_such_host)/i) {
while (my ($cell,$formula) = each(%tmphash)) {
$formulas->{$cell}=$formula;
}
@@ -1662,26 +1699,35 @@ sub load {
$formulas = $self->load_system_default_sheet();
}
}
- $filename=$self->filename(); # filename may have changed
- $cachekey = join('_',($cnum,$cdom,$stype,$filename));
- if (ref($formulas) eq 'HASH') {
- %{$spreadsheets{$cachekey}->{'formulas'}} = %{$formulas};
- }
$self->formulas($formulas);
$self->set_row_sources();
$self->set_row_numbers();
- if (ref($self->{'row_source'})) {
- %{$spreadsheets{$cachekey}->{'row_source'}} =
- %{$self->{'row_source'}};
- }
- if (ref($self->{'row_numbers'})) {
- %{$spreadsheets{$cachekey}->{'row_numbers'}} =
- %{$self->{'row_numbers'}};
- }
- $spreadsheets{$cachekey}->{'maxrow'} = $self->{'maxrow'};
+ $self->cache_sheet($formulas);
}
}
+sub cache_sheet {
+ my $self = shift;
+ my ($formulas) = @_;
+ my $stype = $self->{'type'};
+ my $cnum = $self->{'cnum'};
+ my $cdom = $self->{'cdom'};
+ #
+ my $filename = $self->filename();
+ my $cachekey = join('_',($cnum,$cdom,$stype,$filename));
+
+ if (ref($formulas) eq 'HASH') {
+ %{$spreadsheets{$cachekey}->{'formulas'}} = %{$formulas};
+ }
+ if (ref($self->{'row_source'})) {
+ %{$spreadsheets{$cachekey}->{'row_source'}} =%{$self->{'row_source'}};
+ }
+ if (ref($self->{'row_numbers'})) {
+ %{$spreadsheets{$cachekey}->{'row_numbers'}}=%{$self->{'row_numbers'}};
+ }
+ $spreadsheets{$cachekey}->{'maxrow'} = $self->{'maxrow'};
+}
+
sub set_row_sources {
my $self = shift;
$self->check_formulas_loaded();
@@ -1731,9 +1777,8 @@ sub save {
my $cnum = $self->{'cnum'};
my $cdom = $self->{'cdom'};
my $filename = $self->{'filename'};
- my $cachekey = join('_',($cnum,$cdom,$stype,$filename));
# Cache new sheet
- %{$spreadsheets{$cachekey}->{'formulas'}}=%f;
+ $self->cache_sheet(\%f);
# Write sheet
foreach (keys(%f)) {
delete($f{$_}) if ($f{$_} eq 'import');
@@ -1749,14 +1794,14 @@ sub save {
{'spreadsheet_default_'.$stype => $filename },
$cdom,$cnum);
return $reply if ($reply ne 'ok');
+ &Apache::lonnet::appenv('course.'.$self->{'cid'}.'.spreadsheet_default_'.
+ $self->{'type'} => $self->filename());
}
- if ($self->is_default()) {
- if ($self->{'type'} eq 'studentcalc') {
- &Apache::lonnet::expirespread('','','studentcalc','');
- } elsif ($self->{'type'} eq 'assesscalc') {
- &Apache::lonnet::expirespread('','','assesscalc','');
- &Apache::lonnet::expirespread('','','studentcalc','');
- }
+ if ($self->{'type'} eq 'studentcalc') {
+ &Apache::lonnet::expirespread('','','studentcalc','');
+ } elsif ($self->{'type'} eq 'assesscalc') {
+ &Apache::lonnet::expirespread('','','assesscalc','');
+ &Apache::lonnet::expirespread('','','studentcalc','');
}
return $reply;
}
@@ -1778,8 +1823,8 @@ sub save_tmp {
my %f = $self->formulas();
while( my ($cell,$formula) = each(%f)) {
next if ($formula eq 'import');
- print $fh &Apache::lonnet::escape($cell)."=".
- &Apache::lonnet::escape($formula)."\n";
+ print $fh &escape($cell)."=".
+ &escape($formula)."\n";
}
$fh->close();
}
@@ -1797,8 +1842,8 @@ sub load_tmp {
while (<$spreadsheet_file>) {
chomp;
my ($cell,$formula) = split(/=/);
- $cell = &Apache::lonnet::unescape($cell);
- $formula = &Apache::lonnet::unescape($formula);
+ $cell = &unescape($cell);
+ $formula = &unescape($formula);
$formulas{$cell} = $formula;
}
$spreadsheet_file->close();
@@ -1841,14 +1886,13 @@ sub othersheets {
my ($stype) = @_;
$stype = $self->{'type'} if (! defined($stype) || $stype !~ /calc$/);
#
- my @alternatives=();
+ my @alternatives=(&mt('Default'), &mt('LON-CAPA Standard'));
my %results=&Apache::lonnet::dump($stype.'_spreadsheets',
$self->{'cdom'}, $self->{'cnum'});
my ($tmp) = keys(%results);
- if ($tmp =~ /^(con_lost|error|no_such_host)/i ) {
- @alternatives = (&mt('Default'));
- } else {
- @alternatives = (&mt('Default'), sort (keys(%results)));
+ if (%results
+ && $tmp !~ /^(con_lost|error|no_such_host)/i ) {
+ push(@alternatives, sort(keys(%results)));
}
return @alternatives;
}