/********************************************************************* * * Copyright (C) 2004 Andrew Khan, Eric Jung * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ***************************************************************************/ package jxl.biff; import common.Logger; /** * Class which represents an Excel header or footer. Information for this * class came from Microsoft Knowledge Base Article 142136 * (previously Q142136). * * This class encapsulates three internal structures representing the header * or footer contents which appear on the left, right or central part of the * page */ public abstract class HeaderFooter { /** * The logger */ private static Logger logger = Logger.getLogger(HeaderFooter.class); // Codes to format text /** * Turns bold printing on or off */ private static final String BOLD_TOGGLE = "&B"; /** * Turns underline printing on or off */ private static final String UNDERLINE_TOGGLE = "&U"; /** * Turns italic printing on or off */ private static final String ITALICS_TOGGLE = "&I"; /** * Turns strikethrough printing on or off */ private static final String STRIKETHROUGH_TOGGLE = "&S"; /** * Turns double-underline printing on or off */ private static final String DOUBLE_UNDERLINE_TOGGLE = "&E"; /** * Turns superscript printing on or off */ private static final String SUPERSCRIPT_TOGGLE = "&X"; /** * Turns subscript printing on or off */ private static final String SUBSCRIPT_TOGGLE = "&Y"; /** * Turns outline printing on or off (Macintosh only) */ private static final String OUTLINE_TOGGLE = "&O"; /** * Turns shadow printing on or off (Macintosh only) */ private static final String SHADOW_TOGGLE = "&H"; /** * Left-aligns the characters that follow */ private static final String LEFT_ALIGN = "&L"; /** * Centres the characters that follow */ private static final String CENTRE = "&C"; /** * Right-aligns the characters that follow */ private static final String RIGHT_ALIGN = "&R"; // Codes to insert specific data /** * Prints the page number */ private static final String PAGENUM = "&P"; /** * Prints the total number of pages in the document */ private static final String TOTAL_PAGENUM = "&N"; /** * Prints the current date */ private static final String DATE = "&D"; /** * Prints the current time */ private static final String TIME = "&T"; /** * Prints the name of the workbook */ private static final String WORKBOOK_NAME = "&F"; /** * Prints the name of the worksheet */ private static final String WORKSHEET_NAME = "&A"; /** * The contents - a simple wrapper around a string buffer */ protected static class Contents { /** * The buffer containing the header/footer string */ private StringBuffer contents; /** * The constructor */ protected Contents() { contents = new StringBuffer(); } /** * Constructor used when reading worksheets. The string contains all * the formatting (but not alignment characters * * @param s the format string */ protected Contents(String s) { contents = new StringBuffer(s); } /** * Copy constructor * * @param copy the contents to copy */ protected Contents(Contents copy) { contents = new StringBuffer(copy.getContents()); } /** * Retrieves a Stringified * version of this object * * @return the header string */ protected String getContents() { return contents != null ? contents.toString() : ""; } /** * Internal method which appends the text to the string buffer * * @param txt */ private void appendInternal(String txt) { if (contents == null) { contents = new StringBuffer(); } contents.append(txt); } /** * Internal method which appends the text to the string buffer * * @param ch */ private void appendInternal(char ch) { if (contents == null) { contents = new StringBuffer(); } contents.append(ch); } /** * Appends the text to the string buffer * * @param txt */ protected void append(String txt) { appendInternal(txt); } /** * Turns bold printing on or off. Bold printing * is initially off. Text subsequently appended to * this object will be bolded until this method is * called again. */ protected void toggleBold() { appendInternal(BOLD_TOGGLE); } /** * Turns underline printing on or off. Underline printing * is initially off. Text subsequently appended to * this object will be underlined until this method is * called again. */ protected void toggleUnderline() { appendInternal(UNDERLINE_TOGGLE); } /** * Turns italics printing on or off. Italics printing * is initially off. Text subsequently appended to * this object will be italicized until this method is * called again. */ protected void toggleItalics() { appendInternal(ITALICS_TOGGLE); } /** * Turns strikethrough printing on or off. Strikethrough printing * is initially off. Text subsequently appended to * this object will be striked out until this method is * called again. */ protected void toggleStrikethrough() { appendInternal(STRIKETHROUGH_TOGGLE); } /** * Turns double-underline printing on or off. Double-underline printing * is initially off. Text subsequently appended to * this object will be double-underlined until this method is * called again. */ protected void toggleDoubleUnderline() { appendInternal(DOUBLE_UNDERLINE_TOGGLE); } /** * Turns superscript printing on or off. Superscript printing * is initially off. Text subsequently appended to * this object will be superscripted until this method is * called again. */ protected void toggleSuperScript() { appendInternal(SUPERSCRIPT_TOGGLE); } /** * Turns subscript printing on or off. Subscript printing * is initially off. Text subsequently appended to * this object will be subscripted until this method is * called again. */ protected void toggleSubScript() { appendInternal(SUBSCRIPT_TOGGLE); } /** * Turns outline printing on or off (Macintosh only). * Outline printing is initially off. Text subsequently appended * to this object will be outlined until this method is * called again. */ protected void toggleOutline() { appendInternal(OUTLINE_TOGGLE); } /** * Turns shadow printing on or off (Macintosh only). * Shadow printing is initially off. Text subsequently appended * to this object will be shadowed until this method is * called again. */ protected void toggleShadow() { appendInternal(SHADOW_TOGGLE); } /** * Sets the font of text subsequently appended to this * object.. Previously appended text is not affected. *

* Note: no checking is performed to * determine if fontName is a valid font. * * @param fontName name of the font to use */ protected void setFontName(String fontName) { // Font name must be in quotations appendInternal("&\""); appendInternal(fontName); appendInternal('\"'); } /** * Sets the font size of text subsequently appended to this * object. Previously appended text is not affected. *

* Valid point sizes are between 1 and 99 (inclusive). If * size is outside this range, this method returns false * and does not change font size. If size is within this * range, the font size is changed and true is returned. * * @param size The size in points. Valid point sizes are * between 1 and 99 (inclusive). * @return true if the font size was changed, false if font * size was not changed because 1 > size > 99. */ protected boolean setFontSize(int size) { if (size < 1 || size > 99) { return false; } // A two digit number should be used -- even if the // leading number is just a zero. String fontSize; if (size < 10) { // single-digit -- make two digit fontSize = "0" + size; } else { fontSize = Integer.toString(size); } appendInternal('&'); appendInternal(fontSize); return true; } /** * Appends the page number */ protected void appendPageNumber() { appendInternal(PAGENUM); } /** * Appends the total number of pages */ protected void appendTotalPages() { appendInternal(TOTAL_PAGENUM); } /** * Appends the current date */ protected void appendDate() { appendInternal(DATE); } /** * Appends the current time */ protected void appendTime() { appendInternal(TIME); } /** * Appends the workbook name */ protected void appendWorkbookName() { appendInternal(WORKBOOK_NAME); } /** * Appends the worksheet name */ protected void appendWorkSheetName() { appendInternal(WORKSHEET_NAME); } /** * Clears the contents of this portion */ protected void clear() { contents = null; } /** * Queries if the contents are empty * * @return TRUE if the contents are empty, FALSE otherwise */ protected boolean empty() { if (contents == null || contents.length() == 0) { return true; } else { return false; } } } /** * The left aligned header/footer contents */ private Contents left; /** * The right aligned header/footer contents */ private Contents right; /** * The centrally aligned header/footer contents */ private Contents centre; /** * Default constructor. */ protected HeaderFooter() { left = createContents(); right = createContents(); centre = createContents(); } /** * Copy constructor * * @param c the item to copy */ protected HeaderFooter(HeaderFooter hf) { left = createContents(hf.left); right = createContents(hf.right); centre = createContents(hf.centre); } /** * Constructor used when reading workbooks to separate the left, right * a central part of the strings into their constituent parts */ protected HeaderFooter(String s) { if (s == null || s.length() == 0) { left = createContents(); right = createContents(); centre = createContents(); return; } int pos = 0; int leftPos = s.indexOf(LEFT_ALIGN); int rightPos = s.indexOf(RIGHT_ALIGN); int centrePos = s.indexOf(CENTRE); // Do the left position string if (pos == leftPos) { if (centrePos != -1) { left = createContents(s.substring(pos + 2, centrePos)); pos = centrePos; } else if (rightPos != -1 ) { left = createContents(s.substring(pos + 2, rightPos)); pos = rightPos; } else { left = createContents(s.substring(pos + 2)); pos = s.length(); } } // Do the centrally positioned part of the string. This is the default // if no alignment string is specified if (pos == centrePos || (leftPos == -1 && rightPos == -1 && centrePos == -1)) { if (rightPos != -1) { centre = createContents(s.substring(pos + 2, rightPos)); pos = rightPos; } else { int cpos = (pos == centrePos) ? pos + 2 : pos; centre = createContents(s.substring(cpos)); pos = s.length(); } } // Do the right positioned part of the string if (pos == rightPos) { right = createContents(s.substring(pos + 2)); pos = s.length(); } if (left == null) { left = createContents(); } if (centre == null) { centre = createContents(); } if (right == null) { right = createContents(); } } /** * Retrieves a Stringified * version of this object * * @return the header string */ public String toString() { StringBuffer hf = new StringBuffer(); if (!left.empty()) { hf.append(LEFT_ALIGN); hf.append(left.getContents()); } if (!centre.empty()) { hf.append(CENTRE); hf.append(centre.getContents()); } if (!right.empty()) { hf.append(RIGHT_ALIGN); hf.append(right.getContents()); } return hf.toString(); } /** * Accessor for the contents which appear on the right hand side of the page * * @return the right aligned contents */ protected Contents getRightText() { return right; } /** * Accessor for the contents which in the centre of the page * * @return the centrally aligned contents */ protected Contents getCentreText() { return centre; } /** * Accessor for the contents which appear on the left hand side of the page * * @return the left aligned contents */ protected Contents getLeftText() { return left; } /** * Clears the contents of the header/footer */ protected void clear() { left.clear(); right.clear(); centre.clear(); } /** * Creates internal class of the appropriate type */ protected abstract Contents createContents(); /** * Creates internal class of the appropriate type */ protected abstract Contents createContents(String s); /** * Creates internal class of the appropriate type */ protected abstract Contents createContents(Contents c); }