257 lines
7.6 KiB
Java
257 lines
7.6 KiB
Java
package jxl.biff;
|
|
|
|
import common.Assert;
|
|
import common.Logger;
|
|
import java.io.IOException;
|
|
import java.text.DateFormat;
|
|
import java.text.NumberFormat;
|
|
import java.util.ArrayList;
|
|
import java.util.HashMap;
|
|
import java.util.Iterator;
|
|
import jxl.format.Colour;
|
|
import jxl.format.RGB;
|
|
import jxl.write.biff.File;
|
|
|
|
public class FormattingRecords {
|
|
private static Logger logger = Logger.getLogger(FormattingRecords.class);
|
|
|
|
private HashMap formats;
|
|
|
|
private ArrayList formatsList;
|
|
|
|
private ArrayList xfRecords;
|
|
|
|
private int nextCustomIndexNumber;
|
|
|
|
private Fonts fonts;
|
|
|
|
private PaletteRecord palette;
|
|
|
|
private static final int customFormatStartIndex = 164;
|
|
|
|
private static final int maxFormatRecordsIndex = 441;
|
|
|
|
private static final int minXFRecords = 21;
|
|
|
|
public FormattingRecords(Fonts f) {
|
|
this.xfRecords = new ArrayList(10);
|
|
this.formats = new HashMap(10);
|
|
this.formatsList = new ArrayList(10);
|
|
this.fonts = f;
|
|
this.nextCustomIndexNumber = 164;
|
|
}
|
|
|
|
public final void addStyle(XFRecord xf) throws NumFormatRecordsException {
|
|
if (!xf.isInitialized()) {
|
|
int pos = this.xfRecords.size();
|
|
xf.initialize(pos, this, this.fonts);
|
|
this.xfRecords.add(xf);
|
|
} else if (xf.getXFIndex() >= this.xfRecords.size()) {
|
|
this.xfRecords.add(xf);
|
|
}
|
|
}
|
|
|
|
public final void addFormat(DisplayFormat fr) throws NumFormatRecordsException {
|
|
if (fr.isInitialized() && fr.getFormatIndex() >= 441) {
|
|
logger.warn("Format index exceeds Excel maximum - assigning custom number");
|
|
fr.initialize(this.nextCustomIndexNumber);
|
|
this.nextCustomIndexNumber++;
|
|
}
|
|
if (!fr.isInitialized()) {
|
|
fr.initialize(this.nextCustomIndexNumber);
|
|
this.nextCustomIndexNumber++;
|
|
}
|
|
if (this.nextCustomIndexNumber > 441) {
|
|
this.nextCustomIndexNumber = 441;
|
|
throw new NumFormatRecordsException();
|
|
}
|
|
if (fr.getFormatIndex() >= this.nextCustomIndexNumber)
|
|
this.nextCustomIndexNumber = fr.getFormatIndex() + 1;
|
|
if (!fr.isBuiltIn()) {
|
|
this.formatsList.add(fr);
|
|
this.formats.put(new Integer(fr.getFormatIndex()), fr);
|
|
}
|
|
}
|
|
|
|
public final boolean isDate(int pos) {
|
|
XFRecord xfr = this.xfRecords.get(pos);
|
|
if (xfr.isDate())
|
|
return true;
|
|
FormatRecord fr = (FormatRecord)this.formats.get(new Integer(xfr.getFormatRecord()));
|
|
return (fr == null) ? false : fr.isDate();
|
|
}
|
|
|
|
public final DateFormat getDateFormat(int pos) {
|
|
XFRecord xfr = this.xfRecords.get(pos);
|
|
if (xfr.isDate())
|
|
return xfr.getDateFormat();
|
|
FormatRecord fr = (FormatRecord)this.formats.get(new Integer(xfr.getFormatRecord()));
|
|
if (fr == null)
|
|
return null;
|
|
return fr.isDate() ? fr.getDateFormat() : null;
|
|
}
|
|
|
|
public final NumberFormat getNumberFormat(int pos) {
|
|
XFRecord xfr = this.xfRecords.get(pos);
|
|
if (xfr.isNumber())
|
|
return xfr.getNumberFormat();
|
|
FormatRecord fr = (FormatRecord)this.formats.get(new Integer(xfr.getFormatRecord()));
|
|
if (fr == null)
|
|
return null;
|
|
return fr.isNumber() ? fr.getNumberFormat() : null;
|
|
}
|
|
|
|
FormatRecord getFormatRecord(int index) {
|
|
return (FormatRecord)this.formats.get(new Integer(index));
|
|
}
|
|
|
|
public void write(File outputFile) throws IOException {
|
|
Iterator i = this.formatsList.iterator();
|
|
FormatRecord fr = null;
|
|
while (i.hasNext()) {
|
|
fr = i.next();
|
|
outputFile.write(fr);
|
|
}
|
|
i = this.xfRecords.iterator();
|
|
XFRecord xfr = null;
|
|
while (i.hasNext()) {
|
|
xfr = (XFRecord)i.next();
|
|
outputFile.write(xfr);
|
|
}
|
|
BuiltInStyle style = new BuiltInStyle(16, 3);
|
|
outputFile.write(style);
|
|
style = new BuiltInStyle(17, 6);
|
|
outputFile.write(style);
|
|
style = new BuiltInStyle(18, 4);
|
|
outputFile.write(style);
|
|
style = new BuiltInStyle(19, 7);
|
|
outputFile.write(style);
|
|
style = new BuiltInStyle(0, 0);
|
|
outputFile.write(style);
|
|
style = new BuiltInStyle(20, 5);
|
|
outputFile.write(style);
|
|
}
|
|
|
|
protected final Fonts getFonts() {
|
|
return this.fonts;
|
|
}
|
|
|
|
public final XFRecord getXFRecord(int index) {
|
|
return this.xfRecords.get(index);
|
|
}
|
|
|
|
protected final int getNumberOfFormatRecords() {
|
|
return this.formatsList.size();
|
|
}
|
|
|
|
public IndexMapping rationalizeFonts() {
|
|
return this.fonts.rationalize();
|
|
}
|
|
|
|
public IndexMapping rationalize(IndexMapping fontMapping, IndexMapping formatMapping) {
|
|
XFRecord xfr = null;
|
|
for (Iterator it = this.xfRecords.iterator(); it.hasNext(); ) {
|
|
xfr = it.next();
|
|
if (xfr.getFormatRecord() >= 164)
|
|
xfr.setFormatIndex(formatMapping.getNewIndex(xfr.getFormatRecord()));
|
|
xfr.setFontIndex(fontMapping.getNewIndex(xfr.getFontIndex()));
|
|
}
|
|
ArrayList newrecords = new ArrayList(21);
|
|
IndexMapping mapping = new IndexMapping(this.xfRecords.size());
|
|
int numremoved = 0;
|
|
int numXFRecords = Math.min(21, this.xfRecords.size());
|
|
int j;
|
|
for (j = 0; j < numXFRecords; j++) {
|
|
newrecords.add(this.xfRecords.get(j));
|
|
mapping.setMapping(j, j);
|
|
}
|
|
if (numXFRecords < 21) {
|
|
logger.warn("There are less than the expected minimum number of XF records");
|
|
return mapping;
|
|
}
|
|
for (j = 21; j < this.xfRecords.size(); j++) {
|
|
XFRecord xf = this.xfRecords.get(j);
|
|
boolean duplicate = false;
|
|
Iterator iterator = newrecords.iterator();
|
|
while (iterator.hasNext() && !duplicate) {
|
|
XFRecord xf2 = iterator.next();
|
|
if (xf2.equals(xf)) {
|
|
duplicate = true;
|
|
mapping.setMapping(j, mapping.getNewIndex(xf2.getXFIndex()));
|
|
numremoved++;
|
|
}
|
|
}
|
|
if (!duplicate) {
|
|
newrecords.add(xf);
|
|
mapping.setMapping(j, j - numremoved);
|
|
}
|
|
}
|
|
for (Iterator i = this.xfRecords.iterator(); i.hasNext(); ) {
|
|
XFRecord xf = i.next();
|
|
xf.rationalize(mapping);
|
|
}
|
|
this.xfRecords = newrecords;
|
|
return mapping;
|
|
}
|
|
|
|
public IndexMapping rationalizeDisplayFormats() {
|
|
ArrayList newformats = new ArrayList();
|
|
int numremoved = 0;
|
|
IndexMapping mapping = new IndexMapping(this.nextCustomIndexNumber);
|
|
Iterator i = this.formatsList.iterator();
|
|
DisplayFormat df = null;
|
|
DisplayFormat df2 = null;
|
|
boolean duplicate = false;
|
|
while (i.hasNext()) {
|
|
df = i.next();
|
|
Assert.verify(!df.isBuiltIn());
|
|
Iterator i2 = newformats.iterator();
|
|
duplicate = false;
|
|
while (i2.hasNext() && !duplicate) {
|
|
df2 = i2.next();
|
|
if (df2.equals(df)) {
|
|
duplicate = true;
|
|
mapping.setMapping(df.getFormatIndex(), mapping.getNewIndex(df2.getFormatIndex()));
|
|
numremoved++;
|
|
}
|
|
}
|
|
if (!duplicate) {
|
|
newformats.add(df);
|
|
int indexnum = df.getFormatIndex() - numremoved;
|
|
if (indexnum > 441) {
|
|
logger.warn("Too many number formats - using default format.");
|
|
indexnum = 0;
|
|
}
|
|
mapping.setMapping(df.getFormatIndex(), df.getFormatIndex() - numremoved);
|
|
}
|
|
}
|
|
this.formatsList = newformats;
|
|
i = this.formatsList.iterator();
|
|
while (i.hasNext()) {
|
|
df = i.next();
|
|
df.initialize(mapping.getNewIndex(df.getFormatIndex()));
|
|
}
|
|
return mapping;
|
|
}
|
|
|
|
public PaletteRecord getPalette() {
|
|
return this.palette;
|
|
}
|
|
|
|
public void setPalette(PaletteRecord pr) {
|
|
this.palette = pr;
|
|
}
|
|
|
|
public void setColourRGB(Colour c, int r, int g, int b) {
|
|
if (this.palette == null)
|
|
this.palette = new PaletteRecord();
|
|
this.palette.setColourRGB(c, r, g, b);
|
|
}
|
|
|
|
public RGB getColourRGB(Colour c) {
|
|
if (this.palette == null)
|
|
return c.getDefaultRGB();
|
|
return this.palette.getColourRGB(c);
|
|
}
|
|
}
|