Diff for /loncom/interface/spreadsheet/Spreadsheet.pm between versions 1.4 and 1.12

version 1.4, 2003/05/23 14:52:51 version 1.12, 2003/05/29 18:31:27
Line 97  sub new { Line 97  sub new {
         chome    => $ENV{'course.'.$ENV{'request.course.id'}.'.home'},          chome    => $ENV{'course.'.$ENV{'request.course.id'}.'.home'},
         coursedesc => $ENV{'course.'.$ENV{'request.course.id'}.'.description'},          coursedesc => $ENV{'course.'.$ENV{'request.course.id'}.'.description'},
         coursefilename => $ENV{'request.course.fn'},          coursefilename => $ENV{'request.course.fn'},
         temporary => '',          #
           # Flags
           temporary => 0,  # true if this sheet has been modified but not saved
           new_rows  => 0, # true if this sheet has new rows
         #          #
         # blackout is used to determine if any data needs to be hidden from the          # blackout is used to determine if any data needs to be hidden from the
         # student.          # student.
Line 142  sub filename { Line 145  sub filename {
     if (@_) {      if (@_) {
         my ($newfilename) = @_;          my ($newfilename) = @_;
         if (! defined($newfilename) || $newfilename eq 'Default' ||          if (! defined($newfilename) || $newfilename eq 'Default' ||
             $newfilename !~ /\w/    || $newfilename =~ /\W/) {              $newfilename !~ /\w/) {
             my %tmphash = &Apache::lonnet::get('environment',              my %tmphash = &Apache::lonnet::get('environment',
                                                ['spreadsheet_default_'.                                                 ['spreadsheet_default_'.
                                                 $self->{'type'}],                                                  $self->{'type'}],
Line 152  sub filename { Line 155  sub filename {
             if ($tmp !~ /^(con_lost|error|no_such_host)/i) {              if ($tmp !~ /^(con_lost|error|no_such_host)/i) {
                 $newfilename=$tmphash{'spreadsheet_default_'.$self->{'type'}};                  $newfilename=$tmphash{'spreadsheet_default_'.$self->{'type'}};
             }              }
         }              if (! defined($newfilename) || 
         if (! defined($newfilename) ||                   $newfilename !~ /\w/   || 
               $newfilename !~ /\w/   ||                   $newfilename =~ /^\W*$/) {
               $newfilename =~ /^\W*$/) {                  $newfilename = 'default.'.$self->{'type'};
             $newfilename = 'default.'.$self->{'type'};              }
         } else {          } elsif ($newfilename !~ /^\/res\/.*\.spreadsheet/ &&
                    $newfilename !~ /^default\.$self->{'type'}$/ ) {
             my $regexp = '_'.$self->{'type'}.'$';              my $regexp = '_'.$self->{'type'}.'$';
             if ($newfilename !~ /$regexp/) {              if ($newfilename !~ /$regexp/) {
                 $newfilename .= '_'.$self->{'type'};                  $newfilename .= '_'.$self->{'type'};
Line 221  sub is_default { Line 225  sub is_default {
     return 0;      return 0;
 }  }
   
   sub initialize {
       # This method is here to remind you that it will be overridden by
       # the descendents of the spreadsheet class.
   }
   
 sub initialize_spreadsheet_package {  sub initialize_spreadsheet_package {
     &load_spreadsheet_expirationdates();      &load_spreadsheet_expirationdates();
     &clear_spreadsheet_definition_cache();      &clear_spreadsheet_definition_cache();
Line 815  sub expandnamed { Line 824  sub expandnamed {
             push @matches,$parameter if ($parameter =~ /$expression/);              push @matches,$parameter if ($parameter =~ /$expression/);
         }          }
         if (scalar(@matches) == 0) {          if (scalar(@matches) == 0) {
             $returnvalue = 'unmatched parameter: '.$parameter;              $returnvalue = '""';#'"unmatched parameter: '.$parameter.'"';
         } elsif (scalar(@matches) == 1) {          } elsif (scalar(@matches) == 1) {
             # why do we not do this lookup here, instead of delaying it?              # why do we not do this lookup here, instead of delaying it?
             $returnvalue = '$c{\''.$matches[0].'\'}';              $returnvalue = '$c{\''.$matches[0].'\'}';
Line 831  sub expandnamed { Line 840  sub expandnamed {
         } else {          } else {
             # There was a negative number of matches, which indicates               # There was a negative number of matches, which indicates 
             # something is wrong with reality.  Better warn the user.              # something is wrong with reality.  Better warn the user.
             $returnvalue = 'bizzare parameter: '.$parameter;              $returnvalue = '"bizzare parameter: '.$parameter.'"';
         }          }
         return $returnvalue;          return $returnvalue;
     }      }
Line 1110  sub calcsheet { Line 1119  sub calcsheet {
 ## Output Helpers  ## 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           ##  ##         HTML output routines           ##
 ############################################  ############################################
Line 1140  sub html_template_row { Line 1167  sub html_template_row {
     for (my $i = 0; $i<=$#rowdata; $i++) {      for (my $i = 0; $i<=$#rowdata; $i++) {
         my $cell = $rowdata[$i];          my $cell = $rowdata[$i];
         if ($i < $num_uneditable) {          if ($i < $num_uneditable) {
     $row_html .= '<td bgcolor="#DDCCFF">'.      $row_html .= '<td bgcolor="#FFDDDD">'.
                 &html_editable_cell($cell,'#DDCCFF',$allowed).'</td>';                  &html_uneditable_cell($cell,'#FFDDDD',$allowed).'</td>';
         } else {          } else {
     $row_html .= '<td bgcolor="#EOFFDD">'.      $row_html .= '<td bgcolor="#EOFFDD">'.
                 &html_editable_cell($cell,'#EOFFDD',$allowed).'</td>';                  &html_editable_cell($cell,'#EOFFDD',$allowed).'</td>';
Line 1212  sub html_row { Line 1239  sub html_row {
     return $row_html;      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 {  sub create_excel_spreadsheet {
     my $self = shift;      my $self = shift;
     my ($r) = @_;      my ($r) = @_;
Line 1237  sub create_excel_spreadsheet { Line 1313  sub create_excel_spreadsheet {
     return ($workbook,$filename);      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           ##  ##          XML output routines           ##
 ############################################  ############################################
Line 1333  sub load { Line 1506  sub load {
                 $sheetxml='<field row="0" col="A"></field>';                  $sheetxml='<field row="0" col="A"></field>';
             }              }
             ($formulas,undef) = &parse_sheet(\$sheetxml);              ($formulas,undef) = &parse_sheet(\$sheetxml);
         } elsif($self->filename() =~ /^\/*\.spreadsheet$/) {          } elsif($self->filename() =~ /^\/res\/.*\.spreadsheet$/) {
             # Load a spreadsheet definition file              # Load a spreadsheet definition file
             my $sheetxml=&Apache::lonnet::getfile              my $sheetxml=&Apache::lonnet::getfile
                 (&Apache::lonnet::filelocation('',$filename));                  (&Apache::lonnet::filelocation('',$filename));
Line 1385  sub set_row_sources { Line 1558  sub set_row_sources {
     return;      return;
 }  }
   
   sub set_row_numbers {
       my $self = shift;
       while (my ($cell,$value) = each(%{$self->{'formulas'}})) {
    next if ($cell !~ /^A(\d+)$/);
           next if (! defined($value));
    $self->{'row_numbers'}->{$value} = $1;
           $self->{'maxrow'} = $1 if ($1 > $self->{'maxrow'});
       }
   }
   
 ##  ##
 ## exportrow is *not* used to get the export row from a computed sub-sheet.  ## exportrow is *not* used to get the export row from a computed sub-sheet.
 ##  ##
Line 1409  sub save { Line 1592  sub save {
         my $cnum  = $self->{'cnum'};          my $cnum  = $self->{'cnum'};
         my $cdom  = $self->{'cdom'};          my $cdom  = $self->{'cdom'};
         my $chome = $self->{'chome'};          my $chome = $self->{'chome'};
         my $fn    = $self->{'filename'};          my $filename    = $self->{'filename'};
           my $cachekey = join('_',($cnum,$cdom,$stype,$filename));
         # Cache new sheet          # Cache new sheet
         $spreadsheets{$cnum.'_'.$cdom.'_'.$stype.'_'.$fn}=join('___;___',%f);          %{$spreadsheets{$cachekey}}=%f;
         # Write sheet          # Write sheet
         foreach (keys(%f)) {          foreach (keys(%f)) {
             delete($f{$_}) if ($f{$_} eq 'import');              delete($f{$_}) if ($f{$_} eq 'import');
         }          }
         my $reply = &Apache::lonnet::put($fn,\%f,$cdom,$cnum);          my $reply = &Apache::lonnet::put($filename,\%f,$cdom,$cnum);
         return $reply if ($reply ne 'ok');          return $reply if ($reply ne 'ok');
         $reply = &Apache::lonnet::put($stype.'_spreadsheets',          $reply = &Apache::lonnet::put($stype.'_spreadsheets',
                        {$fn => $ENV{'user.name'}.'@'.$ENV{'user.domain'}},                       {$filename => $ENV{'user.name'}.'@'.$ENV{'user.domain'}},
                                       $cdom,$cnum);                                        $cdom,$cnum);
         return $reply if ($reply ne 'ok');          return $reply if ($reply ne 'ok');
         if ($makedef) {           if ($makedef) { 
             $reply = &Apache::lonnet::put('environment',              $reply = &Apache::lonnet::put('environment',
                                 {'spreadsheet_default_'.$stype => $fn },                                  {'spreadsheet_default_'.$stype => $filename },
                                           $cdom,$cnum);                                            $cdom,$cnum);
             return $reply if ($reply ne 'ok');              return $reply if ($reply ne 'ok');
         }           } 
Line 1440  sub save { Line 1624  sub save {
   
 sub save_tmp {  sub save_tmp {
     my $self = shift;      my $self = shift;
     my $fn=$ENV{'user.name'}.'_'.      my $filename=$ENV{'user.name'}.'_'.
         $ENV{'user.domain'}.'_spreadsheet_'.$self->{'usymb'}.'_'.          $ENV{'user.domain'}.'_spreadsheet_'.$self->{'usymb'}.'_'.
            $self->{'filename'};             $self->{'filename'};
     $fn=~s/\W/\_/g;      $filename=~s/\W/\_/g;
     $fn=$Apache::lonnet::tmpdir.$fn.'.tmp';      $filename=$Apache::lonnet::tmpdir.$filename.'.tmp';
     $self->temporary(1);      $self->temporary(1);
     my $fh;      my $fh;
     if ($fh=Apache::File->new('>'.$fn)) {      if ($fh=Apache::File->new('>'.$filename)) {
         my %f = $self->formulas();          my %f = $self->formulas();
         while( my ($cell,$formula) = each(%f)) {          while( my ($cell,$formula) = each(%f)) {
             next if ($formula eq 'import');              next if ($formula eq 'import');
Line 1489  sub temporary { Line 1673  sub temporary {
     if (@_) {      if (@_) {
         ($self->{'temporary'})= @_;          ($self->{'temporary'})= @_;
     }      }
     $self->logthis('temporary = '.$self->{'temporary'});  
     return $self->{'temporary'};      return $self->{'temporary'};
 }  }
   
Line 1558  sub get_template_row { Line 1741  sub get_template_row {
     return @cols;      return @cols;
 }  }
   
 sub set_row_numbers {  sub need_to_save {
     my $self = shift;      my $self = shift;
     my %f=$self->formulas();      if ($self->{'new_rows'} && ! $self->temporary()) {
     while (my ($cell,$value) = each(%{$self->{'formulas'}})) {          return 1;
  next if ($cell !~ /^A(\d+)$/);  
         next if (! defined($value));  
  $self->{'row_numbers'}->{$value} = $1;  
     }      }
       return 0;
 }  }
   
 sub get_row_number_from_key {  sub get_row_number_from_key {
Line 1577  sub get_row_number_from_key { Line 1758  sub get_row_number_from_key {
         # may not be the key we need to save          # may not be the key we need to save
  $self->{'maxrow'}++;   $self->{'maxrow'}++;
  $self->{'row_numbers'}->{$key} = $self->{'maxrow'};   $self->{'row_numbers'}->{$key} = $self->{'maxrow'};
           $self->{'new_rows'} = 1;
     }      }
     return $self->{'row_numbers'}->{$key};      return $self->{'row_numbers'}->{$key};
 }  }

Removed from v.1.4  
changed lines
  Added in v.1.12


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>