--- loncom/interface/spreadsheet/Spreadsheet.pm 2003/05/16 20:55:11 1.1 +++ loncom/interface/spreadsheet/Spreadsheet.pm 2003/05/28 15:20:40 1.9 @@ -1,5 +1,5 @@ # -# $Id: Spreadsheet.pm,v 1.1 2003/05/16 20:55:11 matthew Exp $ +# $Id: Spreadsheet.pm,v 1.9 2003/05/28 15:20:40 matthew Exp $ # # Copyright Michigan State University Board of Trustees # @@ -97,6 +97,11 @@ sub new { chome => $ENV{'course.'.$ENV{'request.course.id'}.'.home'}, coursedesc => $ENV{'course.'.$ENV{'request.course.id'}.'.description'}, coursefilename => $ENV{'request.course.fn'}, + temporary => '', + # + # blackout is used to determine if any data needs to be hidden from the + # student. + blackout => 0, # # Data storage formulas => {}, @@ -137,7 +142,7 @@ sub filename { if (@_) { my ($newfilename) = @_; if (! defined($newfilename) || $newfilename eq 'Default' || - $newfilename !~ /\w/ || $newfilename =~ /\W/) { + $newfilename !~ /\w/) { my %tmphash = &Apache::lonnet::get('environment', ['spreadsheet_default_'. $self->{'type'}], @@ -147,12 +152,13 @@ sub filename { if ($tmp !~ /^(con_lost|error|no_such_host)/i) { $newfilename=$tmphash{'spreadsheet_default_'.$self->{'type'}}; } - } - if (! defined($newfilename) || - $newfilename !~ /\w/ || - $newfilename =~ /^\W*$/) { - $newfilename = 'default.'.$self->{'type'}; - } else { + if (! defined($newfilename) || + $newfilename !~ /\w/ || + $newfilename =~ /^\W*$/) { + $newfilename = 'default.'.$self->{'type'}; + } + } elsif ($newfilename !~ /^\/res\/.*\.spreadsheet/ && + $newfilename !~ /^default\.$self->{'type'}$/ ) { my $regexp = '_'.$self->{'type'}.'$'; if ($newfilename !~ /$regexp/) { $newfilename .= '_'.$self->{'type'}; @@ -1105,6 +1111,24 @@ sub calcsheet { ## Output Helpers ## ########################################################### +sub display { + my $self = shift; + my ($r) = @_; + $self->compute($r); + my $outputmode = 'html'; + if ($ENV{'form.output_format'} =~ /^(html|excel|csv)$/) { + $outputmode = $ENV{'form.output_format'}; + } + if ($outputmode eq 'html') { + $self->outsheet_html($r); + } elsif ($outputmode eq 'excel') { + $self->outsheet_excel($r); + } elsif ($outputmode eq 'csv') { + $self->outsheet_csv($r); + } + return; +} + ############################################ ## HTML output routines ## ############################################ @@ -1135,8 +1159,8 @@ sub html_template_row { for (my $i = 0; $i<=$#rowdata; $i++) { my $cell = $rowdata[$i]; if ($i < $num_uneditable) { - $row_html .= '<td bgcolor="#DDCCFF">'. - &html_editable_cell($cell,'#DDCCFF',$allowed).'</td>'; + $row_html .= '<td bgcolor="#FFDDDD">'. + &html_uneditable_cell($cell,'#FFDDDD',$allowed).'</td>'; } else { $row_html .= '<td bgcolor="#EOFFDD">'. &html_editable_cell($cell,'#EOFFDD',$allowed).'</td>'; @@ -1207,6 +1231,55 @@ sub html_row { return $row_html; } +sub html_header { + my $self = shift; + return '' if (! $ENV{'request.role.adv'}); + return "<table>\n". + '<tr><th align="center">Output Format</th><tr>'."\n". + '<tr><td>'.&output_selector()."</td></tr>\n". + "</table>\n"; +} + +sub output_selector { + my $output_selector = '<select name="output_format" size="3">'."\n"; + my $default = 'html'; + if (exists($ENV{'form.output_format'})) { + $default = $ENV{'form.output_format'} + } else { + $ENV{'form.output_format'} = $default; + } + foreach (['html','HTML'], + ['excel','Excel'], + ['csv','Comma Seperated Values']) { + my ($name,$description) = @{$_}; + $output_selector.=qq{<option value="$name"}; + if ($name eq $default) { + $output_selector .= ' selected'; + } + $output_selector .= ">$description</option>\n"; + } + $output_selector .= "</select>\n"; + return $output_selector; +} + +################################################ +## Excel output routines ## +################################################ +sub excel_output_row { + my $self = shift; + my ($worksheet,$rownum,$rows_output,@prepend) = @_; + my $cols_output = 0; + # + my @rowdata = $self->get_row($rownum); + foreach my $cell (@prepend,@rowdata) { + my $value = $cell; + $value = $cell->{'value'} if (ref($value)); + $value =~ s/\ / /gi; + $worksheet->write($rows_output,$cols_output++,$value); + } + return; +} + sub create_excel_spreadsheet { my $self = shift; my ($r) = @_; @@ -1232,6 +1305,103 @@ sub create_excel_spreadsheet { return ($workbook,$filename); } +sub outsheet_excel { + my $self = shift; + my ($r) = @_; + $r->print("<h2>Preparing Excel Spreadsheet</h2>"); + # + # Create excel worksheet + my ($workbook,$filename) = $self->create_excel_spreadsheet($r); + return if (! defined($workbook)); + # + # Create main worksheet + my $worksheet = $workbook->addworksheet('main'); + my $rows_output = 0; + my $cols_output = 0; + # + # Write excel header + foreach my $value ($self->get_title()) { + $cols_output = 0; + $worksheet->write($rows_output++,$cols_output,$value); + } + $rows_output++; # skip a line + # + # Write summary/export row + $cols_output = 0; + $self->excel_output_row($worksheet,0,$rows_output++,'Summary'); + $rows_output++; # skip a line + # + $self->excel_rows($worksheet,$cols_output,$rows_output); + # + # + # Close the excel file + $workbook->close(); + # + # Write a link to allow them to download it + $r->print('<br />'. + '<a href="'.$filename.'">Your Excel spreadsheet.</a>'."\n"); + return; +} + +################################# +## CSV output routines ## +################################# +sub outsheet_csv { + my $self = shift; + my ($r) = @_; + my $csvdata = ''; + my @Values; + # + # Open the csv file + my $filename = '/prtspool/'. + $ENV{'user.name'}.'_'.$ENV{'user.domain'}.'_'. + time.'_'.rand(1000000000).'.csv'; + my $file; + unless ($file = Apache::File->new('>'.'/home/httpd'.$filename)) { + $r->log_error("Couldn't open $filename for output $!"); + $r->print("Problems occured in writing the csv file. ". + "This error has been logged. ". + "Please alert your LON-CAPA administrator."); + $r->print("<pre>\n".$csvdata."</pre>\n"); + return 0; + } + # + # Output the title information + foreach my $value ($self->get_title()) { + print $file "'".&Apache::loncommon::csv_translate($value)."'\n"; + } + # + # Output the body of the spreadsheet + $self->csv_rows($file); + # + # Close the csv file + close($file); + $r->print('<br /><br />'. + '<a href="'.$filename.'">Your CSV spreadsheet.</a>'."\n"); + # + return 1; +} + +sub csv_output_row { + my $self = shift; + my ($filehandle,$rownum,@prepend) = @_; + # + my @rowdata = (); + if (defined($rownum)) { + @rowdata = $self->get_row($rownum); + } + my @output = (); + foreach my $cell (@prepend,@rowdata) { + my $value = $cell; + $value = $cell->{'value'} if (ref($value)); + $value =~ s/\ / /gi; + $value = "'".$value."'"; + push (@output,$value); + } + print $filehandle join(',',@output )."\n"; + return; +} + ############################################ ## XML output routines ## ############################################ @@ -1328,7 +1498,7 @@ sub load { $sheetxml='<field row="0" col="A"></field>'; } ($formulas,undef) = &parse_sheet(\$sheetxml); - } elsif($self->filename() =~ /^\/*\.spreadsheet$/) { + } elsif($self->filename() =~ /^\/res\/.*\.spreadsheet$/) { # Load a spreadsheet definition file my $sheetxml=&Apache::lonnet::getfile (&Apache::lonnet::filelocation('',$filename)); @@ -1396,6 +1566,8 @@ sub save { my $self = shift; my ($makedef)=@_; my $cid=$self->{'cid'}; + # If we are saving it, it must not be temporary + $self->temporary(0); if (&Apache::lonnet::allowed('opa',$cid)) { my %f=$self->formulas(); my $stype = $self->{'type'}; @@ -1433,13 +1605,14 @@ sub save { sub save_tmp { my $self = shift; - my $fn=$ENV{'user.name'}.'_'. + my $filename=$ENV{'user.name'}.'_'. $ENV{'user.domain'}.'_spreadsheet_'.$self->{'usymb'}.'_'. $self->{'filename'}; - $fn=~s/\W/\_/g; - $fn=$Apache::lonnet::tmpdir.$fn.'.tmp'; + $filename=~s/\W/\_/g; + $filename=$Apache::lonnet::tmpdir.$filename.'.tmp'; + $self->temporary(1); my $fh; - if ($fh=Apache::File->new('>'.$fn)) { + if ($fh=Apache::File->new('>'.$filename)) { my %f = $self->formulas(); while( my ($cell,$formula) = each(%f)) { next if ($formula eq 'import'); @@ -1468,12 +1641,22 @@ sub load_tmp { } $spreadsheet_file->close(); } + # flag the sheet as temporary + $self->temporary(1); $self->formulas(\%formulas); $self->set_row_sources(); $self->set_row_numbers(); return; } +sub temporary { + my $self=shift; + if (@_) { + ($self->{'temporary'})= @_; + } + return $self->{'temporary'}; +} + sub modify_cell { # studentcalc overrides this my $self = shift; @@ -1500,12 +1683,20 @@ sub othersheets { my %results=&Apache::lonnet::dump($stype.'_spreadsheets', $self->{'cdom'}, $self->{'cnum'}); my ($tmp) = keys(%results); - unless ($tmp =~ /^(con_lost|error|no_such_host)/i ) { + if ($tmp =~ /^(con_lost|error|no_such_host)/i ) { + @alternatives = ('Default'); + } else { @alternatives = sort (keys(%results)); } return @alternatives; } +sub blackout { + my $self = shift; + $self->{'blackout'} = $_[0] if (@_); + return $self->{'blackout'}; +} + sub get_row { my $self = shift; my ($n)=@_;