001: /* ====================================================================
002: Licensed to the Apache Software Foundation (ASF) under one or more
003: contributor license agreements. See the NOTICE file distributed with
004: this work for additional information regarding copyright ownership.
005: The ASF licenses this file to You under the Apache License, Version 2.0
006: (the "License"); you may not use this file except in compliance with
007: the License. You may obtain a copy of the License at
008:
009: http://www.apache.org/licenses/LICENSE-2.0
010:
011: Unless required by applicable law or agreed to in writing, software
012: distributed under the License is distributed on an "AS IS" BASIS,
013: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: See the License for the specific language governing permissions and
015: limitations under the License.
016: ==================================================================== */
017:
018: package org.apache.poi.hssf.usermodel;
019:
020: import org.apache.poi.hssf.model.Workbook;
021: import org.apache.poi.hssf.record.LabelSSTRecord;
022: import org.apache.poi.hssf.record.UnicodeString;
023:
024: import java.util.Iterator;
025:
026: /**
027: * Rich text unicode string. These strings can have fonts applied to
028: * arbitary parts of the string.
029: *
030: * @author Glen Stampoultzis (glens at apache.org)
031: * @author Jason Height (jheight at apache.org)
032: */
033: public class HSSFRichTextString implements Comparable {
034: /** Place holder for indicating that NO_FONT has been applied here */
035: public static final short NO_FONT = 0;
036:
037: private UnicodeString string;
038: private Workbook book;
039: private LabelSSTRecord record;
040:
041: public HSSFRichTextString() {
042: this ("");
043: }
044:
045: public HSSFRichTextString(String string) {
046: if (string == null)
047: string = "";
048: this .string = new UnicodeString(string);
049: }
050:
051: HSSFRichTextString(Workbook book, LabelSSTRecord record) {
052: setWorkbookReferences(book, record);
053:
054: this .string = book.getSSTString(record.getSSTIndex());
055: }
056:
057: /** This must be called to setup the internal work book references whenever
058: * a RichTextString is added to a cell
059: */
060: void setWorkbookReferences(Workbook book, LabelSSTRecord record) {
061: this .book = book;
062: this .record = record;
063: }
064:
065: /** Called whenever the unicode string is modified. When it is modified
066: * we need to create a new SST index, so that other LabelSSTRecords will not
067: * be affected by changes tat we make to this string.
068: */
069: private UnicodeString cloneStringIfRequired() {
070: if (book == null)
071: return string;
072: UnicodeString s = (UnicodeString) string.clone();
073: return s;
074: }
075:
076: private void addToSSTIfRequired() {
077: if (book != null) {
078: int index = book.addSSTString(string);
079: record.setSSTIndex(index);
080: //The act of adding the string to the SST record may have meant that
081: //a extsing string was returned for the index, so update our local version
082: string = book.getSSTString(index);
083: }
084: }
085:
086: /**
087: * Applies a font to the specified characters of a string.
088: *
089: * @param startIndex The start index to apply the font to (inclusive)
090: * @param endIndex The end index to apply the font to (exclusive)
091: * @param fontIndex The font to use.
092: */
093: public void applyFont(int startIndex, int endIndex, short fontIndex) {
094: if (startIndex > endIndex)
095: throw new IllegalArgumentException(
096: "Start index must be less than end index.");
097: if (startIndex < 0 || endIndex > length())
098: throw new IllegalArgumentException(
099: "Start and end index not in range.");
100: if (startIndex == endIndex)
101: return;
102:
103: //Need to check what the font is currently, so we can reapply it after
104: //the range is completed
105: short currentFont = NO_FONT;
106: if (endIndex != length()) {
107: currentFont = this .getFontAtIndex(startIndex);
108: }
109:
110: //Need to clear the current formatting between the startIndex and endIndex
111: string = cloneStringIfRequired();
112: Iterator formatting = string.formatIterator();
113: if (formatting != null) {
114: while (formatting.hasNext()) {
115: UnicodeString.FormatRun r = (UnicodeString.FormatRun) formatting
116: .next();
117: if ((r.getCharacterPos() >= startIndex)
118: && (r.getCharacterPos() < endIndex))
119: formatting.remove();
120: }
121: }
122:
123: string.addFormatRun(new UnicodeString.FormatRun(
124: (short) startIndex, fontIndex));
125: if (endIndex != length())
126: string.addFormatRun(new UnicodeString.FormatRun(
127: (short) endIndex, currentFont));
128:
129: addToSSTIfRequired();
130: }
131:
132: /**
133: * Applies a font to the specified characters of a string.
134: *
135: * @param startIndex The start index to apply the font to (inclusive)
136: * @param endIndex The end index to apply to font to (exclusive)
137: * @param font The index of the font to use.
138: */
139: public void applyFont(int startIndex, int endIndex, HSSFFont font) {
140: applyFont(startIndex, endIndex, font.getIndex());
141: }
142:
143: /**
144: * Sets the font of the entire string.
145: * @param font The font to use.
146: */
147: public void applyFont(HSSFFont font) {
148: applyFont(0, string.getCharCount(), font);
149: }
150:
151: /**
152: * Removes any formatting that may have been applied to the string.
153: */
154: public void clearFormatting() {
155: string = cloneStringIfRequired();
156: string.clearFormatting();
157: addToSSTIfRequired();
158: }
159:
160: /**
161: * Returns the plain string representation.
162: */
163: public String getString() {
164: return string.getString();
165: }
166:
167: /** Used internally by the HSSFCell to get the internal string value*/
168: UnicodeString getUnicodeString() {
169: return cloneStringIfRequired();
170: }
171:
172: /** Used internally by the HSSFCell to set the internal string value*/
173: void setUnicodeString(UnicodeString str) {
174: this .string = str;
175: }
176:
177: /**
178: * @return the number of characters in the font.
179: */
180: public int length() {
181: return string.getCharCount();
182: }
183:
184: /**
185: * Returns the font in use at a particular index.
186: *
187: * @param index The index.
188: * @return The font that's currently being applied at that
189: * index or null if no font is being applied or the
190: * index is out of range.
191: */
192: public short getFontAtIndex(int index) {
193: int size = string.getFormatRunCount();
194: UnicodeString.FormatRun currentRun = null;
195: for (int i = 0; i < size; i++) {
196: UnicodeString.FormatRun r = string.getFormatRun(i);
197: if (r.getCharacterPos() > index)
198: break;
199: else
200: currentRun = r;
201: }
202: if (currentRun == null)
203: return NO_FONT;
204: else
205: return currentRun.getFontIndex();
206: }
207:
208: /**
209: * @return The number of formatting runs used. There will always be at
210: * least one of font NO_FONT.
211: *
212: * @see #NO_FONT
213: */
214: public int numFormattingRuns() {
215: return string.getFormatRunCount();
216: }
217:
218: /**
219: * The index within the string to which the specified formatting run applies.
220: * @param index the index of the formatting run
221: * @return the index within the string.
222: */
223: public int getIndexOfFormattingRun(int index) {
224: UnicodeString.FormatRun r = string.getFormatRun(index);
225: return r.getCharacterPos();
226: }
227:
228: /**
229: * Gets the font used in a particular formatting run.
230: *
231: * @param index the index of the formatting run
232: * @return the font number used.
233: */
234: public short getFontOfFormattingRun(int index) {
235: UnicodeString.FormatRun r = string.getFormatRun(index);
236: return r.getFontIndex();
237: }
238:
239: /**
240: * Compares one rich text string to another.
241: */
242: public int compareTo(Object o) {
243: HSSFRichTextString r = (HSSFRichTextString) o;
244: return string.compareTo(r.string);
245: }
246:
247: public boolean equals(Object o) {
248: if (o instanceof HSSFRichTextString) {
249: return string.equals(((HSSFRichTextString) o).string);
250: }
251: return false;
252:
253: }
254:
255: /**
256: * @return the plain text representation of this string.
257: */
258: public String toString() {
259: return string.toString();
260: }
261:
262: /**
263: * Applies the specified font to the entire string.
264: *
265: * @param fontIndex the font to apply.
266: */
267: public void applyFont(short fontIndex) {
268: applyFont(0, string.getCharCount(), fontIndex);
269: }
270: }
|