public static final int TYPE_THEMED = 3;
public static final int TYPE_UNSET = 4;
- private int type;
- // TODO Decode
- private byte[] value;
+ public static final int THEME_DARK_1 = 0;
+ public static final int THEME_LIGHT_1 = 1;
+ public static final int THEME_DARK_2 = 2;
+ public static final int THEME_LIGHT_2 = 3;
+ public static final int THEME_ACCENT_1 = 4;
+ public static final int THEME_ACCENT_2 = 5;
+ public static final int THEME_ACCENT_3 = 6;
+ public static final int THEME_ACCENT_4 = 7;
+ public static final int THEME_ACCENT_5 = 8;
+ public static final int THEME_ACCENT_6 = 9;
+ public static final int THEME_HYPERLINK = 10;
+ // This one is SheetEx only, not allowed in CFs
+ public static final int THEME_FOLLOWED_HYPERLINK = 11;
+
+ private int type;
+
+ // Type = Indexed
+ private int colorIndex;
+ // Type = RGB
+ private byte[] rgba;
+ // Type = Theme
+ private int themeIndex;
+
private double tint;
public ExtendedColor() {
this.type = TYPE_INDEXED;
- this.value = new byte[4];
+ this.colorIndex = 0;
this.tint = 0d;
}
public ExtendedColor(LittleEndianInput in) {
type = in.readInt();
- // TODO Decode color
- value = new byte[4];
- in.readFully(value);
+ if (type == TYPE_INDEXED) {
+ colorIndex = in.readInt();
+ } else if (type == TYPE_RGB) {
+ rgba = new byte[4];
+ in.readFully(rgba);
+ } else if (type == TYPE_THEMED) {
+ themeIndex = in.readInt();
+ } else {
+ // Ignored
+ in.readInt();
+ }
tint = in.readDouble();
}
public void setType(int type) {
this.type = type;
}
+
+ /**
+ * @return Palette color index, if type is {@link #TYPE_INDEXED}
+ */
+ public int getColorIndex() {
+ return colorIndex;
+ }
+ public void setColorIndex(int colorIndex) {
+ this.colorIndex = colorIndex;
+ }
- // TODO Return the color details
+ /**
+ * @return Red Green Blue Alpha, if type is {@link #TYPE_RGB}
+ */
+ public byte[] getRGBA() {
+ return rgba;
+ }
+ public void setRGBA(byte[] rgba) {
+ this.rgba = rgba;
+ }
+ /**
+ * @return Theme color type index, eg {@link #THEME_DARK_1}, if type is {@link #TYPE_THEMED}
+ */
+ public int getThemeIndex() {
+ return themeIndex;
+ }
+ public void setThemeIndex(int themeIndex) {
+ this.themeIndex = themeIndex;
+ }
/**
* @return Tint and Shade value, between -1 and +1
*/
buffer.append(" [Extended Color]\n");
buffer.append(" .type = ").append(type).append("\n");
buffer.append(" .tint = ").append(tint).append("\n");
- buffer.append(" .color = ").append(HexDump.toHex(value)).append("\n");
+ buffer.append(" .c_idx = ").append(colorIndex).append("\n");
+ buffer.append(" .rgba = ").append(HexDump.toHex(rgba)).append("\n");
+ buffer.append(" .t_idx = ").append(themeIndex).append("\n");
buffer.append(" [/Extended Color]\n");
return buffer.toString();
}
ExtendedColor exc = new ExtendedColor();
exc.type = type;
exc.tint = tint;
- exc.value = new byte[value.length];
- System.arraycopy(value, 0, exc.value, 0, value.length);
+ if (type == TYPE_INDEXED) {
+ exc.colorIndex = colorIndex;
+ } else if (type == TYPE_RGB) {
+ exc.rgba = new byte[4];
+ System.arraycopy(rgba, 0, exc.rgba, 0, 4);
+ } else if (type == TYPE_THEMED) {
+ exc.themeIndex = themeIndex;
+ }
return exc;
}
public void serialize(LittleEndianOutput out) {
out.writeInt(type);
- out.write(value);
+ if (type == TYPE_INDEXED) {
+ out.writeInt(colorIndex);
+ } else if (type == TYPE_RGB) {
+ out.write(rgba);
+ } else if (type == TYPE_THEMED) {
+ out.writeInt(themeIndex);
+ } else {
+ out.writeInt(0);
+ }
out.writeDouble(tint);
}
}
\ No newline at end of file
import org.apache.poi.hssf.record.cf.ColorGradientFormatting;
import org.apache.poi.hssf.record.cf.ColorGradientThreshold;
import org.apache.poi.hssf.record.cf.Threshold;
+import org.apache.poi.hssf.record.common.ExtendedColor;
import org.apache.poi.ss.usermodel.Color;
import org.apache.poi.ss.usermodel.ConditionalFormattingThreshold;
colorFormatting.setNumControlPoints(num);
}
- public Color[] getColors() {
- return null; // TODO
+ public HSSFExtendedColor[] getColors() {
+ ExtendedColor[] colors = colorFormatting.getColors();
+ HSSFExtendedColor[] hcolors = new HSSFExtendedColor[colors.length];
+ for (int i=0; i<colors.length; i++) {
+ hcolors[i] = new HSSFExtendedColor(colors[i]);
+ }
+ return hcolors;
}
public void setColors(Color[] colors) {
- // TODO
+ ExtendedColor[] cr = new ExtendedColor[colors.length];
+ for (int i=0; i<colors.length; i++) {
+ cr[i] = ((HSSFExtendedColor)colors[i]).getExtendedColor();
+ }
+ colorFormatting.setColors(cr);
}
public HSSFConditionalFormattingThreshold[] getThresholds() {
--- /dev/null
+/* ====================================================================
+ 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.usermodel;
+
+import static org.apache.poi.hssf.record.common.ExtendedColor.TYPE_AUTO;
+import static org.apache.poi.hssf.record.common.ExtendedColor.TYPE_INDEXED;
+import static org.apache.poi.hssf.record.common.ExtendedColor.TYPE_RGB;
+import static org.apache.poi.hssf.record.common.ExtendedColor.TYPE_THEMED;
+
+import org.apache.poi.ss.usermodel.ExtendedColor;
+
+/**
+ * The HSSF file format normally stores Color information in the
+ * Palette (see PaletteRecord), but for a few cases (eg Conditional
+ * Formatting, Sheet Extensions), this XSSF-style color record
+ * can be used.
+ */
+public class HSSFExtendedColor extends ExtendedColor {
+ private org.apache.poi.hssf.record.common.ExtendedColor color;
+
+ public HSSFExtendedColor(org.apache.poi.hssf.record.common.ExtendedColor color) {
+ this.color = color;
+ }
+
+ protected org.apache.poi.hssf.record.common.ExtendedColor getExtendedColor() {
+ return color;
+ }
+
+ public boolean isAuto() {
+ return color.getType() == TYPE_AUTO;
+ }
+ public boolean isIndexed() {
+ return color.getType() == TYPE_INDEXED;
+ }
+ public boolean isRGB() {
+ return color.getType() == TYPE_RGB;
+ }
+ public boolean isThemed() {
+ return color.getType() == TYPE_THEMED;
+ }
+
+ public short getIndex() {
+ return (short)color.getColorIndex();
+ }
+ public int getTheme() {
+ return color.getThemeIndex();
+ }
+
+ public byte[] getRGB() {
+ // Trim trailing A
+ byte[] rgb = new byte[3];
+ byte[] rgba = color.getRGBA();
+ if (rgba == null) return null;
+ System.arraycopy(rgba, 0, rgb, 0, 3);
+ return rgb;
+ }
+ public byte[] getARGB() {
+ // Swap from RGBA to ARGB
+ byte[] argb = new byte[4];
+ byte[] rgba = color.getRGBA();
+ if (rgba == null) return null;
+ System.arraycopy(rgba, 0, argb, 1, 3);
+ argb[0] = rgba[3];
+ return argb;
+ }
+
+ protected byte[] getStoredRBG() {
+ return getARGB();
+ }
+
+ public void setRGB(byte[] rgb) {
+ if (rgb.length == 3) {
+ byte[] rgba = new byte[4];
+ System.arraycopy(rgb, 0, rgba, 0, 3);
+ rgba[3] = -1;
+ } else {
+ // Shuffle from ARGB to RGBA
+ byte a = rgb[0];
+ rgb[0] = rgb[1];
+ rgb[1] = rgb[2];
+ rgb[2] = rgb[3];
+ rgb[3] = a;
+ color.setRGBA(rgb);
+ }
+ }
+
+ public double getTint() {
+ return color.getTint();
+ }
+ public void setTint(double tint) {
+ color.setTint(tint);
+ }
+}
import org.apache.poi.hssf.record.CFRule12Record;
import org.apache.poi.hssf.record.cf.IconMultiStateFormatting;
+import org.apache.poi.hssf.record.cf.IconMultiStateThreshold;
import org.apache.poi.hssf.record.cf.Threshold;
import org.apache.poi.ss.usermodel.ConditionalFormattingThreshold;
}
public HSSFConditionalFormattingThreshold createThreshold() {
- return new HSSFConditionalFormattingThreshold(new Threshold(), sheet);
+ return new HSSFConditionalFormattingThreshold(new IconMultiStateThreshold(), sheet);
}
}
}
protected void assertColour(String hexExpected, Color actual) {
assertNotNull("Colour must be given", actual);
- HSSFColor colour = (HSSFColor)actual;
- assertEquals(hexExpected, colour.getHexString());
+ if (actual instanceof HSSFColor) {
+ HSSFColor colour = (HSSFColor)actual;
+ assertEquals(hexExpected, colour.getHexString());
+ } else {
+ HSSFExtendedColor colour = (HSSFExtendedColor)actual;
+ if (hexExpected.length() == 8) {
+ assertEquals(hexExpected, colour.getARGBHex());
+ } else {
+ assertEquals(hexExpected, colour.getARGBHex().substring(2));
+ }
+ }
}
public void testRead() {
assertEquals(null, cr.getFormula1());\r
assertEquals(null, cr.getFormula2());\r
\r
-// TODO Finish HSSF\r
-if (cr instanceof HSSFConditionalFormattingRule) return;\r
- \r
ColorScaleFormatting color = cr.getColorScaleFormatting();\r
assertNotNull(color);\r
assertNotNull(color.getColors());\r