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

427 lines
15 KiB
Java
Executable File

/*
* ====================================================================
* 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.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D;
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.STShapeType;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextAnchoringType;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextWrappingType;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextVerticalType;
import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
import org.openxmlformats.schemas.presentationml.x2006.main.CTShapeNonVisual;
import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
/**
* Represents a preset geometric shape.
*
* @author Yegor Kozlov
*/
@Beta
public class XSLFAutoShape extends XSLFSimpleShape {
private final List<XSLFTextParagraph> _paragraphs;
/*package*/ XSLFAutoShape(CTShape shape, XSLFSheet sheet) {
super(shape, sheet);
_paragraphs = new ArrayList<XSLFTextParagraph>();
if (shape.isSetTxBody()) {
CTTextBody txBody = shape.getTxBody();
for (CTTextParagraph p : txBody.getPList()) {
_paragraphs.add(new XSLFTextParagraph(p));
}
}
}
/*package*/
static XSLFAutoShape create(CTShape shape, XSLFSheet sheet) {
if (shape.getSpPr().isSetCustGeom()) {
return new XSLFFreeformShape(shape, sheet);
} else if (shape.getNvSpPr().getCNvSpPr().isSetTxBox()) {
return new XSLFTextBox(shape, sheet);
} else {
return new XSLFAutoShape(shape, sheet);
}
}
// 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() {
CTShape shape = (CTShape) getXmlObject();
CTTextBody txBody;
if (!shape.isSetTxBody()) {
txBody = shape.addNewTxBody();
txBody.addNewBodyPr();
txBody.addNewLstStyle();
} else {
txBody = shape.getTxBody();
}
CTTextParagraph p = txBody.addNewP();
XSLFTextParagraph paragraph = new XSLFTextParagraph(p);
_paragraphs.add(paragraph);
return paragraph;
}
/**
* @param shapeId 1-based shapeId
*/
static CTShape prototype(int shapeId) {
CTShape ct = CTShape.Factory.newInstance();
CTShapeNonVisual nvSpPr = ct.addNewNvSpPr();
CTNonVisualDrawingProps cnv = nvSpPr.addNewCNvPr();
cnv.setName("AutoShape " + shapeId);
cnv.setId(shapeId + 1);
nvSpPr.addNewCNvSpPr();
nvSpPr.addNewNvPr();
CTShapeProperties spPr = ct.addNewSpPr();
CTPresetGeometry2D prst = spPr.addNewPrstGeom();
prst.setPrst(STShapeType.RECT);
prst.addNewAvLst();
return ct;
}
/**
* 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 VerticalAlignment#TOP}
*/
public void setVerticalAlignment(VerticalAlignment anchor){
CTShape shape = (CTShape) getXmlObject();
if (shape.isSetTxBody()) {
CTTextBodyProperties bodyPr = shape.getTxBody().getBodyPr();
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(){
CTShape shape = (CTShape) getXmlObject();
if (shape.isSetTxBody()) {
STTextAnchoringType.Enum val = shape.getTxBody().getBodyPr().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){
CTShape shape = (CTShape) getXmlObject();
if (shape.isSetTxBody()) {
CTTextBodyProperties bodyPr = shape.getTxBody().getBodyPr();
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(){
CTShape shape = (CTShape) getXmlObject();
if (shape.isSetTxBody()) {
STTextVerticalType.Enum val = shape.getTxBody().getBodyPr().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(){
CTShape shape = (CTShape) getXmlObject();
if (shape.isSetTxBody()) {
CTTextBodyProperties bodyPr = shape.getTxBody().getBodyPr();
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(){
CTShape shape = (CTShape) getXmlObject();
if (shape.isSetTxBody()) {
CTTextBodyProperties bodyPr = shape.getTxBody().getBodyPr();
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(){
CTShape shape = (CTShape) getXmlObject();
if (shape.isSetTxBody()) {
CTTextBodyProperties bodyPr = shape.getTxBody().getBodyPr();
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(){
CTShape shape = (CTShape) getXmlObject();
if (shape.isSetTxBody()) {
CTTextBodyProperties bodyPr = shape.getTxBody().getBodyPr();
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){
CTShape shape = (CTShape) getXmlObject();
if (shape.isSetTxBody()) {
CTTextBodyProperties bodyPr = shape.getTxBody().getBodyPr();
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){
CTShape shape = (CTShape) getXmlObject();
if (shape.isSetTxBody()) {
CTTextBodyProperties bodyPr = shape.getTxBody().getBodyPr();
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){
CTShape shape = (CTShape) getXmlObject();
if (shape.isSetTxBody()) {
CTTextBodyProperties bodyPr = shape.getTxBody().getBodyPr();
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){
CTShape shape = (CTShape) getXmlObject();
if (shape.isSetTxBody()) {
CTTextBodyProperties bodyPr = shape.getTxBody().getBodyPr();
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(){
CTShape shape = (CTShape) getXmlObject();
if (shape.isSetTxBody()) {
return shape.getTxBody().getBodyPr().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){
CTShape shape = (CTShape) getXmlObject();
if (shape.isSetTxBody()) {
shape.getTxBody().getBodyPr().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){
CTShape shape = (CTShape) getXmlObject();
if (shape.isSetTxBody()) {
CTTextBodyProperties bodyPr = shape.getTxBody().getBodyPr();
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(){
CTShape shape = (CTShape) getXmlObject();
if (shape.isSetTxBody()) {
CTTextBodyProperties bodyPr = shape.getTxBody().getBodyPr();
if(bodyPr.isSetNoAutofit()) return TextAutofit.NONE;
else if (bodyPr.isSetNormAutofit()) return TextAutofit.NORMAL;
else if (bodyPr.isSetSpAutoFit()) return TextAutofit.SHAPE;
}
return TextAutofit.NORMAL;
}
@Override
void onCopy(XSLFSheet srcSheet){
CTShape shape = (CTShape) getXmlObject();
if (!shape.isSetTxBody()) return;
CTPlaceholder ph = shape.getNvSpPr().getNvPr().getPh();
if(ph == null || !ph.isSetType()) return;
if(ph.getType() == STPlaceholderType.TITLE){
}
}
}