| /* ==================================================================== |
| 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; |
| |
| |
| /** |
| * Common class for {@link HSSFHeader} and {@link HSSFFooter}. |
| */ |
| public abstract class HeaderFooter implements org.apache.poi.ss.usermodel.HeaderFooter { |
| |
| protected HeaderFooter() { |
| // |
| } |
| |
| /** |
| * @return the internal text representation (combining center, left and right parts). |
| * Possibly empty string if no header or footer is set. Never <code>null</code>. |
| */ |
| protected abstract String getRawText(); |
| |
| private String[] splitParts() { |
| String text = getRawText(); |
| // default values |
| String _left = ""; |
| String _center = ""; |
| String _right = ""; |
| |
| // FIXME: replace outer goto. just eww. |
| outer: |
| while (text.length() > 1) { |
| if (text.charAt(0) != '&') { |
| // Mimics the behaviour of Excel, which would put it in the center. |
| _center = text; |
| break; |
| } |
| int pos = text.length(); |
| switch (text.charAt(1)) { |
| case 'L': |
| if (text.contains("&C")) { |
| pos = Math.min(pos, text.indexOf("&C")); |
| } |
| if (text.contains("&R")) { |
| pos = Math.min(pos, text.indexOf("&R")); |
| } |
| _left = text.substring(2, pos); |
| text = text.substring(pos); |
| break; |
| case 'C': |
| if (text.contains("&L")) { |
| pos = Math.min(pos, text.indexOf("&L")); |
| } |
| if (text.contains("&R")) { |
| pos = Math.min(pos, text.indexOf("&R")); |
| } |
| _center = text.substring(2, pos); |
| text = text.substring(pos); |
| break; |
| case 'R': |
| if (text.contains("&C")) { |
| pos = Math.min(pos, text.indexOf("&C")); |
| } |
| if (text.contains("&L")) { |
| pos = Math.min(pos, text.indexOf("&L")); |
| } |
| _right = text.substring(2, pos); |
| text = text.substring(pos); |
| break; |
| default: |
| // Mimics the behaviour of Excel, which would put it in the center. |
| _center = text; |
| break outer; |
| } |
| } |
| return new String[] { _left, _center, _right, }; |
| } |
| |
| /** |
| * @return the left side of the header or footer. |
| */ |
| public final String getLeft() { |
| return splitParts()[0]; |
| } |
| |
| /** |
| * @param newLeft The string to set as the left side. |
| */ |
| public final void setLeft(String newLeft) { |
| updatePart(0, newLeft); |
| } |
| |
| /** |
| * @return the center of the header or footer. |
| */ |
| public final String getCenter() { |
| return splitParts()[1]; |
| } |
| |
| /** |
| * @param newCenter The string to set as the center. |
| */ |
| public final void setCenter(String newCenter) { |
| updatePart(1, newCenter); |
| } |
| |
| /** |
| * @return The right side of the header or footer. |
| */ |
| public final String getRight() { |
| return splitParts()[2]; |
| } |
| |
| /** |
| * @param newRight The string to set as the right side. |
| */ |
| public final void setRight(String newRight) { |
| updatePart(2, newRight); |
| } |
| |
| private void updatePart(int partIndex, String newValue) { |
| String[] parts = splitParts(); |
| parts[partIndex] = newValue == null ? "" : newValue; |
| updateHeaderFooterText(parts); |
| } |
| /** |
| * Creates the complete footer string based on the left, center, and middle |
| * strings. |
| */ |
| private void updateHeaderFooterText(String[] parts) { |
| String _left = parts[0]; |
| String _center = parts[1]; |
| String _right = parts[2]; |
| |
| if (_center.length() < 1 && _left.length() < 1 && _right.length() < 1) { |
| setHeaderFooterText(""); |
| return; |
| } |
| StringBuilder sb = new StringBuilder(64); |
| sb.append("&C"); |
| sb.append(_center); |
| sb.append("&L"); |
| sb.append(_left); |
| sb.append("&R"); |
| sb.append(_right); |
| String text = sb.toString(); |
| setHeaderFooterText(text); |
| } |
| |
| /** |
| * @param text the new header footer text (contains mark-up tags). Possibly |
| * empty string never <code>null</code> |
| */ |
| protected abstract void setHeaderFooterText(String text); |
| |
| /** |
| * @param size |
| * the new font size |
| * @return The mark-up tag representing a new font size |
| */ |
| public static String fontSize(short size) { |
| return "&" + size; |
| } |
| |
| /** |
| * @param font |
| * the new font |
| * @param style |
| * the fonts style, one of regular, italic, bold, italic bold or |
| * bold italic |
| * @return The mark-up tag representing a new font size |
| */ |
| public static String font(String font, String style) { |
| return "&\"" + font + "," + style + "\""; |
| } |
| |
| /** |
| * @return The mark-up tag representing the current page number |
| */ |
| public static String page() { |
| return MarkupTag.PAGE_FIELD.getRepresentation(); |
| } |
| |
| /** |
| * @return The mark-up tag representing the number of pages |
| */ |
| public static String numPages() { |
| return MarkupTag.NUM_PAGES_FIELD.getRepresentation(); |
| } |
| |
| /** |
| * @return The mark-up tag representing the current date date |
| */ |
| public static String date() { |
| return MarkupTag.DATE_FIELD.getRepresentation(); |
| } |
| |
| /** |
| * @return The mark-up tag representing current time |
| */ |
| public static String time() { |
| return MarkupTag.TIME_FIELD.getRepresentation(); |
| } |
| |
| /** |
| * @return The mark-up tag representing the current file name |
| */ |
| public static String file() { |
| return MarkupTag.FILE_FIELD.getRepresentation(); |
| } |
| |
| /** |
| * @return The mark-up tag representing the current tab (sheet) name |
| */ |
| public static String tab() { |
| return MarkupTag.SHEET_NAME_FIELD.getRepresentation(); |
| } |
| |
| /** |
| * @return The mark-up tag for start bold |
| */ |
| public static String startBold() { |
| return MarkupTag.BOLD_FIELD.getRepresentation(); |
| } |
| |
| /** |
| * @return The mark-up tag for end bold |
| */ |
| public static String endBold() { |
| return MarkupTag.BOLD_FIELD.getRepresentation(); |
| } |
| |
| /** |
| * @return The mark-up tag for start underline |
| */ |
| public static String startUnderline() { |
| return MarkupTag.UNDERLINE_FIELD.getRepresentation(); |
| } |
| |
| /** |
| * @return The mark-up tag for end underline |
| */ |
| public static String endUnderline() { |
| return MarkupTag.UNDERLINE_FIELD.getRepresentation(); |
| } |
| |
| /** |
| * @return The mark-up tag for start double underline |
| */ |
| public static String startDoubleUnderline() { |
| return MarkupTag.DOUBLE_UNDERLINE_FIELD.getRepresentation(); |
| } |
| |
| /** |
| * @return The mark-up tag for end double underline |
| */ |
| public static String endDoubleUnderline() { |
| return MarkupTag.DOUBLE_UNDERLINE_FIELD.getRepresentation(); |
| } |
| |
| /** |
| * Removes any fields (eg macros, page markers etc) from the string. |
| * Normally used to make some text suitable for showing to humans, and the |
| * resultant text should not normally be saved back into the document! |
| */ |
| public static String stripFields(String pText) { |
| int pos; |
| |
| // Check we really got something to work on |
| if (pText == null || pText.length() == 0) { |
| return pText; |
| } |
| |
| String text = pText; |
| |
| // Firstly, do the easy ones which are static |
| for (MarkupTag mt : MarkupTag.values()) { |
| String seq = mt.getRepresentation(); |
| while ((pos = text.indexOf(seq)) >= 0) { |
| text = text.substring(0, pos) + text.substring(pos + seq.length()); |
| } |
| } |
| |
| // Now do the tricky, dynamic ones |
| // These are things like font sizes and font names |
| text = text.replaceAll("\\&\\d+", ""); |
| text = text.replaceAll("\\&\".*?,.*?\"", ""); |
| |
| // All done |
| return text; |
| } |
| |
| private enum MarkupTag { |
| SHEET_NAME_FIELD ("&A", false), |
| DATE_FIELD ("&D", false), |
| FILE_FIELD ("&F", false), |
| FULL_FILE_FIELD ("&Z", false), |
| PAGE_FIELD ("&P", false), |
| TIME_FIELD ("&T", false), |
| NUM_PAGES_FIELD ("&N", false), |
| |
| PICTURE_FIELD ("&G", false), |
| |
| BOLD_FIELD ("&B", true), |
| ITALIC_FIELD ("&I", true), |
| STRIKETHROUGH_FIELD ("&S", true), |
| SUBSCRIPT_FIELD ("&Y", true), |
| SUPERSCRIPT_FIELD ("&X", true), |
| UNDERLINE_FIELD ("&U", true), |
| DOUBLE_UNDERLINE_FIELD ("&E", true), |
| ; |
| |
| private final String _representation; |
| private final boolean _occursInPairs; |
| private MarkupTag(String sequence, boolean occursInPairs) { |
| _representation = sequence; |
| _occursInPairs = occursInPairs; |
| } |
| /** |
| * @return The character sequence that marks this field |
| */ |
| public String getRepresentation() { |
| return _representation; |
| } |
| |
| /** |
| * @return true if this markup tag normally comes in a pair, eg turn on |
| * underline / turn off underline |
| */ |
| public boolean occursPairs() { |
| return _occursInPairs; |
| } |
| } |
| } |