--- 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/\&nbsp;/ /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/\&nbsp;/ /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)=@_;