package Excel::Template::Format;
use strict;
# This is the format repository. Spreadsheet::WriteExcel does not cache the
# known formats. So, it is very possible to continually add the same format
# over and over until you run out of RAM or addressability in the XLS file. In
# real life, less than 10-20 formats are used, and they're re-used in various
# places in the file. This provides a way of keeping track of already-allocated
# formats and making new formats based on old ones.
sub new { bless {}, shift }
sub _assign { $_[0]{$_[1]} = $_[2]; $_[0]{$_[2]} = $_[1] }
# my $self = shift;
# my ($key, $format) = @_;
# $self->{$key} = $format;
# $self->{$format} = $key;
#}
sub _retrieve_key { $_[0]{ $_[1] } }
# my $self = shift;
# my ($format) = @_;
# return $self->{$format};
#}
*_retrieve_format = \&_retrieve_key;
#sub _retrieve_format {
# my $self = shift;
# my ($key) = @_;
# return $self->{$key};
#}
{
my @_boolean_formats = qw(
bold italic locked hidden font_outline font_shadow font_strikeout
text_wrap text_justlast shrink is_merged
);
my @_integer_formats = qw(
size underline rotation indent pattern border
bottom top left right
);
my @_string_formats = qw(
num_format font color align valign bg_color fg_color border_color
bottom_color top_color left_color right_color
);
my @_fake_slots = qw(
is_merged
);
sub _params_to_key
{
my %params = @_;
$params{lc $_} = delete $params{$_} for keys %params;
my @parts = (
(map { $params{$_} ? 1 : '' } @_boolean_formats),
(map { $params{$_} ? $params{$_} + 0 : '' } @_integer_formats),
(map { $params{$_} || '' } @_string_formats),
);
return join( "\n", @parts );
}
sub _key_to_params
{
my ($key) = @_;
my @key_parts = split /\n/, $key;
my @boolean_parts = splice @key_parts, 0, scalar( @_boolean_formats );
my @integer_parts = splice @key_parts, 0, scalar( @_integer_formats );
my @string_parts = splice @key_parts, 0, scalar( @_string_formats );
my %params;
$params{ $_boolean_formats[$_] } = ~~1
for grep { $boolean_parts[$_] } 0 .. $#_boolean_formats;
$params{ $_integer_formats[$_] } = $integer_parts[$_]
for grep { defined $integer_parts[$_] && length $integer_parts[$_] } 0 .. $#_integer_formats;
$params{ $_string_formats[$_] } = $string_parts[$_]
for grep { $string_parts[$_] } 0 .. $#_string_formats;
return %params;
}
sub copy
{
my $self = shift;
my ($context, $old_fmt, %properties) = @_;
# This is a key used for non-format book-keeping.
delete $properties{ ELEMENTS };
defined(my $key = _retrieve_key($self, $old_fmt))
|| die "Internal Error: Cannot find key for format '$old_fmt'!\n";
my %params = _key_to_params($key);
PROPERTY:
while ( my ($prop, $value) = each %properties )
{
$prop = lc $prop;
foreach (@_boolean_formats)
{
if ($prop eq $_) {
$params{$_} = ($value && $value !~ /false/i);
next PROPERTY;
}
}
foreach (@_integer_formats, @_string_formats)
{
if ($prop eq $_) {
$params{$_} = $value;
next PROPERTY;
}
}
warn "Property '$prop' is unrecognized\n" if $^W;
}
my $new_key = _params_to_key(%params);
my $format = _retrieve_format($self, $new_key);
return $format if $format;
delete $params{$_} for @_fake_slots;
$format = $context->{XLS}->add_format(%params);
_assign($self, $new_key, $format);
return $format;
}
}
sub blank_format
{
my $self = shift;
my ($context) = @_;
my $blank_key = _params_to_key();
my $format = _retrieve_format($self, $blank_key);
return $format if $format;
$format = $context->{XLS}->add_format;
_assign($self, $blank_key, $format);
return $format;
}
1;
__END__
=head1 NAME
Excel::Template::Format - Excel::Template::Format
=head1 PURPOSE
Helper class for FORMAT
=head1 NODE NAME
None
=head1 INHERITANCE
None
=head1 ATTRIBUTES
None
=head1 CHILDREN
None
=head1 EFFECTS
None
=head1 DEPENDENCIES
None
=head1 METHODS
=head2 blank_format
Provides a blank format for use
=head2 copy
Clones an existing format, so that a new format can be built from it
=head1 AUTHOR
Rob Kinyon (rob.kinyon@gmail.com)
=head1 SEE ALSO
FORMAT
=cut