r13918@rob-kinyons-powerbook58: rob | 2006-06-02 10:04:04 -0400
[p5sagit/Excel-Template.git] / lib / Excel / Template / Format.pm
index dcd2a1f..778c49d 100644 (file)
@@ -9,133 +9,192 @@ use strict;
 # 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};
+#}
+
 {
-    # %_Parameters is a hash with the key being the format name and the value
-    # being the index/length of the format in the bit-vector.
-    my %_Formats = ( 
-        bold   => [ 0, 1 ],
-        italic => [ 1, 1 ],
-        locked => [ 2, 1 ],
-        hidden => [ 3, 1 ],
-        font_outline   => [ 4, 1 ],
-        font_shadow    => [ 5, 1 ],
-        font_strikeout => [ 6, 1 ],
+    my @_boolean_formats = qw(
+        bold italic locked hidden font_outline font_shadow font_strikeout
+        text_wrap text_justlast shrink
+    );
+
+    my @_integer_formats = qw(
+        size num_format underline rotation indent pattern border
+        bottom top left right
     );
-    sub _params_to_vec
+
+    my @_string_formats = qw(
+        font color align valign bg_color fg_color border_color
+        bottom_color top_color left_color right_color
+    );
+
+    sub _params_to_key
     {
         my %params = @_;
         $params{lc $_} = delete $params{$_} for keys %params;
-        my $vec = '';
-        vec( $vec, $_Formats{$_}[0], $_Formats{$_}[1] ) = ($params{$_} && 1)  
-            for grep { exists $_Formats{$_} } 
-                map { lc } keys %params;
-        $vec;
+
+        my @parts = (
+            (map { $params{$_} ? 1 : '' } @_boolean_formats),
+            (map { $params{$_} ? $params{$_} + 0 : '' } @_integer_formats),
+            (map { $params{$_} || '' } @_string_formats),
+        );
+
+        return join( "\n", @parts );
     }
-    sub _vec_to_params
+
+    sub _key_to_params
     {
-        my ($vec) = @_;
+        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;
-        while (my ($k, $v) = each %_Formats) 
+        $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 )
         {
-            next unless vec( $vec, $v->[0], $v->[1] );
-            $params{$k} = 1;
+            $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;
         }
-        %params;
-    }
-}
 
-{
-    my %_Formats;
+        my $new_key = _params_to_key(%params);
 
-    sub _assign {
-        $_Formats{$_[0]} = $_[1] unless exists $_Formats{$_[0]};
-        $_Formats{$_[1]} = $_[0] unless exists $_Formats{$_[1]};
-    }
+        my $format = _retrieve_format($self, $new_key);
+        return $format if $format;
 
-    sub _retrieve_vec    { ref($_[0]) ? ($_Formats{$_[0]}) : ($_[0]); }
-    sub _retrieve_format { ref($_[0]) ? ($_[0]) : ($_Formats{$_[0]}); }
+        $format = $context->{XLS}->add_format(%params);
+        _assign($self, $new_key, $format);
+        return $format;
+    }
 }
 
 sub blank_format
 {
-    shift;
+    my $self = shift;
     my ($context) = @_;
 
-    my $blank_vec = _params_to_vec();
+    my $blank_key = _params_to_key();
 
-    my $format = _retrieve_format($blank_vec);
+    my $format = _retrieve_format($self, $blank_key);
     return $format if $format;
 
     $format = $context->{XLS}->add_format;
-    _assign($blank_vec, $format);
-    $format;
+    _assign($self, $blank_key, $format);
+    return $format;
 }
 
-sub copy
-{
-    shift;
-    my ($context, $old_format, %properties) = @_;
+1;
+__END__
 
-    defined(my $vec = _retrieve_vec($old_format))
-        || die "Internal Error: Cannot find vector for format '$old_format'!\n";
+=head1 NAME
 
-    my $new_vec = _params_to_vec(%properties);
+Excel::Template::Format - Excel::Template::Format
 
-    $new_vec |= $vec;
+=head1 PURPOSE
 
-    my $format = _retrieve_format($new_vec);
-    return $format if $format;
+Helper class for FORMAT
 
-    $format = $context->{XLS}->add_format(_vec_to_params($new_vec));
-    _assign($new_vec, $format);
-    $format;
-}
+=head1 NODE NAME
 
-1;
-__END__
+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
 
-Category   Description       Property        Method Name          Implemented
---------   -----------       --------        -----------          -----------
-Font       Font type         font            set_font()
-           Font size         size            set_size()
-           Font color        color           set_color()
-           Bold              bold            set_bold()              YES
-           Italic            italic          set_italic()            YES
-           Underline         underline       set_underline()
-           Strikeout         font_strikeout  set_font_strikeout()    YES
-           Super/Subscript   font_script     set_font_script()
-           Outline           font_outline    set_font_outline()      YES
-           Shadow            font_shadow     set_font_shadow()       YES
-
-Number     Numeric format    num_format      set_num_format()
-
-Protection Lock cells        locked          set_locked()            YES
-           Hide formulas     hidden          set_hidden()            YES
-
-Alignment  Horizontal align  align           set_align()
-           Vertical align    valign          set_align()
-           Rotation          rotation        set_rotation()
-           Text wrap         text_wrap       set_text_wrap()
-           Justify last      text_justlast   set_text_justlast()
-           Merge             merge           set_merge()
-
-Pattern    Cell pattern      pattern         set_pattern()
-           Background color  bg_color        set_bg_color()
-           Foreground color  fg_color        set_fg_color()
-
-Border     Cell border       border          set_border()
-           Bottom border     bottom          set_bottom()
-           Top border        top             set_top()
-           Left border       left            set_left()
-           Right border      right           set_right()
-           Border color      border_color    set_border_color()
-           Bottom color      bottom_color    set_bottom_color()
-           Top color         top_color       set_top_color()
-           Left color        left_color      set_left_color()
-           Right color       right_color     set_right_color()
+=cut