git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1508692 13f79535-47bb-0310-9956-ffa450edef68pull/7/head
/* | |||||
* ==================================================================== | |||||
* 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.xssf.model; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties; | |||||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShape; | |||||
import org.apache.xmlbeans.XmlObject; | |||||
import org.apache.poi.util.Internal; | |||||
/** | |||||
* Used internally to navigate the paragraph text style hierarchy within a shape and fetch properties | |||||
*/ | |||||
@Internal | |||||
public abstract class ParagraphPropertyFetcher<T> { | |||||
private T _value; | |||||
private int _level; | |||||
public T getValue(){ | |||||
return _value; | |||||
} | |||||
public void setValue(T val){ | |||||
_value = val; | |||||
} | |||||
public ParagraphPropertyFetcher(int level) { | |||||
_level = level; | |||||
} | |||||
/** | |||||
* | |||||
* @param shape the shape being examined | |||||
* @return true if the desired property was fetched | |||||
*/ | |||||
public boolean fetch(CTShape shape) { | |||||
XmlObject[] o = shape.selectPath( | |||||
"declare namespace xdr='http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing' " + | |||||
"declare namespace a='http://schemas.openxmlformats.org/drawingml/2006/main' " + | |||||
".//xdr:txBody/a:lstStyle/a:lvl" + (_level + 1) + "pPr" | |||||
); | |||||
if (o.length == 1) { | |||||
CTTextParagraphProperties props = (CTTextParagraphProperties) o[0]; | |||||
return fetch(props); | |||||
} | |||||
return false; | |||||
} | |||||
public abstract boolean fetch(CTTextParagraphProperties props); | |||||
} |
/* | |||||
* ==================================================================== | |||||
* 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.xssf.usermodel; | |||||
/** | |||||
* Specifies type of automatic numbered bullet points that should be applied to a paragraph. | |||||
*/ | |||||
public enum ListAutoNumber { | |||||
/** | |||||
* (a), (b), (c), ... | |||||
*/ | |||||
ALPHA_LC_PARENT_BOTH, | |||||
/** | |||||
* (A), (B), (C), ... | |||||
*/ | |||||
ALPHA_UC_PARENT_BOTH, | |||||
/** | |||||
* a), b), c), ... | |||||
*/ | |||||
ALPHA_LC_PARENT_R, | |||||
/** | |||||
* A), B), C), ... | |||||
*/ | |||||
ALPHA_UC_PARENT_R, | |||||
/** | |||||
* a., b., c., ... | |||||
*/ | |||||
ALPHA_LC_PERIOD, | |||||
/** | |||||
* A., B., C., ... | |||||
*/ | |||||
ALPHA_UC_PERIOD, | |||||
/** | |||||
* (1), (2), (3), ... | |||||
*/ | |||||
ARABIC_PARENT_BOTH, | |||||
/** | |||||
* 1), 2), 3), ... | |||||
*/ | |||||
ARABIC_PARENT_R, | |||||
/** | |||||
* 1., 2., 3., ... | |||||
*/ | |||||
ARABIC_PERIOD, | |||||
/** | |||||
* 1, 2, 3, ... | |||||
*/ | |||||
ARABIC_PLAIN, | |||||
/** | |||||
* (i), (ii), (iii), ... | |||||
*/ | |||||
ROMAN_LC_PARENT_BOTH, | |||||
/** | |||||
* (I), (II), (III), ... | |||||
*/ | |||||
ROMAN_UC_PARENT_BOTH, | |||||
/** | |||||
* i), ii), iii), ... | |||||
*/ | |||||
ROMAN_LC_PARENT_R, | |||||
/** | |||||
* I), II), III), ... | |||||
*/ | |||||
ROMAN_UC_PARENT_R, | |||||
/** | |||||
* i., ii., iii., ... | |||||
*/ | |||||
ROMAN_LC_PERIOD , | |||||
/** | |||||
* I., II., III., ... | |||||
*/ | |||||
ROMAN_UC_PERIOD, | |||||
/** | |||||
* Dbl-byte circle numbers | |||||
*/ | |||||
CIRCLE_NUM_DB_PLAIN, | |||||
/** | |||||
* Wingdings black circle numbers | |||||
*/ | |||||
CIRCLE_NUM_WD_BLACK_PLAIN, | |||||
/** | |||||
* Wingdings white circle numbers | |||||
*/ | |||||
CIRCLE_NUM_WD_WHITE_PLAIN | |||||
} |
/* | |||||
* ==================================================================== | |||||
* 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.xssf.usermodel; | |||||
/** | |||||
* Specified a list of text alignment types | |||||
*/ | |||||
public enum TextAlign { | |||||
/** | |||||
* Align text to the left margin. | |||||
*/ | |||||
LEFT, | |||||
/** | |||||
* Align text in the center. | |||||
*/ | |||||
CENTER, | |||||
/** | |||||
* Align text to the right margin. | |||||
*/ | |||||
RIGHT, | |||||
/** | |||||
* Align text so that it is justified across the whole line. It | |||||
* is smart in the sense that it will not justify sentences | |||||
* which are short | |||||
*/ | |||||
JUSTIFY, | |||||
JUSTIFY_LOW, | |||||
DIST, | |||||
THAI_DIST | |||||
} |
/* | |||||
* ==================================================================== | |||||
* 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.xssf.usermodel; | |||||
/** | |||||
* Specifies a list of auto-fit types. | |||||
* <p> | |||||
* Autofit specifies that a shape should be auto-fit to fully contain the text described within it. | |||||
* Auto-fitting is when text within a shape is scaled in order to contain all the text inside | |||||
* </p> | |||||
*/ | |||||
public enum TextAutofit { | |||||
/** | |||||
* Specifies that text within the text body should not be auto-fit to the bounding box. | |||||
* Auto-fitting is when text within a text box is scaled in order to remain inside | |||||
* the text box. | |||||
*/ | |||||
NONE, | |||||
/** | |||||
* Specifies that text within the text body should be normally auto-fit to the bounding box. | |||||
* Autofitting is when text within a text box is scaled in order to remain inside the text box. | |||||
* | |||||
* <p> | |||||
* <em>Example:</em> Consider the situation where a user is building a diagram and needs | |||||
* to have the text for each shape that they are using stay within the bounds of the shape. | |||||
* An easy way this might be done is by using NORMAL autofit | |||||
* </p> | |||||
*/ | |||||
NORMAL, | |||||
/** | |||||
* Specifies that a shape should be auto-fit to fully contain the text described within it. | |||||
* Auto-fitting is when text within a shape is scaled in order to contain all the text inside. | |||||
* | |||||
* <p> | |||||
* <em>Example:</em> Consider the situation where a user is building a diagram and needs to have | |||||
* the text for each shape that they are using stay within the bounds of the shape. | |||||
* An easy way this might be done is by using SHAPE autofit | |||||
* </p> | |||||
*/ | |||||
SHAPE | |||||
} |
/* | |||||
* ==================================================================== | |||||
* 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.xssf.usermodel; | |||||
/** | |||||
* Text Capitalization that is to be applied to the text run. This is a render-only | |||||
* modification and does not affect the actual characters stored in the text run. | |||||
*/ | |||||
public enum TextCap { | |||||
NONE, | |||||
SMALL, | |||||
ALL | |||||
} |
/* | |||||
* ==================================================================== | |||||
* 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.xssf.usermodel; | |||||
/** | |||||
* Vertical Text Types | |||||
*/ | |||||
public enum TextDirection { | |||||
/** | |||||
* Horizontal text. This should be default. | |||||
*/ | |||||
HORIZONTAL, | |||||
/** | |||||
* Vertical orientation. | |||||
* (each line is 90 degrees rotated clockwise, so it goes | |||||
* from top to bottom; each next line is to the left from | |||||
* the previous one). | |||||
*/ | |||||
VERTICAL, | |||||
/** | |||||
* Vertical orientation. | |||||
* (each line is 270 degrees rotated clockwise, so it goes | |||||
* from bottom to top; each next line is to the right from | |||||
* the previous one). | |||||
*/ | |||||
VERTICAL_270, | |||||
/** | |||||
* Determines if all of the text is vertical | |||||
* ("one letter on top of another"). | |||||
*/ | |||||
STACKED; | |||||
} |
/* | |||||
* ==================================================================== | |||||
* 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.xssf.usermodel; | |||||
/** | |||||
* Specified a list of text font alignment types | |||||
*/ | |||||
public enum TextFontAlign { | |||||
/** | |||||
* Automatic alignment | |||||
*/ | |||||
AUTO, | |||||
/** | |||||
* Align text to the top. | |||||
*/ | |||||
TOP, | |||||
/** | |||||
* Align text in the center. | |||||
*/ | |||||
CENTER, | |||||
/** | |||||
* Align text to the baseline. | |||||
*/ | |||||
BASELINE, | |||||
/** | |||||
* Align text to the bottom. | |||||
*/ | |||||
BOTTOM | |||||
} |
/* | |||||
* ==================================================================== | |||||
* 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.xssf.usermodel; | |||||
/** | |||||
* Text Horizontal Overflow | |||||
*/ | |||||
public enum TextHorizontalOverflow { | |||||
/** | |||||
* When a big character does not fit into a line, allow a | |||||
* horizontal overflow. | |||||
*/ | |||||
OVERFLOW, | |||||
/** | |||||
* When a big character does not fit into a line, clip it at | |||||
* the proper horizontal overflow. | |||||
*/ | |||||
CLIP | |||||
} |
/* | |||||
* ==================================================================== | |||||
* 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.xssf.usermodel; | |||||
/** | |||||
* Text Vertical Overflow | |||||
*/ | |||||
public enum TextVerticalOverflow { | |||||
/** | |||||
* Overflow the text and pay no attention to top and bottom barriers. | |||||
*/ | |||||
OVERFLOW, | |||||
/** | |||||
* Pay attention to top and bottom barriers. Use an | |||||
* ellipsis to denote that there is text which is not visible. | |||||
*/ | |||||
ELLIPSIS, | |||||
/** | |||||
* Pay attention to top and bottom barriers. Provide no | |||||
* indication that there is text which is not visible. | |||||
*/ | |||||
CLIP | |||||
} |
/* | |||||
* ==================================================================== | |||||
* 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.xssf.usermodel; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties; | |||||
class XSSFLineBreak extends XSSFTextRun { | |||||
private final CTTextCharacterProperties _brProps; | |||||
XSSFLineBreak(CTRegularTextRun r, XSSFTextParagraph p, CTTextCharacterProperties brProps){ | |||||
super(r, p); | |||||
_brProps = brProps; | |||||
} | |||||
@Override | |||||
protected CTTextCharacterProperties getRPr(){ | |||||
return _brProps; | |||||
} | |||||
/** | |||||
* Always throws IllegalStateException. You cannot change text of a line break. | |||||
*/ | |||||
public void setText(String text){ | |||||
throw new IllegalStateException("You cannot change text of a line break, it is always '\\n'"); | |||||
} | |||||
} |
/* ==================================================================== | |||||
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.xssf.usermodel; | |||||
import org.apache.poi.util.Internal; | |||||
import org.apache.poi.util.Units; | |||||
import org.apache.poi.xssf.usermodel.TextAlign; | |||||
import org.apache.poi.xssf.model.ParagraphPropertyFetcher; | |||||
import org.apache.xmlbeans.XmlObject; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.*; | |||||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShape; | |||||
import java.awt.Color; | |||||
import java.util.ArrayList; | |||||
import java.util.Iterator; | |||||
import java.util.List; | |||||
/** | |||||
* Represents a paragraph of text within the containing text body. | |||||
* The paragraph is the highest level text separation mechanism. | |||||
*/ | |||||
public class XSSFTextParagraph implements Iterable<XSSFTextRun>{ | |||||
private final CTTextParagraph _p; | |||||
private final CTShape _shape; | |||||
private final List<XSSFTextRun> _runs; | |||||
XSSFTextParagraph(CTTextParagraph p, CTShape ctShape){ | |||||
_p = p; | |||||
_shape = ctShape; | |||||
_runs = new ArrayList<XSSFTextRun>(); | |||||
for(XmlObject ch : _p.selectPath("*")){ | |||||
if(ch instanceof CTRegularTextRun){ | |||||
CTRegularTextRun r = (CTRegularTextRun)ch; | |||||
_runs.add(new XSSFTextRun(r, this)); | |||||
} else if (ch instanceof CTTextLineBreak){ | |||||
CTTextLineBreak br = (CTTextLineBreak)ch; | |||||
CTRegularTextRun r = CTRegularTextRun.Factory.newInstance(); | |||||
r.setRPr(br.getRPr()); | |||||
r.setT("\n"); | |||||
_runs.add(new XSSFTextRun(r, this)); | |||||
} else if (ch instanceof CTTextField){ | |||||
CTTextField f = (CTTextField)ch; | |||||
CTRegularTextRun r = CTRegularTextRun.Factory.newInstance(); | |||||
r.setRPr(f.getRPr()); | |||||
r.setT(f.getT()); | |||||
_runs.add(new XSSFTextRun(r, this)); | |||||
} | |||||
} | |||||
} | |||||
public String getText(){ | |||||
StringBuilder out = new StringBuilder(); | |||||
for (XSSFTextRun r : _runs) { | |||||
out.append(r.getText()); | |||||
} | |||||
return out.toString(); | |||||
} | |||||
@Internal | |||||
public CTTextParagraph getXmlObject(){ | |||||
return _p; | |||||
} | |||||
@Internal | |||||
public CTShape getParentShape(){ | |||||
return _shape; | |||||
} | |||||
public List<XSSFTextRun> getTextRuns(){ | |||||
return _runs; | |||||
} | |||||
public Iterator<XSSFTextRun> iterator(){ | |||||
return _runs.iterator(); | |||||
} | |||||
/** | |||||
* Add a new run of text | |||||
* | |||||
* @return a new run of text | |||||
*/ | |||||
public XSSFTextRun addNewTextRun(){ | |||||
CTRegularTextRun r = _p.addNewR(); | |||||
CTTextCharacterProperties rPr = r.addNewRPr(); | |||||
rPr.setLang("en-US"); | |||||
XSSFTextRun run = new XSSFTextRun(r, this); | |||||
_runs.add(run); | |||||
return run; | |||||
} | |||||
/** | |||||
* Insert a line break | |||||
* | |||||
* @return text run representing this line break ('\n') | |||||
*/ | |||||
public XSSFTextRun addLineBreak(){ | |||||
CTTextLineBreak br = _p.addNewBr(); | |||||
CTTextCharacterProperties brProps = br.addNewRPr(); | |||||
if(_runs.size() > 0){ | |||||
// by default line break has the font size of the last text run | |||||
CTTextCharacterProperties prevRun = _runs.get(_runs.size() - 1).getRPr(); | |||||
brProps.set(prevRun); | |||||
} | |||||
CTRegularTextRun r = CTRegularTextRun.Factory.newInstance(); | |||||
r.setRPr(brProps); | |||||
r.setT("\n"); | |||||
XSSFTextRun run = new XSSFLineBreak(r, this, brProps); | |||||
_runs.add(run); | |||||
return run; | |||||
} | |||||
/** | |||||
* Returns the alignment that is applied to the paragraph. | |||||
* | |||||
* If this attribute is omitted, then a value of left is implied. | |||||
* @return alignment that is applied to the paragraph | |||||
*/ | |||||
public TextAlign getTextAlign(){ | |||||
ParagraphPropertyFetcher<TextAlign> fetcher = new ParagraphPropertyFetcher<TextAlign>(getLevel()){ | |||||
public boolean fetch(CTTextParagraphProperties props){ | |||||
if(props.isSetAlgn()){ | |||||
TextAlign val = TextAlign.values()[props.getAlgn().intValue() - 1]; | |||||
setValue(val); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchParagraphProperty(fetcher); | |||||
return fetcher.getValue() == null ? TextAlign.LEFT : fetcher.getValue(); | |||||
} | |||||
/** | |||||
* Specifies the alignment that is to be applied to the paragraph. | |||||
* Possible values for this include left, right, centered, justified and distributed, | |||||
* see {@link org.apache.poi.xssf.usermodel.TextAlign}. | |||||
* | |||||
* @param align text align | |||||
*/ | |||||
public void setTextAlign(TextAlign align){ | |||||
CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); | |||||
if(align == null) { | |||||
if(pr.isSetAlgn()) pr.unsetAlgn(); | |||||
} else { | |||||
pr.setAlgn(STTextAlignType.Enum.forInt(align.ordinal() + 1)); | |||||
} | |||||
} | |||||
/** | |||||
* Returns where vertically on a line of text the actual words are positioned. This deals | |||||
* with vertical placement of the characters with respect to the baselines. | |||||
* | |||||
* If this attribute is omitted, then a value of baseline is implied. | |||||
* @return alignment that is applied to the paragraph | |||||
*/ | |||||
public TextFontAlign getTextFontAlign(){ | |||||
ParagraphPropertyFetcher<TextFontAlign> fetcher = new ParagraphPropertyFetcher<TextFontAlign>(getLevel()){ | |||||
public boolean fetch(CTTextParagraphProperties props){ | |||||
if(props.isSetAlgn()){ | |||||
TextFontAlign val = TextFontAlign.values()[props.getFontAlgn().intValue() - 1]; | |||||
setValue(val); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchParagraphProperty(fetcher); | |||||
return fetcher.getValue() == null ? TextFontAlign.BASELINE : fetcher.getValue(); | |||||
} | |||||
/** | |||||
* Determines where vertically on a line of text the actual words are positioned. This deals | |||||
* with vertical placement of the characters with respect to the baselines. For instance | |||||
* having text anchored to the top baseline, anchored to the bottom baseline, centered in | |||||
* between, etc. | |||||
* | |||||
* @param align text font align | |||||
*/ | |||||
public void setTextFontAlign(TextFontAlign align){ | |||||
CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); | |||||
if(align == null) { | |||||
if(pr.isSetFontAlgn()) pr.unsetFontAlgn(); | |||||
} else { | |||||
pr.setFontAlgn(STTextFontAlignType.Enum.forInt(align.ordinal() + 1)); | |||||
} | |||||
} | |||||
/** | |||||
* @return the font to be used on bullet characters within a given paragraph | |||||
*/ | |||||
public String getBulletFont(){ | |||||
ParagraphPropertyFetcher<String> fetcher = new ParagraphPropertyFetcher<String>(getLevel()){ | |||||
public boolean fetch(CTTextParagraphProperties props){ | |||||
if(props.isSetBuFont()){ | |||||
setValue(props.getBuFont().getTypeface()); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchParagraphProperty(fetcher); | |||||
return fetcher.getValue(); | |||||
} | |||||
public void setBulletFont(String typeface){ | |||||
CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); | |||||
CTTextFont font = pr.isSetBuFont() ? pr.getBuFont() : pr.addNewBuFont(); | |||||
font.setTypeface(typeface); | |||||
} | |||||
/** | |||||
* @return the character to be used in place of the standard bullet point | |||||
*/ | |||||
public String getBulletCharacter(){ | |||||
ParagraphPropertyFetcher<String> fetcher = new ParagraphPropertyFetcher<String>(getLevel()){ | |||||
public boolean fetch(CTTextParagraphProperties props){ | |||||
if(props.isSetBuChar()){ | |||||
setValue(props.getBuChar().getChar()); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchParagraphProperty(fetcher); | |||||
return fetcher.getValue(); | |||||
} | |||||
public void setBulletCharacter(String str){ | |||||
CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); | |||||
CTTextCharBullet c = pr.isSetBuChar() ? pr.getBuChar() : pr.addNewBuChar(); | |||||
c.setChar(str); | |||||
} | |||||
/** | |||||
* | |||||
* @return the color of bullet characters within a given paragraph. | |||||
* A <code>null</code> value means to use the text font color. | |||||
*/ | |||||
public Color getBulletFontColor(){ | |||||
ParagraphPropertyFetcher<Color> fetcher = new ParagraphPropertyFetcher<Color>(getLevel()){ | |||||
public boolean fetch(CTTextParagraphProperties props){ | |||||
if(props.isSetBuClr()){ | |||||
if(props.getBuClr().isSetSrgbClr()){ | |||||
CTSRgbColor clr = props.getBuClr().getSrgbClr(); | |||||
byte[] rgb = clr.getVal(); | |||||
setValue(new Color(0xFF & rgb[0], 0xFF & rgb[1], 0xFF & rgb[2])); | |||||
return true; | |||||
} | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchParagraphProperty(fetcher); | |||||
return fetcher.getValue(); | |||||
} | |||||
/** | |||||
* Set the color to be used on bullet characters within a given paragraph. | |||||
* | |||||
* @param color the bullet color | |||||
*/ | |||||
public void setBulletFontColor(Color color){ | |||||
CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); | |||||
CTColor c = pr.isSetBuClr() ? pr.getBuClr() : pr.addNewBuClr(); | |||||
CTSRgbColor clr = c.isSetSrgbClr() ? c.getSrgbClr() : c.addNewSrgbClr(); | |||||
clr.setVal(new byte[]{(byte) color.getRed(), (byte) color.getGreen(), (byte) color.getBlue()}); | |||||
} | |||||
/** | |||||
* Returns the bullet size that is to be used within a paragraph. | |||||
* This may be specified in two different ways, percentage spacing and font point spacing: | |||||
* <p> | |||||
* If bulletSize >= 0, then bulletSize is a percentage of the font size. | |||||
* If bulletSize < 0, then it specifies the size in points | |||||
* </p> | |||||
* | |||||
* @return the bullet size | |||||
*/ | |||||
public double getBulletFontSize(){ | |||||
ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){ | |||||
public boolean fetch(CTTextParagraphProperties props){ | |||||
if(props.isSetBuSzPct()){ | |||||
setValue(props.getBuSzPct().getVal() * 0.001); | |||||
return true; | |||||
} | |||||
if(props.isSetBuSzPts()){ | |||||
setValue( - props.getBuSzPts().getVal() * 0.01); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchParagraphProperty(fetcher); | |||||
return fetcher.getValue() == null ? 100 : fetcher.getValue(); | |||||
} | |||||
/** | |||||
* Sets the bullet size that is to be used within a paragraph. | |||||
* This may be specified in two different ways, percentage spacing and font point spacing: | |||||
* <p> | |||||
* If bulletSize >= 0, then bulletSize is a percentage of the font size. | |||||
* If bulletSize < 0, then it specifies the size in points | |||||
* </p> | |||||
*/ | |||||
public void setBulletFontSize(double bulletSize){ | |||||
CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); | |||||
if(bulletSize >= 0) { | |||||
CTTextBulletSizePercent pt = pr.isSetBuSzPct() ? pr.getBuSzPct() : pr.addNewBuSzPct(); | |||||
pt.setVal((int)(bulletSize*1000)); | |||||
if(pr.isSetBuSzPts()) pr.unsetBuSzPts(); | |||||
} else { | |||||
CTTextBulletSizePoint pt = pr.isSetBuSzPts() ? pr.getBuSzPts() : pr.addNewBuSzPts(); | |||||
pt.setVal((int)(-bulletSize*100)); | |||||
if(pr.isSetBuSzPct()) pr.unsetBuSzPct(); | |||||
} | |||||
} | |||||
/** | |||||
* Specifies the indent size that will be applied to the first line of text in the paragraph. | |||||
* | |||||
* @param value the indent in points. | |||||
*/ | |||||
public void setIndent(double value){ | |||||
CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); | |||||
if(value == -1) { | |||||
if(pr.isSetIndent()) pr.unsetIndent(); | |||||
} else { | |||||
pr.setIndent(Units.toEMU(value)); | |||||
} | |||||
} | |||||
/** | |||||
* | |||||
* @return the indent applied to the first line of text in the paragraph. | |||||
*/ | |||||
public double getIndent(){ | |||||
ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){ | |||||
public boolean fetch(CTTextParagraphProperties props){ | |||||
if(props.isSetIndent()){ | |||||
setValue(Units.toPoints(props.getIndent())); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchParagraphProperty(fetcher); | |||||
return fetcher.getValue() == null ? 0 : fetcher.getValue(); | |||||
} | |||||
/** | |||||
* Specifies the left margin of the paragraph. This is specified in addition to the text body | |||||
* inset and applies only to this text paragraph. That is the text body inset and the LeftMargin | |||||
* attributes are additive with respect to the text position. | |||||
* | |||||
* @param value the left margin of the paragraph | |||||
*/ | |||||
public void setLeftMargin(double value){ | |||||
CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); | |||||
if(value == -1) { | |||||
if(pr.isSetMarL()) pr.unsetMarL(); | |||||
} else { | |||||
pr.setMarL(Units.toEMU(value)); | |||||
} | |||||
} | |||||
/** | |||||
* | |||||
* @return the left margin of the paragraph | |||||
*/ | |||||
public double getLeftMargin(){ | |||||
ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){ | |||||
public boolean fetch(CTTextParagraphProperties props){ | |||||
if(props.isSetMarL()){ | |||||
double val = Units.toPoints(props.getMarL()); | |||||
setValue(val); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchParagraphProperty(fetcher); | |||||
// if the marL attribute is omitted, then a value of 347663 is implied | |||||
return fetcher.getValue() == null ? 0 : fetcher.getValue(); | |||||
} | |||||
/** | |||||
* Specifies the right margin of the paragraph. This is specified in addition to the text body | |||||
* inset and applies only to this text paragraph. That is the text body inset and the marR | |||||
* attributes are additive with respect to the text position. | |||||
* | |||||
* @param value the right margin of the paragraph | |||||
*/ | |||||
public void setRightMargin(double value){ | |||||
CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); | |||||
if(value == -1) { | |||||
if(pr.isSetMarR()) pr.unsetMarR(); | |||||
} else { | |||||
pr.setMarR(Units.toEMU(value)); | |||||
} | |||||
} | |||||
/** | |||||
* | |||||
* @return the right margin of the paragraph | |||||
*/ | |||||
public double getRightMargin(){ | |||||
ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){ | |||||
public boolean fetch(CTTextParagraphProperties props){ | |||||
if(props.isSetMarR()){ | |||||
double val = Units.toPoints(props.getMarR()); | |||||
setValue(val); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchParagraphProperty(fetcher); | |||||
// if the marL attribute is omitted, then a value of 347663 is implied | |||||
return fetcher.getValue() == null ? 0 : fetcher.getValue(); | |||||
} | |||||
/** | |||||
* | |||||
* @return the default size for a tab character within this paragraph in points | |||||
*/ | |||||
public double getDefaultTabSize(){ | |||||
ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){ | |||||
public boolean fetch(CTTextParagraphProperties props){ | |||||
if(props.isSetDefTabSz()){ | |||||
double val = Units.toPoints(props.getDefTabSz()); | |||||
setValue(val); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchParagraphProperty(fetcher); | |||||
return fetcher.getValue() == null ? 0 : fetcher.getValue(); | |||||
} | |||||
public double getTabStop(final int idx){ | |||||
ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){ | |||||
public boolean fetch(CTTextParagraphProperties props){ | |||||
if(props.isSetTabLst()){ | |||||
CTTextTabStopList tabStops = props.getTabLst(); | |||||
if(idx < tabStops.sizeOfTabArray() ) { | |||||
CTTextTabStop ts = tabStops.getTabArray(idx); | |||||
double val = Units.toPoints(ts.getPos()); | |||||
setValue(val); | |||||
return true; | |||||
} | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchParagraphProperty(fetcher); | |||||
return fetcher.getValue() == null ? 0. : fetcher.getValue(); | |||||
} | |||||
/** | |||||
* Add a single tab stop to be used on a line of text when there are one or more tab characters | |||||
* present within the text. | |||||
* | |||||
* @param value the position of the tab stop relative to the left margin | |||||
*/ | |||||
public void addTabStop(double value){ | |||||
CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); | |||||
CTTextTabStopList tabStops = pr.isSetTabLst() ? pr.getTabLst() : pr.addNewTabLst(); | |||||
tabStops.addNewTab().setPos(Units.toEMU(value)); | |||||
} | |||||
/** | |||||
* This element specifies the vertical line spacing that is to be used within a paragraph. | |||||
* This may be specified in two different ways, percentage spacing and font point spacing: | |||||
* <p> | |||||
* If linespacing >= 0, then linespacing is a percentage of normal line height | |||||
* If linespacing < 0, the absolute value of linespacing is the spacing in points | |||||
* </p> | |||||
* Examples: | |||||
* <pre><code> | |||||
* // spacing will be 120% of the size of the largest text on each line | |||||
* paragraph.setLineSpacing(120); | |||||
* | |||||
* // spacing will be 200% of the size of the largest text on each line | |||||
* paragraph.setLineSpacing(200); | |||||
* | |||||
* // spacing will be 48 points | |||||
* paragraph.setLineSpacing(-48.0); | |||||
* </code></pre> | |||||
* | |||||
* @param linespacing the vertical line spacing | |||||
*/ | |||||
public void setLineSpacing(double linespacing){ | |||||
CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); | |||||
CTTextSpacing spc = CTTextSpacing.Factory.newInstance(); | |||||
if(linespacing >= 0) spc.addNewSpcPct().setVal((int)(linespacing*1000)); | |||||
else spc.addNewSpcPts().setVal((int)(-linespacing*100)); | |||||
pr.setLnSpc(spc); | |||||
} | |||||
/** | |||||
* Returns the vertical line spacing that is to be used within a paragraph. | |||||
* This may be specified in two different ways, percentage spacing and font point spacing: | |||||
* <p> | |||||
* If linespacing >= 0, then linespacing is a percentage of normal line height. | |||||
* If linespacing < 0, the absolute value of linespacing is the spacing in points | |||||
* </p> | |||||
* | |||||
* @return the vertical line spacing. | |||||
*/ | |||||
public double getLineSpacing(){ | |||||
ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){ | |||||
public boolean fetch(CTTextParagraphProperties props){ | |||||
if(props.isSetLnSpc()){ | |||||
CTTextSpacing spc = props.getLnSpc(); | |||||
if(spc.isSetSpcPct()) setValue( spc.getSpcPct().getVal()*0.001 ); | |||||
else if (spc.isSetSpcPts()) setValue( -spc.getSpcPts().getVal()*0.01 ); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchParagraphProperty(fetcher); | |||||
double lnSpc = fetcher.getValue() == null ? 100 : fetcher.getValue(); | |||||
if(lnSpc > 0) { | |||||
// check if the percentage value is scaled | |||||
CTTextNormalAutofit normAutofit = _shape.getTxBody().getBodyPr().getNormAutofit(); | |||||
if(normAutofit != null) { | |||||
double scale = 1 - (double)normAutofit.getLnSpcReduction() / 100000; | |||||
lnSpc *= scale; | |||||
} | |||||
} | |||||
return lnSpc; | |||||
} | |||||
/** | |||||
* Set the amount of vertical white space that will be present before the paragraph. | |||||
* This space is specified in either percentage or points: | |||||
* <p> | |||||
* If spaceBefore >= 0, then space is a percentage of normal line height. | |||||
* If spaceBefore < 0, the absolute value of linespacing is the spacing in points | |||||
* </p> | |||||
* Examples: | |||||
* <pre><code> | |||||
* // The paragraph will be formatted to have a spacing before the paragraph text. | |||||
* // The spacing will be 200% of the size of the largest text on each line | |||||
* paragraph.setSpaceBefore(200); | |||||
* | |||||
* // The spacing will be a size of 48 points | |||||
* paragraph.setSpaceBefore(-48.0); | |||||
* </code></pre> | |||||
* | |||||
* @param spaceBefore the vertical white space before the paragraph. | |||||
*/ | |||||
public void setSpaceBefore(double spaceBefore){ | |||||
CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); | |||||
CTTextSpacing spc = CTTextSpacing.Factory.newInstance(); | |||||
if(spaceBefore >= 0) spc.addNewSpcPct().setVal((int)(spaceBefore*1000)); | |||||
else spc.addNewSpcPts().setVal((int)(-spaceBefore*100)); | |||||
pr.setSpcBef(spc); | |||||
} | |||||
/** | |||||
* The amount of vertical white space before the paragraph | |||||
* This may be specified in two different ways, percentage spacing and font point spacing: | |||||
* <p> | |||||
* If spaceBefore >= 0, then space is a percentage of normal line height. | |||||
* If spaceBefore < 0, the absolute value of linespacing is the spacing in points | |||||
* </p> | |||||
* | |||||
* @return the vertical white space before the paragraph | |||||
*/ | |||||
public double getSpaceBefore(){ | |||||
ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){ | |||||
public boolean fetch(CTTextParagraphProperties props){ | |||||
if(props.isSetSpcBef()){ | |||||
CTTextSpacing spc = props.getSpcBef(); | |||||
if(spc.isSetSpcPct()) setValue( spc.getSpcPct().getVal()*0.001 ); | |||||
else if (spc.isSetSpcPts()) setValue( -spc.getSpcPts().getVal()*0.01 ); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchParagraphProperty(fetcher); | |||||
double spcBef = fetcher.getValue() == null ? 0 : fetcher.getValue(); | |||||
return spcBef; | |||||
} | |||||
/** | |||||
* Set the amount of vertical white space that will be present after the paragraph. | |||||
* This space is specified in either percentage or points: | |||||
* <p> | |||||
* If spaceAfter >= 0, then space is a percentage of normal line height. | |||||
* If spaceAfter < 0, the absolute value of linespacing is the spacing in points | |||||
* </p> | |||||
* Examples: | |||||
* <pre><code> | |||||
* // The paragraph will be formatted to have a spacing after the paragraph text. | |||||
* // The spacing will be 200% of the size of the largest text on each line | |||||
* paragraph.setSpaceAfter(200); | |||||
* | |||||
* // The spacing will be a size of 48 points | |||||
* paragraph.setSpaceAfter(-48.0); | |||||
* </code></pre> | |||||
* | |||||
* @param spaceAfter the vertical white space after the paragraph. | |||||
*/ | |||||
public void setSpaceAfter(double spaceAfter){ | |||||
CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); | |||||
CTTextSpacing spc = CTTextSpacing.Factory.newInstance(); | |||||
if(spaceAfter >= 0) spc.addNewSpcPct().setVal((int)(spaceAfter*1000)); | |||||
else spc.addNewSpcPts().setVal((int)(-spaceAfter*100)); | |||||
pr.setSpcAft(spc); | |||||
} | |||||
/** | |||||
* The amount of vertical white space after the paragraph | |||||
* This may be specified in two different ways, percentage spacing and font point spacing: | |||||
* <p> | |||||
* If spaceBefore >= 0, then space is a percentage of normal line height. | |||||
* If spaceBefore < 0, the absolute value of linespacing is the spacing in points | |||||
* </p> | |||||
* | |||||
* @return the vertical white space after the paragraph | |||||
*/ | |||||
public double getSpaceAfter(){ | |||||
ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){ | |||||
public boolean fetch(CTTextParagraphProperties props){ | |||||
if(props.isSetSpcAft()){ | |||||
CTTextSpacing spc = props.getSpcAft(); | |||||
if(spc.isSetSpcPct()) setValue( spc.getSpcPct().getVal()*0.001 ); | |||||
else if (spc.isSetSpcPts()) setValue( -spc.getSpcPts().getVal()*0.01 ); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchParagraphProperty(fetcher); | |||||
return fetcher.getValue() == null ? 0 : fetcher.getValue(); | |||||
} | |||||
/** | |||||
* Specifies the particular level text properties that this paragraph will follow. | |||||
* The value for this attribute formats the text according to the corresponding level | |||||
* paragraph properties defined in the list of styles associated with the body of text | |||||
* that this paragraph belongs to (therefore in the parent shape). | |||||
* <p> | |||||
* Note that the closest properties object to the text is used, therefore if there is | |||||
* a conflict between the text paragraph properties and the list style properties for | |||||
* this level then the text paragraph properties will take precedence. | |||||
* </p> | |||||
* | |||||
* @param level the level (0 ... 4) | |||||
*/ | |||||
public void setLevel(int level){ | |||||
CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); | |||||
pr.setLvl(level); | |||||
} | |||||
/** | |||||
* Returns the level of text properties that this paragraph will follow. | |||||
* | |||||
* @return the text level of this paragraph (0-based). Default is 0. | |||||
*/ | |||||
public int getLevel(){ | |||||
CTTextParagraphProperties pr = _p.getPPr(); | |||||
if(pr == null) return 0; | |||||
return pr.getLvl(); | |||||
} | |||||
/** | |||||
* Returns whether this paragraph has bullets | |||||
*/ | |||||
public boolean isBullet() { | |||||
ParagraphPropertyFetcher<Boolean> fetcher = new ParagraphPropertyFetcher<Boolean>(getLevel()){ | |||||
public boolean fetch(CTTextParagraphProperties props){ | |||||
if(props.isSetBuNone()) { | |||||
setValue(false); | |||||
return true; | |||||
} | |||||
if(props.isSetBuFont() || props.isSetBuChar() || props.isSetBuAutoNum()){ | |||||
setValue(true); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchParagraphProperty(fetcher); | |||||
return fetcher.getValue() == null ? false : fetcher.getValue(); | |||||
} | |||||
/** | |||||
* Set or unset this paragraph as a bullet point | |||||
* | |||||
* @param flag whether text in this paragraph has bullets | |||||
*/ | |||||
public void setBullet(boolean flag) { | |||||
if(isBullet() == flag) return; | |||||
CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); | |||||
if(!flag) { | |||||
pr.addNewBuNone(); | |||||
if(pr.isSetBuAutoNum()) pr.unsetBuAutoNum(); | |||||
if(pr.isSetBuBlip()) pr.unsetBuBlip(); | |||||
if(pr.isSetBuChar()) pr.unsetBuChar(); | |||||
if(pr.isSetBuClr()) pr.unsetBuClr(); | |||||
if(pr.isSetBuClrTx()) pr.unsetBuClrTx(); | |||||
if(pr.isSetBuFont()) pr.unsetBuFont(); | |||||
if(pr.isSetBuFontTx()) pr.unsetBuFontTx(); | |||||
if(pr.isSetBuSzPct()) pr.unsetBuSzPct(); | |||||
if(pr.isSetBuSzPts()) pr.unsetBuSzPts(); | |||||
if(pr.isSetBuSzTx()) pr.unsetBuSzTx(); | |||||
} else { | |||||
if(pr.isSetBuNone()) pr.unsetBuNone(); | |||||
if(!pr.isSetBuFont()) pr.addNewBuFont().setTypeface("Arial"); | |||||
if(!pr.isSetBuAutoNum()) pr.addNewBuChar().setChar("\u2022"); | |||||
} | |||||
} | |||||
/** | |||||
* Set this paragraph as an automatic numbered bullet point | |||||
* | |||||
* @param scheme type of auto-numbering | |||||
* @param startAt the number that will start number for a given sequence of automatically | |||||
* numbered bullets (1-based). | |||||
*/ | |||||
public void setBullet(ListAutoNumber scheme, int startAt) { | |||||
if(startAt < 1) throw new IllegalArgumentException("Start Number must be greater or equal that 1") ; | |||||
CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); | |||||
CTTextAutonumberBullet lst = pr.isSetBuAutoNum() ? pr.getBuAutoNum() : pr.addNewBuAutoNum(); | |||||
lst.setType(STTextAutonumberScheme.Enum.forInt(scheme.ordinal() + 1)); | |||||
lst.setStartAt(startAt); | |||||
if(!pr.isSetBuFont()) pr.addNewBuFont().setTypeface("Arial"); | |||||
if(pr.isSetBuNone()) pr.unsetBuNone(); | |||||
// remove these elements if present as it results in invalid content when opening in Excel. | |||||
if(pr.isSetBuBlip()) pr.unsetBuBlip(); | |||||
if(pr.isSetBuChar()) pr.unsetBuChar(); | |||||
} | |||||
/** | |||||
* Set this paragraph as an automatic numbered bullet point | |||||
* | |||||
* @param scheme type of auto-numbering | |||||
*/ | |||||
public void setBullet(ListAutoNumber scheme) { | |||||
CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); | |||||
CTTextAutonumberBullet lst = pr.isSetBuAutoNum() ? pr.getBuAutoNum() : pr.addNewBuAutoNum(); | |||||
lst.setType(STTextAutonumberScheme.Enum.forInt(scheme.ordinal() + 1)); | |||||
if(!pr.isSetBuFont()) pr.addNewBuFont().setTypeface("Arial"); | |||||
if(pr.isSetBuNone()) pr.unsetBuNone(); | |||||
// remove these elements if present as it results in invalid content when opening in Excel. | |||||
if(pr.isSetBuBlip()) pr.unsetBuBlip(); | |||||
if(pr.isSetBuChar()) pr.unsetBuChar(); | |||||
} | |||||
/** | |||||
* Returns whether this paragraph has automatic numbered bullets | |||||
*/ | |||||
public boolean isBulletAutoNumber() { | |||||
ParagraphPropertyFetcher<Boolean> fetcher = new ParagraphPropertyFetcher<Boolean>(getLevel()){ | |||||
public boolean fetch(CTTextParagraphProperties props){ | |||||
if(props.isSetBuAutoNum()) { | |||||
setValue(true); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchParagraphProperty(fetcher); | |||||
return fetcher.getValue() == null ? false : fetcher.getValue(); | |||||
} | |||||
/** | |||||
* Returns the starting number if this paragraph has automatic numbered bullets, otherwise returns 0 | |||||
*/ | |||||
public int getBulletAutoNumberStart() { | |||||
ParagraphPropertyFetcher<Integer> fetcher = new ParagraphPropertyFetcher<Integer>(getLevel()){ | |||||
public boolean fetch(CTTextParagraphProperties props){ | |||||
if(props.isSetBuAutoNum() && props.getBuAutoNum().isSetStartAt()) { | |||||
setValue(props.getBuAutoNum().getStartAt()); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchParagraphProperty(fetcher); | |||||
return fetcher.getValue() == null ? 0 : fetcher.getValue(); | |||||
} | |||||
/** | |||||
* Returns the auto number scheme if this paragraph has automatic numbered bullets, otherwise returns ListAutoNumber.ARABIC_PLAIN | |||||
*/ | |||||
public ListAutoNumber getBulletAutoNumberScheme() { | |||||
ParagraphPropertyFetcher<ListAutoNumber> fetcher = new ParagraphPropertyFetcher<ListAutoNumber>(getLevel()){ | |||||
public boolean fetch(CTTextParagraphProperties props){ | |||||
if(props.isSetBuAutoNum()) { | |||||
setValue(ListAutoNumber.values()[props.getBuAutoNum().getType().intValue() - 1]); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchParagraphProperty(fetcher); | |||||
// Note: documentation does not define a default, return ListAutoNumber.ARABIC_PLAIN (1,2,3...) | |||||
return fetcher.getValue() == null ? ListAutoNumber.ARABIC_PLAIN : fetcher.getValue(); | |||||
} | |||||
@SuppressWarnings("rawtypes") | |||||
private boolean fetchParagraphProperty(ParagraphPropertyFetcher visitor){ | |||||
boolean ok = false; | |||||
if(_p.isSetPPr()) ok = visitor.fetch(_p.getPPr()); | |||||
if(!ok) { | |||||
ok = visitor.fetch(_shape); | |||||
} | |||||
return ok; | |||||
} | |||||
@Override | |||||
public String toString(){ | |||||
return "[" + getClass() + "]" + getText(); | |||||
} | |||||
} |
/* ==================================================================== | |||||
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.xssf.usermodel; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextFont; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextNormalAutofit; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.STTextStrikeType; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.STTextUnderlineType; | |||||
import java.awt.Color; | |||||
/** | |||||
* Represents a run of text within the containing text body. The run element is the | |||||
* lowest level text separation mechanism within a text body. | |||||
*/ | |||||
public class XSSFTextRun { | |||||
private final CTRegularTextRun _r; | |||||
private final XSSFTextParagraph _p; | |||||
XSSFTextRun(CTRegularTextRun r, XSSFTextParagraph p){ | |||||
_r = r; | |||||
_p = p; | |||||
} | |||||
XSSFTextParagraph getParentParagraph(){ | |||||
return _p; | |||||
} | |||||
public String getText(){ | |||||
return _r.getT(); | |||||
} | |||||
public void setText(String text){ | |||||
_r.setT(text); | |||||
} | |||||
public CTRegularTextRun getXmlObject(){ | |||||
return _r; | |||||
} | |||||
public void setFontColor(Color color){ | |||||
CTTextCharacterProperties rPr = getRPr(); | |||||
CTSolidColorFillProperties fill = rPr.isSetSolidFill() ? rPr.getSolidFill() : rPr.addNewSolidFill(); | |||||
CTSRgbColor clr = fill.isSetSrgbClr() ? fill.getSrgbClr() : fill.addNewSrgbClr(); | |||||
clr.setVal(new byte[]{(byte)color.getRed(), (byte)color.getGreen(), (byte)color.getBlue()}); | |||||
if(fill.isSetHslClr()) fill.unsetHslClr(); | |||||
if(fill.isSetPrstClr()) fill.unsetPrstClr(); | |||||
if(fill.isSetSchemeClr()) fill.unsetSchemeClr(); | |||||
if(fill.isSetScrgbClr()) fill.unsetScrgbClr(); | |||||
if(fill.isSetSysClr()) fill.unsetSysClr(); | |||||
} | |||||
public Color getFontColor(){ | |||||
CTTextCharacterProperties rPr = getRPr(); | |||||
if(rPr.isSetSolidFill()){ | |||||
CTSolidColorFillProperties fill = rPr.getSolidFill(); | |||||
if(fill.isSetSrgbClr()){ | |||||
CTSRgbColor clr = fill.getSrgbClr(); | |||||
byte[] rgb = clr.getVal(); | |||||
return new Color(0xFF & rgb[0], 0xFF & rgb[1], 0xFF & rgb[2]); | |||||
} | |||||
} | |||||
return new Color(0, 0, 0); | |||||
} | |||||
/** | |||||
* | |||||
* @param fontSize font size in points. | |||||
* The value of <code>-1</code> unsets the Sz attribute from the underlying xml bean | |||||
*/ | |||||
public void setFontSize(double fontSize){ | |||||
CTTextCharacterProperties rPr = getRPr(); | |||||
if(fontSize == -1.0) { | |||||
if(rPr.isSetSz()) rPr.unsetSz(); | |||||
} else { | |||||
if(fontSize < 1.0) { | |||||
throw new IllegalArgumentException("Minimum font size is 1pt but was " + fontSize); | |||||
} | |||||
rPr.setSz((int)(100*fontSize)); | |||||
} | |||||
} | |||||
/** | |||||
* @return font size in points or -1 if font size is not set. | |||||
*/ | |||||
public double getFontSize(){ | |||||
double scale = 1; | |||||
double size = XSSFFont.DEFAULT_FONT_SIZE; // default font size | |||||
CTTextNormalAutofit afit = getParentParagraph().getParentShape().getTxBody().getBodyPr().getNormAutofit(); | |||||
if(afit != null) scale = (double)afit.getFontScale() / 100000; | |||||
CTTextCharacterProperties rPr = getRPr(); | |||||
if(rPr.isSetSz()){ | |||||
size = rPr.getSz()*0.01; | |||||
} | |||||
return size * scale; | |||||
} | |||||
/** | |||||
* | |||||
* @return the spacing between characters within a text run, | |||||
* If this attribute is omitted then a value of 0 or no adjustment is assumed. | |||||
*/ | |||||
public double getCharacterSpacing(){ | |||||
CTTextCharacterProperties rPr = getRPr(); | |||||
if(rPr.isSetSpc()){ | |||||
return rPr.getSpc()*0.01; | |||||
} | |||||
return 0; | |||||
} | |||||
/** | |||||
* Set the spacing between characters within a text run. | |||||
* <p> | |||||
* The spacing is specified in points. Positive values will cause the text to expand, | |||||
* negative values to condense. | |||||
* </p> | |||||
* | |||||
* @param spc character spacing in points. | |||||
*/ | |||||
public void setCharacterSpacing(double spc){ | |||||
CTTextCharacterProperties rPr = getRPr(); | |||||
if(spc == 0.0) { | |||||
if(rPr.isSetSpc()) rPr.unsetSpc(); | |||||
} else { | |||||
rPr.setSpc((int)(100*spc)); | |||||
} | |||||
} | |||||
/** | |||||
* Specifies the typeface, or name of the font that is to be used for this text run. | |||||
* | |||||
* @param typeface the font to apply to this text run. | |||||
* The value of <code>null</code> unsets the Typeface attribute from the underlying xml. | |||||
*/ | |||||
public void setFont(String typeface){ | |||||
setFontFamily(typeface, (byte)-1, (byte)-1, false); | |||||
} | |||||
public void setFontFamily(String typeface, byte charset, byte pictAndFamily, boolean isSymbol){ | |||||
CTTextCharacterProperties rPr = getRPr(); | |||||
if(typeface == null){ | |||||
if(rPr.isSetLatin()) rPr.unsetLatin(); | |||||
if(rPr.isSetCs()) rPr.unsetCs(); | |||||
if(rPr.isSetSym()) rPr.unsetSym(); | |||||
} else { | |||||
if(isSymbol){ | |||||
CTTextFont font = rPr.isSetSym() ? rPr.getSym() : rPr.addNewSym(); | |||||
font.setTypeface(typeface); | |||||
} else { | |||||
CTTextFont latin = rPr.isSetLatin() ? rPr.getLatin() : rPr.addNewLatin(); | |||||
latin.setTypeface(typeface); | |||||
if(charset != -1) latin.setCharset(charset); | |||||
if(pictAndFamily != -1) latin.setPitchFamily(pictAndFamily); | |||||
} | |||||
} | |||||
} | |||||
/** | |||||
* @return font family or null if not set | |||||
*/ | |||||
public String getFontFamily(){ | |||||
CTTextCharacterProperties rPr = getRPr(); | |||||
CTTextFont font = rPr.getLatin(); | |||||
if(font != null){ | |||||
return font.getTypeface(); | |||||
} | |||||
return XSSFFont.DEFAULT_FONT_NAME; | |||||
} | |||||
public byte getPitchAndFamily(){ | |||||
CTTextCharacterProperties rPr = getRPr(); | |||||
CTTextFont font = rPr.getLatin(); | |||||
if(font != null){ | |||||
return font.getPitchFamily(); | |||||
} | |||||
return 0; | |||||
} | |||||
/** | |||||
* Specifies whether a run of text will be formatted as strikethrough text. | |||||
* | |||||
* @param strike whether a run of text will be formatted as strikethrough text. | |||||
*/ | |||||
public void setStrikethrough(boolean strike) { | |||||
getRPr().setStrike(strike ? STTextStrikeType.SNG_STRIKE : STTextStrikeType.NO_STRIKE); | |||||
} | |||||
/** | |||||
* @return whether a run of text will be formatted as strikethrough text. Default is false. | |||||
*/ | |||||
public boolean isStrikethrough() { | |||||
CTTextCharacterProperties rPr = getRPr(); | |||||
if(rPr.isSetStrike()){ | |||||
return rPr.getStrike() != STTextStrikeType.NO_STRIKE; | |||||
} | |||||
return false; | |||||
} | |||||
/** | |||||
* @return whether a run of text will be formatted as a superscript text. Default is false. | |||||
*/ | |||||
public boolean isSuperscript() { | |||||
CTTextCharacterProperties rPr = getRPr(); | |||||
if(rPr.isSetBaseline()){ | |||||
return rPr.getBaseline() > 0; | |||||
} | |||||
return false; | |||||
} | |||||
/** | |||||
* Set the baseline for both the superscript and subscript fonts. | |||||
* <p> | |||||
* The size is specified using a percentage. | |||||
* Positive values indicate superscript, negative values indicate subscript. | |||||
* </p> | |||||
* | |||||
* @param baselineOffset | |||||
*/ | |||||
public void setBaselineOffset(double baselineOffset){ | |||||
getRPr().setBaseline((int) baselineOffset * 1000); | |||||
} | |||||
/** | |||||
* Set whether the text in this run is formatted as superscript. | |||||
* Default base line offset is 30% | |||||
* | |||||
* @see #setBaselineOffset(double) | |||||
*/ | |||||
public void setSuperscript(boolean flag){ | |||||
setBaselineOffset(flag ? 30. : 0.); | |||||
} | |||||
/** | |||||
* Set whether the text in this run is formatted as subscript. | |||||
* Default base line offset is -25%. | |||||
* | |||||
* @see #setBaselineOffset(double) | |||||
*/ | |||||
public void setSubscript(boolean flag){ | |||||
setBaselineOffset(flag ? -25.0 : 0.); | |||||
} | |||||
/** | |||||
* @return whether a run of text will be formatted as a superscript text. Default is false. | |||||
*/ | |||||
public boolean isSubscript() { | |||||
CTTextCharacterProperties rPr = getRPr(); | |||||
if(rPr.isSetBaseline()){ | |||||
return rPr.getBaseline() < 0; | |||||
} | |||||
return false; | |||||
} | |||||
/** | |||||
* @return whether a run of text will be formatted as a superscript text. Default is false. | |||||
*/ | |||||
public TextCap getTextCap() { | |||||
CTTextCharacterProperties rPr = getRPr(); | |||||
if(rPr.isSetCap()){ | |||||
return TextCap.values()[rPr.getCap().intValue() - 1]; | |||||
} | |||||
return TextCap.NONE; | |||||
} | |||||
/** | |||||
* Specifies whether this run of text will be formatted as bold text | |||||
* | |||||
* @param bold whether this run of text will be formatted as bold text | |||||
*/ | |||||
public void setBold(boolean bold){ | |||||
getRPr().setB(bold); | |||||
} | |||||
/** | |||||
* @return whether this run of text is formatted as bold text | |||||
*/ | |||||
public boolean isBold(){ | |||||
CTTextCharacterProperties rPr = getRPr(); | |||||
if(rPr.isSetB()){ | |||||
return rPr.getB(); | |||||
} | |||||
return false; | |||||
} | |||||
/** | |||||
* @param italic whether this run of text is formatted as italic text | |||||
*/ | |||||
public void setItalic(boolean italic){ | |||||
getRPr().setI(italic); | |||||
} | |||||
/** | |||||
* @return whether this run of text is formatted as italic text | |||||
*/ | |||||
public boolean isItalic(){ | |||||
CTTextCharacterProperties rPr = getRPr(); | |||||
if(rPr.isSetI()){ | |||||
return rPr.getI(); | |||||
} | |||||
return false; | |||||
} | |||||
/** | |||||
* @param underline whether this run of text is formatted as underlined text | |||||
*/ | |||||
public void setUnderline(boolean underline) { | |||||
getRPr().setU(underline ? STTextUnderlineType.SNG : STTextUnderlineType.NONE); | |||||
} | |||||
/** | |||||
* @return whether this run of text is formatted as underlined text | |||||
*/ | |||||
public boolean isUnderline(){ | |||||
CTTextCharacterProperties rPr = getRPr(); | |||||
if(rPr.isSetU()){ | |||||
return rPr.getU() != STTextUnderlineType.NONE; | |||||
} | |||||
return false; | |||||
} | |||||
protected CTTextCharacterProperties getRPr(){ | |||||
return _r.isSetRPr() ? _r.getRPr() : _r.addNewRPr(); | |||||
} | |||||
@Override | |||||
public String toString(){ | |||||
return "[" + getClass() + "]" + getText(); | |||||
} | |||||
} |