package Lire::Report::TableInfo; use strict; use base qw/ Lire::Report::GroupInfo /; use Lire::Config::Index; use Lire::Config::VariableIndex; use Carp; =pod =head1 NAME Lire::Report::TableInfo - Object that holds all the GroupInfo and ColumnInfo for one subreport =head1 SYNOPSIS my $info = $subreport->table_info; my $col_info = $info->colum_info( "request_total" ); =head1 DESCRIPTION The Lire::Report::TableInfo object holds the ColumnInfo and GroupInfo objects for one subreport.. =head1 CONSTRUCTOR =head2 new() Creates a new Lire::Report::TableInfo object. =cut sub new { my $self = bless( {'name' => "table", 'children' => [], 'row_idx' => 0, 'parent' => undef}, $_[0] ); $self->index( 0 ); return $self; } =pod =head2 column_info_by_name( $name ) Returns the Lire::Report::ColumnInfo object that has the name $name. Contrary to the method in Lire::Report::GroupInfo, this one will throw an exception if there is no column named $name. =cut sub column_info_by_name { my ( $self, $name ) = @_; my $col = $self->SUPER::column_info_by_name( $name ); croak "There is no column named $name" unless $col; return $col; } =pod =head2 column_info_by_col_start( $idx ) Returns the Lire::Report::ColumnInfo object that is starts at column index $idx. Contrary to the method in Lire::Report::GroupInfo, this one will throw an exception if this column is out of bounds. =cut sub column_info_by_col_start { my ( $self, $idx ) = @_; my $col = $self->SUPER::column_info_by_col_start( $idx ); croak "There is no column index $idx" unless $col; return $col; } =pod =head2 group_info( $name ) Returns the Lire::Report::GroupInfo object that has the name $name. Contrary to the method in Lire::Report::GroupInfo, this one will throw an exception if there is no column named $name. =cut sub group_info { my ( $self, $name ) = @_; # Cache the result of the base lookup unless ( exists $self->{'group_info'}{$name} ) { $self->{'group_info'}{$name} = $self->SUPER::group_info( $name ); } croak "There is no group named $name" unless $self->{'group_info'}{$name}; return $self->{'group_info'}{$name}; } =pod =head2 ncols() Returns the number of columns there is in this table. =cut sub ncols { my $self = $_[0]; my @cols = $self->column_infos(); return scalar @cols; } =pod =head2 column_infos() Returns an array containing all the columns of the table. Each element is a Lire::Report::ColumnInfo object. =cut sub column_infos { my $self = $_[0]; my @cols = $self->column_children(); my @groups = $self->group_children(); while ( @groups ) { my $g = shift @groups; push @cols, $g->column_children(); push @groups, $g->group_children(); } return sort { $a->col_start() <=> $b->col_start() } @cols; } =pod =head2 groups() Returns an array containing all the groups of the table. Each element is a Lire::Report::GroupInfo object. =cut sub groups { my $self = $_[0]; my @groups = ( $self ); my @children = ( $self ); while ( @children ) { my $g = shift @children; push @groups, $g->group_children(); push @children, $g->group_children(); } return @groups; } =pod =head2 columns_width() Returns an array where each element represents the suggested columns' width in characters. =cut sub columns_width { return map { $_->col_width() } $_[0]->columns(); } =pod =head2 header_rows() Returns an array reference containing one array reference for each rows in the header. Each row contains the ColumnInfo that should appear on the header line. The first row contains all the numerical columns and the categorical columns appear based on their nesting. The indices of the column is always equals to its column's start. =cut sub header_rows { my $self = $_[0]; my $rows = []; my @groups = $self->groups(); my @group_row; my $ncols = $self->ncols(); while ( @group_row = grep { $_->row_idx() == ( $#$rows + 1 ) } @groups ) { # Grab the ColumInfo in that row my @cols = (); foreach my $g ( @group_row ) { push @cols, grep { $_->class() eq 'categorical' } $g->column_children(); # Special case for the first row, all value columns go there push @cols, grep { $_->class eq 'numerical' } $self->column_infos() unless @$rows; } my $row = [ (undef) x $ncols ]; foreach my $col ( @cols ) { $row->[ $col->col_start() ] = $col; } push @$rows, $row; } return $rows; } =pod =head2 set_variables_indices() Registers this TableInfo's variables using Lire::Config::VariableIndex. =cut sub set_variables_indices { my $self = $_[0]; Lire::Config::Index->set_index( 'variables', new Lire::Config::VariableIndex( $self, 'both' ) ); Lire::Config::Index->set_index( 'categorical_variables', new Lire::Config::VariableIndex( $self, 'categorical' ) ); Lire::Config::Index->set_index( 'numerical_variables', new Lire::Config::VariableIndex( $self, 'numerical' ) ); return; } =pod =head2 reset_variable_indices() Removes the variables indices. This can be called to undo the effect of set_variables_indices(). =cut sub reset_variables_indices { my $self = $_[0]; Lire::Config::Index->set_index( 'variables', undef ); Lire::Config::Index->set_index( 'categorical_variables', undef ); Lire::Config::Index->set_index( 'numerical_variables', undef ); return; } # ------------------------------------------------------------------------ # Method compute_columns_width() # # Try to determine the width of all the columns sub compute_columns_width { my $self = $_[0]; $self->assign_columns_width; $self->correct_spanning_column_width( $self ); return; } #----------------------------------------------------------------------- # Methods write_report( $fh, $index ) sub write_report { my ( $self, $fh, $indent ) = @_; $fh ||= *STDOUT; my $pfx = ' ' x $indent; print $fh $pfx, qq{\n}; foreach my $i ( @{$self->{'children'}} ) { $i->write_report( $fh, $indent + 1 ); } print $fh $pfx, "\n"; return; } # keep perl happy 1; __END__ =pod =head1 SEE ALSO Lire::Report::Subreport(3pm) Lire::Report::ColumnInfo(3pm) =head1 VERSION $Id: TableInfo.pm,v 1.26 2006/07/23 13:16:31 vanbaal Exp $ =head1 COPYRIGHT Copyright (C) 2002 Stichting LogReport Foundation LogReport@LogReport.org This file is part of Lire. Lire is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program (see COPYING); if not, check with http://www.gnu.org/copyleft/gpl.html. =head1 AUTHOR Francis J. Lacoste =cut