#58130 CF Threshold formats differ slightly between types
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1691858 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
7bd1216c52
commit
9aa44bca07
@ -21,6 +21,7 @@ import java.util.Arrays;
|
||||
|
||||
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;
|
||||
@ -125,7 +126,7 @@ public final class CFRule12Record extends CFRuleBase implements 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,
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
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;
|
||||
@ -33,15 +34,16 @@ public final class ColorGradientFormatting implements Cloneable {
|
||||
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
|
||||
@ -53,15 +55,15 @@ public final class ColorGradientFormatting implements Cloneable {
|
||||
}
|
||||
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() {
|
||||
@ -69,19 +71,34 @@ public final class ColorGradientFormatting implements Cloneable {
|
||||
}
|
||||
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);
|
||||
@ -93,6 +110,13 @@ public final class ColorGradientFormatting implements Cloneable {
|
||||
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();
|
||||
@ -102,6 +126,9 @@ public final class ColorGradientFormatting implements Cloneable {
|
||||
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();
|
||||
}
|
||||
@ -109,9 +136,10 @@ public final class ColorGradientFormatting implements Cloneable {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -119,9 +147,11 @@ public final class ColorGradientFormatting implements Cloneable {
|
||||
int len = 6;
|
||||
for (Threshold t : thresholds) {
|
||||
len += t.getDataLength();
|
||||
}
|
||||
for (ExtendedColor c : colors) {
|
||||
len += c.getDataLength();
|
||||
len += 8;
|
||||
}
|
||||
len += colors.length;
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -132,13 +162,16 @@ public final class ColorGradientFormatting implements Cloneable {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,63 @@
|
||||
/* ====================================================================
|
||||
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);
|
||||
}
|
||||
}
|
@ -56,7 +56,7 @@ public final class IconMultiStateFormatting implements Cloneable {
|
||||
|
||||
thresholds = new Threshold[iconSet.num];
|
||||
for (int i=0; i<thresholds.length; i++) {
|
||||
thresholds[i] = new Threshold(in);
|
||||
thresholds[i] = new IconMultiStateThreshold(in);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,75 @@
|
||||
/* ====================================================================
|
||||
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
|
||||
}
|
||||
}
|
@ -26,31 +26,21 @@ import org.apache.poi.util.LittleEndianInput;
|
||||
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) {
|
||||
@ -63,9 +53,6 @@ public final class Threshold {
|
||||
type != RangeType.MAX.id) {
|
||||
value = in.readDouble();
|
||||
}
|
||||
equals = in.readByte();
|
||||
// Reserved, 4 bytes, all 0
|
||||
in.readInt();
|
||||
}
|
||||
|
||||
public byte getType() {
|
||||
@ -74,7 +61,7 @@ public final class Threshold {
|
||||
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;
|
||||
@ -106,19 +93,11 @@ public final class Threshold {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -132,13 +111,10 @@ public final class Threshold {
|
||||
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) {
|
||||
@ -151,7 +127,5 @@ public final class Threshold {
|
||||
if (value != null) {
|
||||
out.writeDouble(value);
|
||||
}
|
||||
out.writeByte(equals);
|
||||
out.writeInt(0); // Reserved
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ package org.apache.poi.hssf.usermodel;
|
||||
|
||||
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;
|
||||
@ -62,14 +63,15 @@ public final class HSSFColorScaleFormatting implements org.apache.poi.ss.usermod
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user