import org.apache.poi.hssf.record.cf.ColorGradientFormatting;
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.hssf.record.common.FtrHeader;
import org.apache.poi.hssf.record.common.FutureRecord;
public static CFRule12Record create(HSSFSheet sheet, IconSet iconSet) {
Threshold[] ts = new Threshold[iconSet.num];
for (int i=0; i<ts.length; i++) {
- ts[i] = new Threshold();
+ ts[i] = new IconMultiStateThreshold();
}
CFRule12Record r = new CFRule12Record(CONDITION_TYPE_COLOR_SCALE,
package org.apache.poi.hssf.record.cf;
+import org.apache.poi.hssf.record.common.ExtendedColor;
import org.apache.poi.util.BitField;
import org.apache.poi.util.BitFieldFactory;
import org.apache.poi.util.LittleEndianInput;
private static POILogger log = POILogFactory.getLogger(ColorGradientFormatting.class);
private byte options = 0;
- private Threshold[] thresholds;
- private byte[] colors; // TODO Decode
+ private ColorGradientThreshold[] thresholds;
+ private ExtendedColor[] colors;
private static BitField clamp = BitFieldFactory.getInstance(0x01);
private static BitField background = BitFieldFactory.getInstance(0x02);
public ColorGradientFormatting() {
options = 3;
- thresholds = new Threshold[3];
+ thresholds = new ColorGradientThreshold[3];
+ colors = new ExtendedColor[3];
}
public ColorGradientFormatting(LittleEndianInput in) {
in.readShort(); // Ignored
}
options = in.readByte();
- // TODO Are these correct?
- thresholds = new Threshold[numI];
+ thresholds = new ColorGradientThreshold[numI];
for (int i=0; i<thresholds.length; i++) {
- thresholds[i] = new Threshold(in);
- in.readDouble(); // Rather pointless value...
+ thresholds[i] = new ColorGradientThreshold(in);
+ }
+ colors = new ExtendedColor[numG];
+ for (int i=0; i<colors.length; i++) {
+ in.readDouble(); // Slightly pointless step counter
+ colors[i] = new ExtendedColor(in);
}
- // TODO Decode colors
- colors = new byte[in.available()];
- in.readFully(colors);
}
public int getNumControlPoints() {
}
public void setNumControlPoints(int num) {
if (num != thresholds.length) {
- thresholds = new Threshold[num];
- // TODO Colors
+ ColorGradientThreshold[] nt = new ColorGradientThreshold[num];
+ ExtendedColor[] nc = new ExtendedColor[num];
+
+ int copy = Math.min(thresholds.length, num);
+ System.arraycopy(thresholds, 0, nt, 0, copy);
+ System.arraycopy(colors, 0, nc, 0, copy);
+
+ this.thresholds = nt;
+ this.colors = nc;
+
+ updateThresholdPositions();
}
}
- public Threshold[] getThresholds() {
+ public ColorGradientThreshold[] getThresholds() {
return thresholds;
}
- public void setThresholds(Threshold[] thresholds) {
+ public void setThresholds(ColorGradientThreshold[] thresholds) {
this.thresholds = thresholds;
+ updateThresholdPositions();
}
- // TODO Colors
+ public ExtendedColor[] getColors() {
+ return colors;
+ }
+ public void setColors(ExtendedColor[] colors) {
+ this.colors = colors;
+ }
public boolean isClampToCurve() {
return getOptionFlag(clamp);
int value = field.getValue(options);
return value==0 ? false : true;
}
+
+ private void updateThresholdPositions() {
+ double step = 1d / (thresholds.length-1);
+ for (int i=0; i<thresholds.length; i++) {
+ thresholds[i].setPosition(step*i);
+ }
+ }
public String toString() {
StringBuffer buffer = new StringBuffer();
for (Threshold t : thresholds) {
buffer.append(t.toString());
}
+ for (ExtendedColor c : colors) {
+ buffer.append(c.toString());
+ }
buffer.append(" [/Color Gradient Formatting]\n");
return buffer.toString();
}
public Object clone() {
ColorGradientFormatting rec = new ColorGradientFormatting();
rec.options = options;
- rec.thresholds = new Threshold[thresholds.length];
+ rec.thresholds = new ColorGradientThreshold[thresholds.length];
+ rec.colors = new ExtendedColor[colors.length];
System.arraycopy(thresholds, 0, rec.thresholds, 0, thresholds.length);
- // TODO Colors
+ System.arraycopy(colors, 0, rec.colors, 0, colors.length);
return rec;
}
int len = 6;
for (Threshold t : thresholds) {
len += t.getDataLength();
+ }
+ for (ExtendedColor c : colors) {
+ len += c.getDataLength();
len += 8;
}
- len += colors.length;
return len;
}
out.writeByte(thresholds.length);
out.writeByte(options);
- double step = 1d / (thresholds.length-1);
- for (int i=0; i<thresholds.length; i++) {
- Threshold t = thresholds[i];
+ for (ColorGradientThreshold t : thresholds) {
t.serialize(out);
- out.writeDouble(step*i);
}
- out.write(colors);
+ double step = 1d / (colors.length-1);
+ for (int i=0; i<colors.length; i++) {
+ out.writeDouble(i*step);
+
+ ExtendedColor c = colors[i];
+ c.serialize(out);
+ }
}
}
--- /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.record.cf;
+
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Color Gradient / Color Scale specific Threshold / value (CFVO),
+ * for changes in Conditional Formatting
+ */
+public final class ColorGradientThreshold extends Threshold {
+ private double position;
+
+ public ColorGradientThreshold() {
+ super();
+ position = 0d;
+ }
+
+ /** Creates new Ico Multi-State Threshold */
+ public ColorGradientThreshold(LittleEndianInput in) {
+ super(in);
+ position = in.readDouble();
+ }
+
+ public double getPosition() {
+ return position;
+ }
+ public void setPosition(double position) {
+ this.position = position;
+ }
+
+ public int getDataLength() {
+ return super.getDataLength() + 8;
+ }
+
+ public Object clone() {
+ ColorGradientThreshold rec = new ColorGradientThreshold();
+ super.copyTo(rec);
+ rec.position = position;
+ return rec;
+ }
+
+ public void serialize(LittleEndianOutput out) {
+ super.serialize(out);
+ out.writeDouble(position);
+ }
+}
thresholds = new Threshold[iconSet.num];
for (int i=0; i<thresholds.length; i++) {
- thresholds[i] = new Threshold(in);
+ thresholds[i] = new IconMultiStateThreshold(in);
}
}
--- /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.record.cf;
+
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Icon / Multi-State specific Threshold / value (CFVO),
+ * for changes in Conditional Formatting
+ */
+public final class IconMultiStateThreshold extends Threshold {
+ /**
+ * Cell values that are equal to the threshold value do not pass the threshold
+ */
+ public static final byte EQUALS_EXCLUDE = 0;
+ /**
+ * Cell values that are equal to the threshold value pass the threshold.
+ */
+ public static final byte EQUALS_INCLUDE = 1;
+
+ private byte equals;
+
+ public IconMultiStateThreshold() {
+ super();
+ equals = EQUALS_INCLUDE;
+ }
+
+ /** Creates new Ico Multi-State Threshold */
+ public IconMultiStateThreshold(LittleEndianInput in) {
+ super(in);
+ equals = in.readByte();
+ // Reserved, 4 bytes, all 0
+ in.readInt();
+ }
+
+ public byte getEquals() {
+ return equals;
+ }
+ public void setEquals(byte equals) {
+ this.equals = equals;
+ }
+
+ public int getDataLength() {
+ return super.getDataLength() + 5;
+ }
+
+ public Object clone() {
+ IconMultiStateThreshold rec = new IconMultiStateThreshold();
+ super.copyTo(rec);
+ rec.equals = equals;
+ return rec;
+ }
+
+ public void serialize(LittleEndianOutput out) {
+ super.serialize(out);
+ out.writeByte(equals);
+ out.writeInt(0); // Reserved
+ }
+}
import org.apache.poi.util.LittleEndianOutput;
/**
- * Threshold / value for changes in Conditional Formatting
+ * Threshold / value (CFVO) for changes in Conditional Formatting
*/
-public final class Threshold {
- /**
- * Cell values that are equal to the threshold value do not pass the threshold
- */
- public static final byte EQUALS_EXCLUDE = 0;
- /**
- * Cell values that are equal to the threshold value pass the threshold.
- */
- public static final byte EQUALS_INCLUDE = 1;
-
+public abstract class Threshold {
private byte type;
private Formula formula;
private Double value;
- private byte equals;
- public Threshold() {
+ protected Threshold() {
type = (byte)RangeType.NUMBER.id;
formula = Formula.create(null);
value = 0d;
}
/** Creates new Threshold */
- public Threshold(LittleEndianInput in) {
+ protected Threshold(LittleEndianInput in) {
type = in.readByte();
short formulaLen = in.readShort();
if (formulaLen > 0) {
type != RangeType.MAX.id) {
value = in.readDouble();
}
- equals = in.readByte();
- // Reserved, 4 bytes, all 0
- in.readInt();
}
public byte getType() {
public void setType(byte type) {
this.type = type;
- // Ensure the value presense / absense is consistent for the new type
+ // Ensure the value presence / absence is consistent for the new type
if (type == RangeType.MIN.id || type == RangeType.MAX.id ||
type == RangeType.FORMULA.id) {
this.value = null;
this.value = value;
}
- public byte getEquals() {
- return equals;
- }
- public void setEquals(byte equals) {
- this.equals = equals;
- }
-
public int getDataLength() {
int len = 1 + formula.getEncodedSize();
if (value != null) {
len += 8;
}
- len += 5;
return len;
}
return buffer.toString();
}
- public Object clone() {
- Threshold rec = new Threshold();
+ public void copyTo(Threshold rec) {
rec.type = type;
rec.formula = formula;
rec.value = value;
- rec.equals = equals;
- return rec;
}
public void serialize(LittleEndianOutput out) {
if (value != null) {
out.writeDouble(value);
}
- out.writeByte(equals);
- out.writeInt(0); // Reserved
}
}
import org.apache.poi.hssf.record.CFRule12Record;
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.ss.usermodel.Color;
import org.apache.poi.ss.usermodel.ConditionalFormattingThreshold;
}
public void setThresholds(ConditionalFormattingThreshold[] thresholds) {
- Threshold[] t = new Threshold[thresholds.length];
+ ColorGradientThreshold[] t = new ColorGradientThreshold[thresholds.length];
for (int i=0; i<t.length; i++) {
- t[i] = ((HSSFConditionalFormattingThreshold)thresholds[i]).getThreshold();
+ HSSFConditionalFormattingThreshold hssfT = (HSSFConditionalFormattingThreshold)thresholds[i];
+ t[i] = (ColorGradientThreshold)hssfT.getThreshold();
}
colorFormatting.setThresholds(t);
}
public HSSFConditionalFormattingThreshold createThreshold() {
- return new HSSFConditionalFormattingThreshold(new Threshold(), sheet);
+ return new HSSFConditionalFormattingThreshold(new ColorGradientThreshold(), sheet);
}
}