]> source.dussan.org Git - poi.git/commitdiff
HSSF record support for CF Iconset rules
authorNick Burch <nick@apache.org>
Tue, 14 Jul 2015 23:30:53 +0000 (23:30 +0000)
committerNick Burch <nick@apache.org>
Tue, 14 Jul 2015 23:30:53 +0000 (23:30 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1691107 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hssf/record/CFRule12Record.java
src/java/org/apache/poi/hssf/record/cf/FontFormatting.java
src/java/org/apache/poi/hssf/record/cf/IconMultiStateFormatting.java [new file with mode: 0644]
src/java/org/apache/poi/ss/usermodel/IconMultiStateFormatting.java
src/java/org/apache/poi/util/BitFieldFactory.java

index c99d12587311bb98ead90229ecaa156733404430..3ace01263e1397485a5dd9d9f90a161b7d41bdb9 100644 (file)
@@ -19,6 +19,7 @@ package org.apache.poi.hssf.record;
 
 import java.util.Arrays;
 
+import org.apache.poi.hssf.record.cf.IconMultiStateFormatting;
 import org.apache.poi.hssf.record.common.FtrHeader;
 import org.apache.poi.hssf.record.common.FutureRecord;
 import org.apache.poi.hssf.usermodel.HSSFSheet;
@@ -52,11 +53,12 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord {
     private byte template_param_length;
     private byte[] template_params;
     
+    private IconMultiStateFormatting multistate;
+    
     // TODO Parse these
     private byte[] gradient_data;
     private byte[] databar_data;
     private byte[] filter_data;
-    private byte[] multistate_data;
 
     /** Creates new CFRuleRecord */
     private CFRule12Record(byte conditionType, byte comparisonOperation) {
@@ -161,7 +163,7 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord {
         } else if (type == CONDITION_TYPE_FILTER) {
             filter_data = in.readRemainder();
         } else if (type == CONDITION_TYPE_ICON_SET) {
-            multistate_data = in.readRemainder();
+            multistate = new IconMultiStateFormatting(in);
         }
     }
 
@@ -231,7 +233,7 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord {
         } else if (type == CONDITION_TYPE_FILTER) {
             out.write(filter_data);
         } else if (type == CONDITION_TYPE_ICON_SET) {
-            out.write(multistate_data);
+            multistate.serialize(out);
         }
     }
 
@@ -255,7 +257,7 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord {
         } else if (type == CONDITION_TYPE_FILTER) {
             len += filter_data.length;
         } else if (type == CONDITION_TYPE_ICON_SET) {
-            len += multistate_data.length;
+            len += multistate.getDataLength();
         }
         return len;
     }
@@ -286,7 +288,9 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord {
         buffer.append("    .gradient_data  =").append(HexDump.toHex(gradient_data)).append("\n");
         buffer.append("    .databar_data   =").append(HexDump.toHex(databar_data)).append("\n");
         buffer.append("    .filter_data    =").append(HexDump.toHex(filter_data)).append("\n");
-        buffer.append("    .multistate_data=").append(HexDump.toHex(multistate_data)).append("\n");
+        if (multistate != null) {
+            buffer.append(multistate);
+        }
         buffer.append("[/CFRULE12]\n");
         return buffer.toString();
     }
index b3cb5e9447ea4e12a220da17da4c65f6937be848..59c49d8a42fb5999bbb8cc1ecf3d2c6f4f6cb10f 100644 (file)
@@ -368,8 +368,7 @@ public final class FontFormatting {
         setInt(OFFSET_FONT_COLOR_INDEX,fci);
     }
 
-    private boolean getOptionFlag(BitField field)
-    {
+    private boolean getOptionFlag(BitField field) {
         int optionFlags = getInt(OFFSET_OPTION_FLAGS);
         int value = field.getValue(optionFlags);
         return value==0? true : false ;
diff --git a/src/java/org/apache/poi/hssf/record/cf/IconMultiStateFormatting.java b/src/java/org/apache/poi/hssf/record/cf/IconMultiStateFormatting.java
new file mode 100644 (file)
index 0000000..8cd177a
--- /dev/null
@@ -0,0 +1,123 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record.cf;
+
+import org.apache.poi.ss.usermodel.IconMultiStateFormatting.IconSet;
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+
+/**
+ * Icon / Multi-State Conditional Formatting Rule Record.
+ */
+public final class IconMultiStateFormatting implements Cloneable {
+    private static POILogger log = POILogFactory.getLogger(IconMultiStateFormatting.class);
+            
+    private IconSet iconSet;
+    private byte options;
+    private byte[] states; // TODO Decode
+    
+    private static BitField iconOnly = BitFieldFactory.getInstance(0x01);
+    private static BitField reversed = BitFieldFactory.getInstance(0x04);
+
+    public IconMultiStateFormatting() {
+        iconSet = IconSet.GYR_3_TRAFFIC_LIGHTS;
+        options = 0;
+        states = new byte[0];
+    }
+    public IconMultiStateFormatting(LittleEndianInput in) {
+        in.readShort(); // Ignored
+        in.readByte();  // Reserved
+        int num = in.readByte();
+        int set = in.readByte();
+        iconSet = IconSet.byId(set);
+        if (iconSet.num != num) {
+            log.log(POILogger.WARN, "Inconsistent Icon Set defintion, found " + iconSet + " but defined as " + num + " entries");
+        }
+        options = in.readByte();
+        // TODO Decode
+        states = new byte[in.available()];
+        in.readFully(states);
+    }
+    
+    public IconSet getIconSet() {
+        return iconSet;
+    }
+    public void setIconSet(IconSet set) {
+        this.iconSet = set;
+    }
+
+    public boolean isIconOnly() {
+        return getOptionFlag(iconOnly);
+    }
+    public void setIconOnly(boolean only) {
+        setOptionFlag(only, iconOnly);
+    }
+    
+    public boolean isReversed() {
+        return getOptionFlag(reversed);
+    }
+    public void setReversed(boolean rev) {
+        setOptionFlag(rev, reversed);
+    }
+    
+    private boolean getOptionFlag(BitField field) {
+        int value = field.getValue(options);
+        return value==0? true : false ;
+    }
+    private void setOptionFlag(boolean option, BitField field) {
+        options = field.setByteBoolean(options, option);
+    }
+    
+    public String toString() {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append("    [Icon Formatting]\n");
+        buffer.append("          .icon_set = ").append(iconSet).append("\n");
+        buffer.append("          .icon_only= ").append(isIconOnly()).append("\n");
+        buffer.append("          .reversed = ").append(isReversed()).append("\n");
+        buffer.append("          .states   = ").append(HexDump.toHex(states)).append("\n");
+        buffer.append("    [/Icon Formatting]\n");
+        return buffer.toString();
+    }
+    
+    public Object clone()  {
+      IconMultiStateFormatting rec = new IconMultiStateFormatting();
+      rec.iconSet = iconSet;
+      rec.options = options;
+      rec.states = new byte[states.length];
+      System.arraycopy(states, 0, rec.states, 0, states.length);
+      return rec;
+    }
+    
+    public int getDataLength() {
+        return 6 + states.length;
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        out.writeShort(0);
+        out.writeByte(0);
+        out.writeByte(iconSet.num);
+        out.writeByte(iconSet.id);
+        out.writeByte(options);
+        out.write(states);
+    }
+}
index 84279c82a892cd1fb5dbb8712e54e586c770a36c..d4762c790cd75748cf95fdbeaef616aefd3d1b61 100644 (file)
 \r
 package org.apache.poi.ss.usermodel;\r
 \r
-import java.util.HashMap;\r
-import java.util.Map;\r
-\r
 /**\r
  * High level representation for the Icon / Multi-State Formatting \r
  *  component of Conditional Formatting settings\r
  */\r
 public interface IconMultiStateFormatting {\r
-    class IconSet {\r
+    public enum IconSet {\r
+        /** Green Up / Yellow Side / Red Down arrows */\r
+        GYR_3_ARROW(0, 3, "3Arrows"),\r
+        /** Grey Up / Side / Down arrows */\r
+        GREY_3_ARROWS(1, 3, "3ArrowsGray"),\r
+        /** Green / Yellow / Red flags */\r
+        GYR_3_FLAGS(2, 3, "3Flags"),\r
+        /** Green / Yellow / Red traffic lights (no background) */\r
+        GYR_3_TRAFFIC_LIGHTS(3, 3, null),\r
+        /** Green Circle / Yellow Triangle / Red Diamond */ \r
+        GYR_3_SHAPES(4, 3, "3Signs"),\r
+        /** Green / Yellow / Red traffic lights on a black square background */\r
+        GYR_3_TRAFFIC_LIGHTS_BOX(5, 3, "3TrafficLights2"),\r
+        /** Green Tick / Yellow ! / Red Cross on a circle background */\r
+        GYR_3_SYMBOLS_CIRCLE(6, 3, "3Symbols"),\r
+        /** Green Tick / Yellow ! / Red Cross (no background) */\r
+        GYR_3_SYMBOLS(7, 3, "3Symbols2"),\r
+        /** Green Up / Yellow NE / Yellow SE / Red Down arrows */\r
+        GYR_4_ARROWS(8, 4, "4Arrows"),\r
+        /** Grey Up / NE / SE / Down arrows */\r
+        GREY_4_ARROWS(9, 4, "4ArrowsGray"),\r
+        /** Red / Light Red / Grey / Black traffic lights */\r
+        RB_4_TRAFFIC_LIGHTS(0xA, 4, "4RedToBlack"),\r
+        RATINGS_4(0xB, 4, "4Rating"),\r
+        /** Green / Yellow / Red / Black traffic lights */\r
+        GYRB_4_TRAFFIC_LIGHTS(0xC, 4, "4TrafficLights"),\r
+        GYYYR_5_ARROWS(0xD, 5, "5Arrows"),\r
+        GREY_5_ARROWS(0xE, 5, "5ArrowsGray"),\r
+        RATINGS_5(0xF, 5, "5Rating"),\r
+        QUARTERS_5(0x10, 5, "5Quarters");\r
+        \r
         /** Numeric ID of the icon set */\r
-        public final int id;\r
+        public int id;\r
         /** How many icons in the set */\r
         public final int num;\r
         /** Name (system) of the set */\r
@@ -42,46 +69,14 @@ public interface IconMultiStateFormatting {
             return (name==null?"default":name);\r
         }\r
         \r
-        public static IconSet byId(int id) { return byId[id]; }\r
-        public static IconSet byName(String name) { return byName.get(name); }\r
+        public static IconSet byId(int id) {\r
+            return values()[id];\r
+        }\r
         \r
-        private static final IconSet[] byId = new IconSet[0x10];\r
-        private static final Map<String,IconSet> byName = new HashMap<String, IconMultiStateFormatting.IconSet>();\r
         private IconSet(int id, int num, String name) {\r
             this.id = id; this.num = num; this.name = name;\r
-            byId[id] = this;\r
-            byName.put(getName(),this);\r
         }\r
     }\r
-    /** Green Up / Yellow Side / Red Down arrows */\r
-    static final IconSet GYR_3_ARROWS = new IconSet(0, 3, "3Arrows");\r
-    /** Grey Up / Side / Down arrows */\r
-    static final IconSet GREY_3_ARROWS = new IconSet(1, 3, "3ArrowsGray");\r
-    /** Green / Yellow / Red flags */\r
-    static final IconSet GYR_3_FLAGS = new IconSet(2, 3, "3Flags");\r
-    /** Green / Yellow / Red traffic lights (no background) */\r
-    static final IconSet GYR_3_TRAFFIC_LIGHTS = new IconSet(3, 3, null);\r
-    /** Green Circle / Yellow Triangle / Red Diamond */ \r
-    static final IconSet GYR_3_SHAPES = new IconSet(4, 3, "3Signs");\r
-    /** Green / Yellow / Red traffic lights on a black square background */\r
-    static final IconSet GYR_3_TRAFFIC_LIGHTS_BOX = new IconSet(5, 3, "3TrafficLights2");\r
-    /** Green Tick / Yellow ! / Red Cross on a circle background */\r
-    static final IconSet GYR_3_SYMBOLS_CIRCLE = new IconSet(6, 3, "3Symbols");\r
-    /** Green Tick / Yellow ! / Red Cross (no background) */\r
-    static final IconSet GYR_3_SYMBOLS = new IconSet(7, 3, "3Symbols2");\r
-    /** Green Up / Yellow NE / Yellow SE / Red Down arrows */\r
-    static final IconSet GYR_4_ARROWS = new IconSet(8, 4, "4Arrows");\r
-    /** Grey Up / NE / SE / Down arrows */\r
-    static final IconSet GREY_4_ARROWS = new IconSet(9, 4, "4ArrowsGray");\r
-    /** Red / Light Red / Grey / Black traffic lights */\r
-    static final IconSet RB_4_TRAFFIC_LIGHTS = new IconSet(0xA, 4, "4RedToBlack");\r
-    static final IconSet RATINGS_4 = new IconSet(0xB, 4, "4Rating");\r
-    /** Green / Yellow / Red / Black traffic lights */\r
-    static final IconSet GYRB_4_TRAFFIC_LIGHTS = new IconSet(0xC, 4, "4TrafficLights");\r
-    static final IconSet GYYYR_5_ARROWS = new IconSet(0xD, 5, "5Arrows");\r
-    static final IconSet GREY_5_ARROWS = new IconSet(0xE, 5, "5ArrowsGray");\r
-    static final IconSet RATINGS_5 = new IconSet(0xF, 5, "5Rating");\r
-    static final IconSet QUARTERS_5 = new IconSet(0x10, 5, "5Quarters");\r
     \r
     /**\r
      * Get the Icon Set used\r
index 4159074d76ec45e6b60f63c6d17ace341ca26a5b..047d5cb1dae9c2637a0b3685b2f7cb5ae31d2425 100644 (file)
@@ -21,11 +21,8 @@ package org.apache.poi.util;
 import java.util.*;
 
 /**
- * Returns immutable Btfield instances.
- *
- * @author Jason Height (jheight at apache dot org)
+ * Returns immutable Bitfield instances.
  */
-
 public class BitFieldFactory {
     private static Map<Integer, BitField> instances = new HashMap<Integer, BitField>();