poi/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java

365 lines
12 KiB
Java

/*
* ====================================================================
* 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.xslf.usermodel;
import org.apache.poi.util.Beta;
import org.apache.poi.util.Units;
import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBodyProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextAnchoringType;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextVerticalType;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextWrappingType;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
/**
* Represents a shape that can hold text.
*
* @author Yegor Kozlov
*/
@Beta
public abstract class XSLFTextShape extends XSLFSimpleShape {
private final List<XSLFTextParagraph> _paragraphs;
/*package*/ XSLFTextShape(XmlObject shape, XSLFSheet sheet) {
super(shape, sheet);
_paragraphs = new ArrayList<XSLFTextParagraph>();
CTTextBody txBody = getTextBody(false);
if (txBody != null) {
for (CTTextParagraph p : txBody.getPList()) {
_paragraphs.add(new XSLFTextParagraph(p, this));
}
}
}
// textual properties
public String getText() {
StringBuilder out = new StringBuilder();
for (XSLFTextParagraph p : _paragraphs) {
if (out.length() > 0) out.append('\n');
out.append(p.getText());
}
return out.toString();
}
public List<XSLFTextParagraph> getTextParagraphs() {
return _paragraphs;
}
public XSLFTextParagraph addNewTextParagraph() {
CTTextBody txBody = getTextBody(true);
CTTextParagraph p = txBody.addNewP();
XSLFTextParagraph paragraph = new XSLFTextParagraph(p, this);
_paragraphs.add(paragraph);
return paragraph;
}
/**
* Specifies a solid color fill. The shape is filled entirely with the specified color.
*
* @param color the solid color fill.
* The value of <code>null</code> unsets the solidFIll attribute from the underlying xml
*/
public void setFillColor(Color color) {
CTShapeProperties spPr = getSpPr();
if (color == null) {
if(spPr.isSetSolidFill()) spPr.unsetSolidFill();
}
else {
CTSolidColorFillProperties fill = spPr.isSetSolidFill() ? spPr.getSolidFill() : spPr.addNewSolidFill();
CTSRgbColor rgb = CTSRgbColor.Factory.newInstance();
rgb.setVal(new byte[]{(byte) color.getRed(), (byte) color.getGreen(), (byte) color.getBlue()});
fill.setSrgbClr(rgb);
}
}
/**
*
* @return solid fill color of null if not set
*/
public Color getFillColor(){
CTShapeProperties spPr = getSpPr();
if(!spPr.isSetSolidFill() ) return null;
CTSolidColorFillProperties fill = spPr.getSolidFill();
if(!fill.isSetSrgbClr()) {
// TODO for now return null for all colors except explicit RGB
return null;
}
byte[] val = fill.getSrgbClr().getVal();
return new Color(0xFF & val[0], 0xFF & val[1], 0xFF & val[2]);
}
/**
* Sets the type of vertical alignment for the text.
* One of the <code>Anchor*</code> constants defined in this class.
*
* @param anchor - the type of alignment. Default is {@link org.apache.poi.xslf.usermodel.VerticalAlignment#TOP}
*/
public void setVerticalAlignment(VerticalAlignment anchor){
CTTextBodyProperties bodyPr = getTextBodyPr();
if (bodyPr != null) {
if(anchor == null) {
if(bodyPr.isSetAnchor()) bodyPr.unsetAnchor();
} else {
bodyPr.setAnchor(STTextAnchoringType.Enum.forInt(anchor.ordinal() + 1));
}
}
}
/**
* Returns the type of vertical alignment for the text.
*
* @return the type of alignment
*/
public VerticalAlignment getVerticalAlignment(){
CTTextBodyProperties bodyPr = getTextBodyPr();
if (bodyPr != null) {
STTextAnchoringType.Enum val = bodyPr.getAnchor();
if(val != null){
return VerticalAlignment.values()[val.intValue() - 1];
}
}
return VerticalAlignment.TOP;
}
/**
*
* @param orientation vertical orientation of the text
*/
public void setTextDirection(TextDirection orientation){
CTTextBodyProperties bodyPr = getTextBodyPr();
if (bodyPr != null) {
if(orientation == null) {
if(bodyPr.isSetVert()) bodyPr.unsetVert();
} else {
bodyPr.setVert(STTextVerticalType.Enum.forInt(orientation.ordinal() + 1));
}
}
}
/**
* @return vertical orientation of the text
*/
public TextDirection getTextDirection(){
CTTextBodyProperties bodyPr = getTextBodyPr();
if (bodyPr != null) {
STTextVerticalType.Enum val = bodyPr.getVert();
if(val != null){
return TextDirection.values()[val.intValue() - 1];
}
}
return TextDirection.HORIZONTAL;
}
/**
* Returns the distance (in points) between the bottom of the text frame
* and the bottom of the inscribed rectangle of the shape that contains the text.
*
* @return the bottom margin or -1 if not set
*/
public double getMarginBottom(){
CTTextBodyProperties bodyPr = getTextBodyPr();
if (bodyPr != null) {
return bodyPr.isSetBIns() ? Units.toPoints(bodyPr.getBIns()) : -1;
}
return -1;
}
/**
* Returns the distance (in points) between the left edge of the text frame
* and the left edge of the inscribed rectangle of the shape that contains
* the text.
*
* @return the left margin
*/
public double getMarginLeft(){
CTTextBodyProperties bodyPr = getTextBodyPr();
if (bodyPr != null) {
return bodyPr.isSetLIns() ? Units.toPoints(bodyPr.getLIns()) : -1;
}
return -1;
}
/**
* Returns the distance (in points) between the right edge of the
* text frame and the right edge of the inscribed rectangle of the shape
* that contains the text.
*
* @return the right margin
*/
public double getMarginRight(){
CTTextBodyProperties bodyPr = getTextBodyPr();
if (bodyPr != null) {
return bodyPr.isSetRIns() ? Units.toPoints(bodyPr.getRIns()) : -1;
}
return -1;
}
/**
* Returns the distance (in points) between the top of the text frame
* and the top of the inscribed rectangle of the shape that contains the text.
*
* @return the top margin
*/
public double getMarginTop(){
CTTextBodyProperties bodyPr = getTextBodyPr();
if (bodyPr != null) {
return bodyPr.isSetTIns() ? Units.toPoints(bodyPr.getTIns()) : -1;
}
return -1;
}
/**
* Sets the botom margin.
* @see #getMarginBottom()
*
* @param margin the bottom margin
*/
public void setMarginBottom(double margin){
CTTextBodyProperties bodyPr = getTextBodyPr();
if (bodyPr != null) {
if(margin == -1) bodyPr.unsetBIns();
else bodyPr.setBIns(Units.toEMU(margin));
}
}
/**
* Sets the left margin.
* @see #getMarginLeft()
*
* @param margin the left margin
*/
public void setMarginLeft(double margin){
CTTextBodyProperties bodyPr = getTextBodyPr();
if (bodyPr != null) {
if(margin == -1) bodyPr.unsetLIns();
else bodyPr.setLIns(Units.toEMU(margin));
}
}
/**
* Sets the right margin.
* @see #getMarginRight()
*
* @param margin the right margin
*/
public void setMarginRight(double margin){
CTTextBodyProperties bodyPr = getTextBodyPr();
if (bodyPr != null) {
if(margin == -1) bodyPr.unsetRIns();
else bodyPr.setRIns(Units.toEMU(margin));
}
}
/**
* Sets the top margin.
* @see #getMarginTop()
*
* @param margin the top margin
*/
public void setMarginTop(double margin){
CTTextBodyProperties bodyPr = getTextBodyPr();
if (bodyPr != null) {
if(margin == -1) bodyPr.unsetTIns();
else bodyPr.setTIns(Units.toEMU(margin));
}
}
/**
* Returns the value indicating word wrap.
* One of the <code>Wrap*</code> constants defined in this class.
*
* @return the value indicating word wrap
*/
public boolean getWordWrap(){
CTTextBodyProperties bodyPr = getTextBodyPr();
if (bodyPr != null) {
return bodyPr.getWrap() == STTextWrappingType.SQUARE;
}
return false;
}
/**
* Specifies how the text should be wrapped
*
* @param wrap the value indicating how the text should be wrapped
*/
public void setWordWrap(boolean wrap){
CTTextBodyProperties bodyPr = getTextBodyPr();
if (bodyPr != null) {
bodyPr.setWrap(wrap ? STTextWrappingType.SQUARE : STTextWrappingType.NONE);
}
}
/**
*
* 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
*
* @param value type of autofit
*/
public void setTextAutofit(TextAutofit value){
CTTextBodyProperties bodyPr = getTextBodyPr();
if (bodyPr != null) {
if(bodyPr.isSetSpAutoFit()) bodyPr.unsetSpAutoFit();
if(bodyPr.isSetNoAutofit()) bodyPr.unsetNoAutofit();
if(bodyPr.isSetNormAutofit()) bodyPr.unsetNormAutofit();
switch(value){
case NONE: bodyPr.addNewNoAutofit(); break;
case NORMAL: bodyPr.addNewNormAutofit(); break;
case SHAPE: bodyPr.addNewSpAutoFit(); break;
}
}
}
/**
*
* @return type of autofit
*/
public TextAutofit getTextAutofit(){
CTTextBodyProperties bodyPr = getTextBodyPr();
if (bodyPr != null) {
if(bodyPr.isSetNoAutofit()) return TextAutofit.NONE;
else if (bodyPr.isSetNormAutofit()) return TextAutofit.NORMAL;
else if (bodyPr.isSetSpAutoFit()) return TextAutofit.SHAPE;
}
return TextAutofit.NORMAL;
}
protected CTTextBodyProperties getTextBodyPr(){
CTTextBody textBody = getTextBody(false);
return textBody == null ? null : textBody.getBodyPr();
}
protected abstract CTTextBody getTextBody(boolean create);
}