Inspired by bug #44958 - Record level support for Data Tables. (No formula parser...
[poi.git] / src / java / org / apache / poi / hssf / usermodel / HSSFRichTextString.java
blob93db9214a60d0b547af4449543f293ae9718a7a0
1 /* ====================================================================
2 Licensed to the Apache Software Foundation (ASF) under one or more
3 contributor license agreements. See the NOTICE file distributed with
4 this work for additional information regarding copyright ownership.
5 The ASF licenses this file to You under the Apache License, Version 2.0
6 (the "License"); you may not use this file except in compliance with
7 the License. You may obtain a copy of the License at
9 http://www.apache.org/licenses/LICENSE-2.0
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16 ==================================================================== */
18 package org.apache.poi.hssf.usermodel;
20 import org.apache.poi.hssf.model.Workbook;
21 import org.apache.poi.hssf.record.LabelSSTRecord;
22 import org.apache.poi.hssf.record.UnicodeString;
24 import java.util.Iterator;
25 /**
26 * Rich text unicode string. These strings can have fonts applied to
27 * arbitary parts of the string.
29 * @author Glen Stampoultzis (glens at apache.org)
30 * @author Jason Height (jheight at apache.org)
32 public class HSSFRichTextString
33 implements Comparable
35 /** Place holder for indicating that NO_FONT has been applied here */
36 public static final short NO_FONT = 0;
38 private UnicodeString string;
39 private Workbook book;
40 private LabelSSTRecord record;
42 public HSSFRichTextString()
44 this("");
47 public HSSFRichTextString( String string )
49 if (string == null)
50 string = "";
51 this.string = new UnicodeString(string);
54 HSSFRichTextString(Workbook book, LabelSSTRecord record) {
55 setWorkbookReferences(book, record);
57 this.string = book.getSSTString(record.getSSTIndex());
60 /** This must be called to setup the internal work book references whenever
61 * a RichTextString is added to a cell
62 */
63 void setWorkbookReferences(Workbook book, LabelSSTRecord record) {
64 this.book = book;
65 this.record = record;
68 /** Called whenever the unicode string is modified. When it is modified
69 * we need to create a new SST index, so that other LabelSSTRecords will not
70 * be affected by changes tat we make to this string.
72 private UnicodeString cloneStringIfRequired() {
73 if (book == null)
74 return string;
75 UnicodeString s = (UnicodeString)string.clone();
76 return s;
79 private void addToSSTIfRequired() {
80 if (book != null) {
81 int index = book.addSSTString(string);
82 record.setSSTIndex(index);
83 //The act of adding the string to the SST record may have meant that
84 //a extsing string was returned for the index, so update our local version
85 string = book.getSSTString(index);
90 /**
91 * Applies a font to the specified characters of a string.
93 * @param startIndex The start index to apply the font to (inclusive)
94 * @param endIndex The end index to apply the font to (exclusive)
95 * @param fontIndex The font to use.
97 public void applyFont(int startIndex, int endIndex, short fontIndex)
99 if (startIndex > endIndex)
100 throw new IllegalArgumentException("Start index must be less than end index.");
101 if (startIndex < 0 || endIndex > length())
102 throw new IllegalArgumentException("Start and end index not in range.");
103 if (startIndex == endIndex)
104 return;
106 //Need to check what the font is currently, so we can reapply it after
107 //the range is completed
108 short currentFont = NO_FONT;
109 if (endIndex != length()) {
110 currentFont = this.getFontAtIndex(startIndex);
113 //Need to clear the current formatting between the startIndex and endIndex
114 string = cloneStringIfRequired();
115 Iterator formatting = string.formatIterator();
116 if (formatting != null) {
117 while (formatting.hasNext()) {
118 UnicodeString.FormatRun r = (UnicodeString.FormatRun)formatting.next();
119 if ((r.getCharacterPos() >= startIndex) && (r.getCharacterPos() < endIndex))
120 formatting.remove();
125 string.addFormatRun(new UnicodeString.FormatRun((short)startIndex, fontIndex));
126 if (endIndex != length())
127 string.addFormatRun(new UnicodeString.FormatRun((short)endIndex, currentFont));
129 addToSSTIfRequired();
133 * Applies a font to the specified characters of a string.
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.
139 public void applyFont(int startIndex, int endIndex, HSSFFont font)
141 applyFont(startIndex, endIndex, font.getIndex());
145 * Sets the font of the entire string.
146 * @param font The font to use.
148 public void applyFont(HSSFFont font)
150 applyFont(0, string.getCharCount(), font);
154 * Removes any formatting that may have been applied to the string.
156 public void clearFormatting() {
157 string = cloneStringIfRequired();
158 string.clearFormatting();
159 addToSSTIfRequired();
163 * Returns the plain string representation.
165 public String getString()
167 return string.getString();
170 /** Used internally by the HSSFCell to get the internal string value*/
171 UnicodeString getUnicodeString() {
172 return cloneStringIfRequired();
175 /** Used internally by the HSSFCell to set the internal string value*/
176 void setUnicodeString(UnicodeString str) {
177 this.string = str;
182 * @return the number of characters in the font.
184 public int length()
186 return string.getCharCount();
190 * Returns the font in use at a particular index.
192 * @param index The index.
193 * @return The font that's currently being applied at that
194 * index or null if no font is being applied or the
195 * index is out of range.
197 public short getFontAtIndex( int index )
199 int size = string.getFormatRunCount();
200 UnicodeString.FormatRun currentRun = null;
201 for (int i=0;i<size;i++) {
202 UnicodeString.FormatRun r = string.getFormatRun(i);
203 if (r.getCharacterPos() > index)
204 break;
205 else currentRun = r;
207 if (currentRun == null)
208 return NO_FONT;
209 else return currentRun.getFontIndex();
213 * @return The number of formatting runs used. There will always be at
214 * least one of font NO_FONT.
216 * @see #NO_FONT
218 public int numFormattingRuns()
220 return string.getFormatRunCount();
224 * The index within the string to which the specified formatting run applies.
225 * @param index the index of the formatting run
226 * @return the index within the string.
228 public int getIndexOfFormattingRun(int index)
230 UnicodeString.FormatRun r = string.getFormatRun(index);
231 return r.getCharacterPos();
235 * Gets the font used in a particular formatting run.
237 * @param index the index of the formatting run
238 * @return the font number used.
240 public short getFontOfFormattingRun(int index)
242 UnicodeString.FormatRun r = string.getFormatRun(index);
243 return r.getFontIndex();
247 * Compares one rich text string to another.
249 public int compareTo( Object o )
251 HSSFRichTextString r = (HSSFRichTextString)o;
252 return string.compareTo(r.string);
255 public boolean equals(Object o) {
256 if (o instanceof HSSFRichTextString) {
257 return string.equals(((HSSFRichTextString)o).string);
259 return false;
264 * @return the plain text representation of this string.
266 public String toString()
268 return string.toString();
272 * Applies the specified font to the entire string.
274 * @param fontIndex the font to apply.
276 public void applyFont( short fontIndex )
278 applyFont(0, string.getCharCount(), fontIndex);