package Lire::Report::ColumnInfo; use strict; use Carp; use POSIX qw/ ceil /; use Lire::DataTypes qw/ check_type check_xml_name /; use Lire::Utils qw/ check_param check_object_param /; =pod =head1 NAME Lire::Report::ColumnInfo - Object that holds column meta-data. =head1 SYNOPSIS my $info = $subreport->column_info_by_idx( 0 ); print "Column's name: ", $info->name(), "\n"; print "Column's index: ", $info->index(), "\n"; print "Column's type: ", $info->type(), "\n"; print "Column's label: ", $info->label(), "\n"; =head1 DESCRIPTION The Lire::Report::ColumnInfo object contains meta-data information on the columns of a subreport. =head1 CONSTRUCTOR =head2 new( $group, $name, $class, $type, [$label]]) Creates a new Lire::Report::ColumnInfo object. The column info attributes are initialized based on $name, $class, $type and $label. =cut sub new { my ( $class, $group, $name, $type_class, $type, $label ) = @_; check_object_param( $group, 'group_info', 'Lire::Report::GroupInfo' ); check_param( $name, 'name', \&check_xml_name, "'name' parameter isn't a valid XML name" ); check_param( $type_class, 'class', qr/^(numerical|categorical)$/, "'class' parameter should either be 'numerical' or 'categorical'" ); check_param( $type, 'type', \&check_type, "'type' parameter isn't a valid Lire type" ); my $self = bless { 'name' => $name, 'class' => $type_class, 'type' => $type, 'col_width' => 0, 'max_chars' => undef, 'avg_chars' => undef, 'padding' => 0, 'index' => undef, 'group_info' => $group, }, $class; $self->label( $label ) if ( defined $label ); return $self; } =pod =head1 OBJECT METHODS =pod =head2 name() Returns the name of this column. This name can be used to find the group operation (from the report specification) that is responsible for the column's content. =cut sub name { return $_[0]{'name'}; } =pod =head2 class() Returns the column's class of data. This will be either 'numerical' or 'categorical'. =cut sub class { return $_[0]{'class'}; } =pod =head2 type() Returns the column's type. This referes to the type of the DLF field that was usd to generate this column's values. =cut sub type { return $_[0]{'type'}; } =pod =head2 group_info() Returns the GroupInfo object which contains this column. =cut sub group_info { return $_[0]{'group_info'}; } =pod =head2 index() Returns the column's index in the table. This will be undef until the column info object is added to a Lire::Subreport or Lire::Group object. =cut sub index { $_[0]{'index'} = $_[1] if @_ == 2; return $_[0]{'index'}; } =pod =head2 col_start() Returns the display column which is the start of the cell span that should be used to render this column's values. =cut sub col_start { $_[0]{'col_start'} = $_[1] if @_ == 2; return $_[0]{'col_start'}; } =pod =head2 col_end() Returns the display column which is the end of the cell span that should be used to render this column's values. =cut sub col_end { $_[0]{'col_end'} = $_[1] if @_ == 2; return $_[0]{'col_end'}; } =pod =head2 col_width() Returns the suggested column width for this column in characters. =cut sub col_width { $_[0]{'col_width'} = $_[1] if @_ == 2; return $_[0]{'col_width'}; } =pod =head2 max_chars() This method returns the length of the longest string in that column (including the label). =cut sub max_chars { my $self = $_[0]; $self->{'max_chars'} = $_[1] if @_ == 2; croak "max_chars() called while stat is undefined. Was subreport's finalize() called?" unless defined $self->{'max_chars'}; return $self->{'max_chars'}; } =pod =head2 avg_chars() This method returns the average length of strings in that column (including the label). This will be round up to the next integer (1.3 -> 2). =cut sub avg_chars { my $self = $_[0]; $self->{'avg_chars'} = $_[1] if @_ == 2; croak "avg_chars() called while stat is undefined. Was subreport's finalize() called?" unless defined $self->{'avg_chars'}; return $self->{'avg_chars'}; } sub init_chars_stats { my ( $self ) = @_; $self->{'total_chars'} = 0; $self->{'column_count'} = 0; $self->{'max_chars'} = length( $self->label() ); return; } sub update_chars_stats { my ( $self, $value ) = @_; my $len = length $value; $self->{'total_chars'} += $len; $self->{'column_count'}++; $self->{'max_chars'} = $len if $len > $self->{'max_chars'}; return; } sub finish_chars_stats { my $self = $_[0]; my $len = length $self->label(); $self->{'avg_chars'} = ceil( ($self->{'total_chars'} + $len) / ($self->{'column_count'} + 1) ); delete $self->{'total_chars'}; delete $self->{'column_count'}; return; } =pod =head2 label( [$label] ) Returns the column's label. If the $label parameter is defined, the column's label will be set to this new value. =cut sub label { my ( $self, $label ) = @_; $self->{'label'} = $label if ( @_ == 2 ); return ( $self->{'label'} ? $self->{'label'} : $self->{'name'} ); } sub write_report { my ( $self, $fh, $indent ) = @_; $fh ||= *STDOUT; my $pfx = ' ' x $indent; print $fh $pfx, qq{{'label'}; print $fh qq{ max-chars="$self->{'max_chars'}" avg-chars="}, $self->avg_chars, qq{"/>\n}; return; } #------------------------------------------------------------------------ # Method delete() # # Remove circular references sub delete { my ( $self ) = @_; %$self = (); return; } # keep perl happy 1; __END__ =pod =head1 SEE ALSO Lire::Report::Subreport(3pm) Lire::Report::GroupInfo(3pm) =head1 VERSION $Id: ColumnInfo.pm,v 1.15 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