|| die "Table $1 not defined completely";
chomp;
/,/ || die "Table $data[0] not defined completely";
s/, /,/g;
push @data, [ split(/,/, $_) ];
# gather for keywords
} elsif ( $info ) {
push @data, $_; # ( $text, $text, ... )
# if ( /\.\s*$/ ) {
# push @data, $_; # ( $text, $text, ... )
# } elsif ( /,/ ) {
# push @data, [ split(/,/, $_) ]; # ( $text, [ $item, ...] )
# } else {
# push @data, $_; # ( $text, $text, ... )
# }
} elsif ( $table ) {
chomp;
/,/ || die "Table $data[0] not defined completely";
s/, /,/g;
push @data, [ split(/,/, $_) ]; # $( $text, [ $item, ...] )
} elsif ( $topic ) {
# ignore extra topic lines for now
}
}
# End of File may catch the last info or table
push @{$info{$it}}, [ @data ] if $info || $table;
# save topics and info data
$self->{topic} = \@topics;
$self->{data} = \%info;
}
=item $info->delete($product_name)
Remove a handout list completely.
=cut
sub delete {
my $self = shift;
my $info = $self->name;
my $dir = $self->dir;
# Delete the current info file
unlink "$dir/$info";
# Clean up current object
$self->{data} = undef;
}
=item $self->{data} = $info->restore();
Restore a information.
=cut
sub restore {
my $self = shift;
}
# $self->add_name()
# add a name to the products file, create it if it doesn't exist
sub add_name {
my $self = shift;
my $name = $self->name;
# Verify handout info name is within the "handouts" file
my $info_file = get_info_file();
my @handouts = ();
if ( -e $info_file ) {
@handouts = File::Slurp::read_file($info_file);
}
# Add name if it isn't already in the products file
if ( $name && ! grep ( /^$name$/, @handouts ) ) {
push @handouts, "$name\n";
File::Slurp::write_file($info_file, @handouts);
}
}
=back 4
=head1 Object methods
Info objects return information needed for display.
=over 4
=item topics
Return a list of topic fields.
=cut
sub topics {
my $self = shift;
die "invalid method call" unless ref($self);
my @topics;
foreach my $count ( 1 .. scalar @{$self->{topic}} ) {
push @topics, "topic_" . $count;
}
return @topics;
}
=item $options_ref = $info->topic_options;
Return a list of options for checkbox selection
of topics.
=cut
sub topic_options {
my $self = shift;
die "invalid method call" unless ref($self);
my $item;
my %topics = ();
foreach my $count ( 1 .. scalar @{$self->{topic}} ) {
$item = "topic_" . $count;
$topics{$item} = [ $self->{topic}->[$count-1] ];
}
return \%topics;
}
=item @fields = $info->info( @topics );
Return a list of topic and info fields.
=cut
sub info {
my ($self, @topics) = @_;
die "invalid method call" unless ref($self);
my @fields = ();
my $item;
my $data;
foreach my $topic ( @topics ) {
push @fields, "topic_" . $topic;
$data = $self->data->{$topic-1};
foreach my $count ( 1 .. scalar @$data ) {
$item = $data->[$count-1];
if ( $item->[0] =~ /^rows (.*)$/ ) {
push @fields, "table_" . $topic . "_" . $count;
} elsif ( $item->[0] =~ /^columns (.*)$/ ) {
push @fields, "table_" . $topic . "_" . $count;
} else {
push @fields, "info_" . $topic . "_" . $count;
}
}
}
return @fields;
}
=item $info->info_options( @topics );
Return the options of info for display.
All topics will be static picks.
All tables, and info items return only the
first banner. Call info_fields to get the
display of other lines.
=cut
sub info_options {
my ($self, @topics) = @_;
die "invalid method call" unless ref($self);
my %fields = ();
my $field = "";
my $index;
my $data;
foreach my $topic ( @topics ) {
$field = "topic_" . $topic;
$fields{$field} = [ $self->{topic}->[$topic-1] ];
$data = $self->data->{$topic-1};
foreach my $count ( 1 .. scalar @$data ) {
$index = $count - 1;
if ( $data->[$index]->[0] =~ /^rows (.*)$/ ) {
$field = "table_" . $topic . "_" . $count;
$fields{$field} = [ $1 ];
} elsif ( $data->[$index]->[0] =~ /^columns (.*)$/ ) {
$field = "table_" . $topic . "_" . $count;
$fields{$field} = [ $1 ];
} else {
$field = "info_" . $topic . "_" . $count;
$fields{$field} = [ $data->[$index]->[0] ];
}
# }
}
}
return \%fields;
}
=item $info->info_data( @topics );
Return the data of info for testing.
=cut
sub info_data {
my ($self, @topics) = @_;
die "invalid method call" unless ref($self);
my %fields = ();
my $field = "";
my $index;
my $data;
foreach my $topic ( @topics ) {
$field = "topic_" . $topic;
$fields{$field} = [ $self->{topic}->[$topic-1] ];
$data = $self->data->{$topic-1};
foreach my $count ( 1 .. scalar @$data ) {
$index = $count - 1;
if ( $data->[$index]->[0] =~ /^rows (.*)$/ ) {
$field = "table_" . $topic . "_" . $count;
$fields{$field} = $data->[$index];
$fields{$field}->[0] = $1;
} elsif ( $data->[$index]->[0] =~ /^columns (.*)$/ ) {
$field = "table_" . $topic . "_" . $count;
$fields{$field} = $data->[$index];
$fields{$field}->[0] = $1;
} else {
$field = "info_" . $topic . "_" . $count;
$fields{$field} = $data->[$index];
}
}
}
return \%fields;
}
=item $info->info_fields( $form, @topics );
Return the field info for for info selection.
=cut
sub info_fields {
my ($self, $form, @topics) = @_;
die "invalid method call" unless ref($self);
# predeclared for efficiency
my ($field, $index, $data, $comment, $item, $list, $max);
# Set each topic to static
foreach my $topic ( @topics ) {
$field = "topic_" . $topic;
$form->field( -name => $field, -type => 'static' );
$data = $self->data->{$topic-1};
# Add data to each selection as a comment
foreach my $count ( 1 .. scalar @$data ) {
$index = $count - 1;
if ( $data->[$index]->[0] =~ /^rows (.*)$/ ) {
$field = "table_" . $topic . "_" . $count;
$list = get_row_list( $data->[$index] );
$comment = "" . table({-border => undef},
caption($1),
Tr({-align => 'CENTER', -valign => 'TOP'},
$list) );
$form->field( -name => $field, -comment => $comment );
} elsif ( $data->[$index]->[0] =~ /^columns (.*)$/ ) {
$field = "table_" . $topic . "_" . $count;
$list = get_col_list( $data->[$index] );
$comment = "
" . table({-border => undef},
caption($1),
Tr({-align => 'CENTER', -valign => 'TOP'},
$list) );
$form->field( -name => $field, -comment => $comment );
} else {
$field = "info_" . $topic . "_" . $count;
$comment = "
";
foreach $item ( 1 .. $#{$data->[$index]} ) {
$comment .= "- " . $data->[$index]->[$item] . "
";
}
$comment .= "
";
$form->field( -name => $field, -comment => $comment );
}
}
}
}
=item @fields = $info->fields( $form, \%label, @topics );
Return a list of topic and handout fields.
This will return only those info fields that
have been picked.
Returns labels for simple numbering of info items.
=cut
sub fields {
my ($self, $form, $labels, @topics) = @_;
die "invalid method call" unless ref($self);
my @fields = ();
my ($data, $item, $id, $info_count, $label);
my $topic_count = 1;
foreach my $topic ( @topics ) {
push @fields, $TOPIC[$topic_count];
$data = $self->data->{$topic-1};
$info_count = 1;
foreach my $count ( 1 .. scalar @$data ) {
$item = $data->[$count-1];
if ( $item->[0] =~ /^rows (.*)$/ ) {
$id = "table_" . $topic . "_" . $count;
} elsif ( $item->[0] =~ /^columns (.*)$/ ) {
$id = "table_" . $topic . "_" . $count;
} else {
$id = "info_" . $topic . "_" . $count;
}
if ( $form->field($id) ) {
$label = $TOPIC[$topic_count] . "_" . $info_count;
push @fields, $label;
$labels->{$label} = $info_count;
++ $info_count;
}
}
++ $topic_count;
}
return @fields;
}
=item $info->show_fields( $picks, $form, @topics );
Return the field info for a handout, in this
case all fields should be set to static. This
is based on form "picks" from "select_info".
=cut
sub show_fields {
my ($self, $picks, $form, @topics) = @_;
die "invalid method call" unless ref($self);
# predeclared for efficiency
my ($field, $index, $data, $comment, $item, $list, $max);
my ($info_count, $id);
my $topic_count = 1;
# Set each topic to static
foreach my $topic ( @topics ) {
$id = "topic_" . $topic;
$field = $TOPIC[$topic_count];
$form->field( -name => $field, -type => 'static' );
$data = $self->data->{$topic-1};
$info_count = 1;
# Add data to each selection as a comment, set to static
foreach my $count ( 1 .. scalar @$data ) {
$index = $count - 1;
$field = $TOPIC[$topic_count] . "_" . $info_count;
if ( $data->[$index]->[0] =~ /^rows (.*)$/ ) {
$id = "table_" . $topic . "_" . $count;
$list = get_row_list( $data->[$index] );
$comment = "" . table({-border => undef},
caption($1),
Tr({-align => 'CENTER', -valign => 'TOP'},
$list) );
} elsif ( $data->[$index]->[0] =~ /^columns (.*)$/ ) {
$id = "table_" . $topic . "_" . $count;
$list = get_col_list( $data->[$index] );
$comment = "
" . table({-border => undef},
caption($1),
Tr({-align => 'CENTER', -valign => 'TOP'},
$list) );
} else {
$id = "info_" . $topic . "_" . $count;
$comment = "
";
foreach $item ( 1 .. $#{$data->[$index]} ) {
$comment .= "- " . $data->[$index]->[$item] . "
";
}
$comment .= "
";
}
if ( $picks->field($id) ) {
$form->field( -name => $field, -comment => $comment,
-type => 'static' );
++ $info_count;
}
}
++ $topic_count;
}
}
=item $info->show_options( $form, @topics );
Return the options of info for display.
All topic and info items will be static displays
for printing.
All tables, and info items return only the
first banner. Call show_fields to get the
display of other lines.
=cut
sub show_options {
my ($self, $form, @topics) = @_;
die "invalid method call" unless ref($self);
my %fields = ();
my $field = "";
my ($index, $data, $id, $info_count);
my $topic_count = 1;
foreach my $topic ( @topics ) {
$id = "topic_" . $topic;
$field = $TOPIC[$topic_count];
$fields{$field} = [ $self->{topic}->[$topic-1] ];
$data = $self->data->{$topic-1};
$info_count = 1;
foreach my $count ( 1 .. scalar @$data ) {
$index = $count - 1;
$field = $TOPIC[$topic_count] . "_" . $info_count;
if ( $data->[$index]->[0] =~ /^rows (.*)$/ ) {
$id = "table_" . $topic . "_" . $count;
$fields{$field} = [ $1 ] if $form->field($id);
} elsif ( $data->[$index]->[0] =~ /^columns (.*)$/ ) {
$id = "table_" . $topic . "_" . $count;
$fields{$field} = [ $1 ] if $form->field($id);
} else {
$id = "info_" . $topic . "_" . $count;
$fields{$field} = [ $data->[$index]->[0] ]
if $form->field($id);
}
++ $info_count if $form->field($id);
}
++ $topic_count;
}
return \%fields;
}
# $list = get_row_list( $data->[$index] );
# returns a list of rows in row order for display
sub get_row_list {
my ($list) = @_;
my @row_list = ();
my @header = @{$list->[1]};
my $max_header = scalar @header;
my ($count, $item);
# create rows with header items
foreach my $index ( 0 .. $max_header-1 ) {
push @row_list, [ "" . $header[$index] . "" ];
}
# find maximum list item
my $max = scalar @{$list->[2]};
foreach $item ( 3 .. scalar @$list - 1 ) {
$count = scalar @{$list->[$item]};
$max = $count if $count > $max;
}
# populate rows
$count = 0;
foreach $item ( 2 .. scalar @$list - 1 ) {
push @{$row_list[$count]}, @{$list->[$item]};
++ $count;
}
# create table rows
my $the_list = [];
foreach $item ( 0 .. $#row_list ) {
push @$the_list, td($row_list[$item]);
}
return $the_list;
}
# $list = get_col_list( $data->[$index] );
# returns a list of cols in col order for display
# th(['Vegetable', 'Breakfast','Lunch','Dinner']),
# td(['Tomatoes' , 'no', 'yes', 'yes']),
# td(['Broccoli' , 'no', 'no', 'yes']),
# td(['Onions' , 'yes','yes', 'yes'])
sub get_col_list {
my ($list) = @_;
my @col_list = ();
my @header = @{$list->[1]};
my $max_header = scalar @header;
my ($count, $item);
# find maximum list item
my $max = scalar @{$list->[2]};
foreach $item ( 3 .. scalar @$list - 1 ) {
$count = scalar @{$list->[$item]};
$max = $count if $count > $max;
}
# create cols
foreach my $index ( 0 .. $max_header-1 ) {
push @col_list, [ ];
}
# populate cols
$count = 0;
foreach $item ( 2 .. scalar @$list - 1 ) {
foreach $count ( 0 .. $max - 1 ) {
if ( $count < scalar @{$list->[$item]} ) {
push @{$col_list[$count]}, $list->[$item]->[$count];
} else {
push @{$col_list[$count]}, "";
}
}
}
# create table cols
my $the_list = [];
push @$the_list, th($list->[1]);
foreach $item ( 0 .. $#col_list ) {
push @$the_list, td($col_list[$item]);
}
return $the_list;
}
=item $output = $info->show( $form, $topics );
Return the handout screen of info for display.
Pass in the topic array and the current screen
response.
Information is numbered and indented at that
number level. Tables are just indented. So
the handout is in outline format.
=cut
sub show {
my ($self, $form, $topics) = @_;
die "invalid method call" unless ref($self);
my %fields = ();
my $field = "";
my $item;
my $data;
foreach my $topic ( @$topics ) {
$field = "topic_" . $topic;
$fields{$field} = [ $self->{topic}->[$topic-1] ];
$data = $self->data->{$topic-1};
foreach my $count ( 1 .. scalar @$data ) {
$item = $data->[$count-1];
if ( $item->[0] =~ /^rows (.*)$/ ) {
$field = "table_" . $topic . "_" . $count;
$fields{$field} = [ $1 ];
} elsif ( $item->[0] =~ /^columns (.*)$/ ) {
$field = "table_" . $topic . "_" . $count;
$fields{$field} = [ $1 ];
} else {
$field = "info_" . $topic . "_" . $count;
$fields{$field} = [ $item->[0] ];
}
}
}
return \%fields;
}
=item AUTOLOAD
Return or set any product info by default.
Put a new value for query of this product:
$product->query($query);
Return the query value for this product:
$product->query);
=cut
sub AUTOLOAD {
my $self = shift;
my $type = ref($self) or croak "$self is not an object";
my $name = $AUTOLOAD;
$name =~ s/.*://; # strip fully-qualified portion
croak "Can't access `$name' field in class $type"
unless (exists $self->{$name});
if (@_) {
return $self->{$name} = shift;
} else {
return $self->{$name};
}
}
# explicit destroy required because of AUTOLOAD
sub DESTROY {
}
1; # all packages must return 1 for sucessful loading
__END__