Add formatting tweak to ensure merged formats distinct. #68308
[p5sagit/Excel-Template.git] / lib / Excel / Template / Format.pm
CommitLineData
d0eafc11 1package Excel::Template::Format;
2
3use strict;
4
5# This is the format repository. Spreadsheet::WriteExcel does not cache the
6# known formats. So, it is very possible to continually add the same format
7# over and over until you run out of RAM or addressability in the XLS file. In
8# real life, less than 10-20 formats are used, and they're re-used in various
9# places in the file. This provides a way of keeping track of already-allocated
10# formats and making new formats based on old ones.
11
9ee3aea0 12sub new { bless {}, shift }
13
14sub _assign { $_[0]{$_[1]} = $_[2]; $_[0]{$_[2]} = $_[1] }
15# my $self = shift;
16# my ($key, $format) = @_;
17# $self->{$key} = $format;
18# $self->{$format} = $key;
19#}
20
21sub _retrieve_key { $_[0]{ $_[1] } }
22# my $self = shift;
23# my ($format) = @_;
24# return $self->{$format};
25#}
26
27*_retrieve_format = \&_retrieve_key;
28#sub _retrieve_format {
29# my $self = shift;
30# my ($key) = @_;
31# return $self->{$key};
32#}
c09684ff 33
34{
35 my @_boolean_formats = qw(
36 bold italic locked hidden font_outline font_shadow font_strikeout
ddb9abcf 37 text_wrap text_justlast shrink is_merged
d0eafc11 38 );
c09684ff 39
40 my @_integer_formats = qw(
1e753f77 41 size underline rotation indent pattern border
c09684ff 42 bottom top left right
43 );
44
45 my @_string_formats = qw(
1e753f77 46 num_format font color align valign bg_color fg_color border_color
c09684ff 47 bottom_color top_color left_color right_color
48 );
49
ddb9abcf 50 my @_fake_slots = qw(
51 is_merged
52 );
53
c09684ff 54 sub _params_to_key
d0eafc11 55 {
56 my %params = @_;
57 $params{lc $_} = delete $params{$_} for keys %params;
c09684ff 58
cbac675a 59 # force fake slots to be zero if not set
60 $params{$_} ||= 0 for @_fake_slots;
61
c09684ff 62 my @parts = (
d5382a2d 63 (map { $params{$_} ? 1 : '' } @_boolean_formats),
c09684ff 64 (map { $params{$_} ? $params{$_} + 0 : '' } @_integer_formats),
65 (map { $params{$_} || '' } @_string_formats),
66 );
67
68 return join( "\n", @parts );
d0eafc11 69 }
c09684ff 70
71 sub _key_to_params
d0eafc11 72 {
c09684ff 73 my ($key) = @_;
74
75 my @key_parts = split /\n/, $key;
76
77 my @boolean_parts = splice @key_parts, 0, scalar( @_boolean_formats );
78 my @integer_parts = splice @key_parts, 0, scalar( @_integer_formats );
79 my @string_parts = splice @key_parts, 0, scalar( @_string_formats );
80
d0eafc11 81 my %params;
d5382a2d 82 $params{ $_boolean_formats[$_] } = ~~1
c09684ff 83 for grep { $boolean_parts[$_] } 0 .. $#_boolean_formats;
d0eafc11 84
c09684ff 85 $params{ $_integer_formats[$_] } = $integer_parts[$_]
d5382a2d 86 for grep { defined $integer_parts[$_] && length $integer_parts[$_] } 0 .. $#_integer_formats;
c09684ff 87
88 $params{ $_string_formats[$_] } = $string_parts[$_]
89 for grep { $string_parts[$_] } 0 .. $#_string_formats;
d0eafc11 90
c09684ff 91 return %params;
d0eafc11 92 }
93
c09684ff 94 sub copy
95 {
9ee3aea0 96 my $self = shift;
c09684ff 97 my ($context, $old_fmt, %properties) = @_;
d0eafc11 98
b6bc5a5d 99 # This is a key used for non-format book-keeping.
100 delete $properties{ ELEMENTS };
101
9ee3aea0 102 defined(my $key = _retrieve_key($self, $old_fmt))
c09684ff 103 || die "Internal Error: Cannot find key for format '$old_fmt'!\n";
104
105 my %params = _key_to_params($key);
106 PROPERTY:
107 while ( my ($prop, $value) = each %properties )
108 {
109 $prop = lc $prop;
110 foreach (@_boolean_formats)
111 {
112 if ($prop eq $_) {
113 $params{$_} = ($value && $value !~ /false/i);
114 next PROPERTY;
115 }
116 }
117 foreach (@_integer_formats, @_string_formats)
118 {
119 if ($prop eq $_) {
120 $params{$_} = $value;
121 next PROPERTY;
122 }
123 }
b6bc5a5d 124
dee1f239 125 warn "Property '$prop' is unrecognized\n" if $^W;
c09684ff 126 }
d0eafc11 127
c09684ff 128 my $new_key = _params_to_key(%params);
d0eafc11 129
9ee3aea0 130 my $format = _retrieve_format($self, $new_key);
c09684ff 131 return $format if $format;
d0eafc11 132
ddb9abcf 133 delete $params{$_} for @_fake_slots;
134
c09684ff 135 $format = $context->{XLS}->add_format(%params);
9ee3aea0 136 _assign($self, $new_key, $format);
c09684ff 137 return $format;
138 }
d0eafc11 139}
140
c09684ff 141sub blank_format
d0eafc11 142{
9ee3aea0 143 my $self = shift;
c09684ff 144 my ($context) = @_;
d0eafc11 145
c09684ff 146 my $blank_key = _params_to_key();
d0eafc11 147
9ee3aea0 148 my $format = _retrieve_format($self, $blank_key);
d0eafc11 149 return $format if $format;
150
c09684ff 151 $format = $context->{XLS}->add_format;
9ee3aea0 152 _assign($self, $blank_key, $format);
c09684ff 153 return $format;
d0eafc11 154}
155
1561;
157__END__
6dd4c89d 158
159=head1 NAME
160
161Excel::Template::Format - Excel::Template::Format
162
163=head1 PURPOSE
164
165Helper class for FORMAT
166
167=head1 NODE NAME
168
169None
170
171=head1 INHERITANCE
172
173None
174
175=head1 ATTRIBUTES
176
177None
178
179=head1 CHILDREN
180
181None
182
183=head1 EFFECTS
184
185None
186
187=head1 DEPENDENCIES
188
189None
190
191=head1 METHODS
192
193=head2 blank_format
194
195Provides a blank format for use
196
197=head2 copy
198
199Clones an existing format, so that a new format can be built from it
200
201=head1 AUTHOR
202
203Rob Kinyon (rob.kinyon@gmail.com)
204
205=head1 SEE ALSO
206
207FORMAT
208
209=cut