690 lines
23 KiB
Java
690 lines
23 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 java.awt.geom.Rectangle2D;
|
|
import java.util.ArrayList;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
|
|
import org.apache.poi.POIXMLException;
|
|
import org.apache.poi.sl.draw.DrawFactory;
|
|
import org.apache.poi.sl.draw.DrawTextShape;
|
|
import org.apache.poi.sl.usermodel.Insets2D;
|
|
import org.apache.poi.sl.usermodel.Placeholder;
|
|
import org.apache.poi.sl.usermodel.TextShape;
|
|
import org.apache.poi.sl.usermodel.VerticalAlignment;
|
|
import org.apache.poi.util.Beta;
|
|
import org.apache.poi.util.Units;
|
|
import org.apache.poi.xslf.model.PropertyFetcher;
|
|
import org.apache.poi.xslf.model.TextBodyPropertyFetcher;
|
|
import org.apache.xmlbeans.XmlObject;
|
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody;
|
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBodyProperties;
|
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;
|
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextListStyle;
|
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph;
|
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties;
|
|
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 org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
|
|
|
|
/**
|
|
* Represents a shape that can hold text.
|
|
*/
|
|
@Beta
|
|
public abstract class XSLFTextShape extends XSLFSimpleShape
|
|
implements TextShape<XSLFShape,XSLFTextParagraph> {
|
|
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.getPArray()) {
|
|
_paragraphs.add(newTextParagraph(p));
|
|
}
|
|
}
|
|
}
|
|
|
|
public Iterator<XSLFTextParagraph> iterator(){
|
|
return getTextParagraphs().iterator();
|
|
}
|
|
|
|
@Override
|
|
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();
|
|
}
|
|
|
|
/**
|
|
* unset text from this shape
|
|
*/
|
|
public void clearText(){
|
|
_paragraphs.clear();
|
|
CTTextBody txBody = getTextBody(true);
|
|
txBody.setPArray(null); // remove any existing paragraphs
|
|
}
|
|
|
|
@Override
|
|
public XSLFTextRun setText(String text) {
|
|
// calling clearText or setting to a new Array leads to a XmlValueDisconnectedException
|
|
if (!_paragraphs.isEmpty()) {
|
|
CTTextBody txBody = getTextBody(false);
|
|
int cntPs = txBody.sizeOfPArray();
|
|
for (int i = cntPs; i > 1; i--) {
|
|
txBody.removeP(i-1);
|
|
_paragraphs.remove(i-1);
|
|
}
|
|
|
|
_paragraphs.get(0).clearButKeepProperties();
|
|
}
|
|
|
|
return appendText(text, false);
|
|
}
|
|
|
|
@Override
|
|
public XSLFTextRun appendText(String text, boolean newParagraph) {
|
|
if (text == null) return null;
|
|
|
|
// copy properties from last paragraph / textrun or paragraph end marker
|
|
CTTextParagraphProperties otherPPr = null;
|
|
CTTextCharacterProperties otherRPr = null;
|
|
|
|
boolean firstPara;
|
|
XSLFTextParagraph para;
|
|
if (_paragraphs.isEmpty()) {
|
|
firstPara = false;
|
|
para = null;
|
|
} else {
|
|
firstPara = !newParagraph;
|
|
para = _paragraphs.get(_paragraphs.size()-1);
|
|
CTTextParagraph ctp = para.getXmlObject();
|
|
otherPPr = ctp.getPPr();
|
|
List<XSLFTextRun> runs = para.getTextRuns();
|
|
if (!runs.isEmpty()) {
|
|
XSLFTextRun r0 = runs.get(runs.size()-1);
|
|
otherRPr = r0.getRPr(false);
|
|
if (otherRPr == null) {
|
|
otherRPr = ctp.getEndParaRPr();
|
|
}
|
|
}
|
|
// don't copy endParaRPr to the run in case there aren't any other runs
|
|
// this is the case when setText() was called initially
|
|
// otherwise the master style will be overridden/ignored
|
|
}
|
|
|
|
XSLFTextRun run = null;
|
|
for (String lineTxt : text.split("\\r\\n?|\\n")) {
|
|
if (!firstPara) {
|
|
if (para != null) {
|
|
CTTextParagraph ctp = para.getXmlObject();
|
|
CTTextCharacterProperties unexpectedRPr = ctp.getEndParaRPr();
|
|
if (unexpectedRPr != null && unexpectedRPr != otherRPr) {
|
|
ctp.unsetEndParaRPr();
|
|
}
|
|
}
|
|
para = addNewTextParagraph();
|
|
if (otherPPr != null) {
|
|
para.getXmlObject().setPPr(otherPPr);
|
|
}
|
|
}
|
|
boolean firstRun = true;
|
|
for (String runText : lineTxt.split("[\u000b]")) {
|
|
if (!firstRun) {
|
|
para.addLineBreak();
|
|
}
|
|
run = para.addNewTextRun();
|
|
run.setText(runText);
|
|
if (otherRPr != null) {
|
|
run.getRPr(true).set(otherRPr);
|
|
}
|
|
firstRun = false;
|
|
}
|
|
firstPara = false;
|
|
}
|
|
|
|
assert(run != null);
|
|
return run;
|
|
}
|
|
|
|
@Override
|
|
public List<XSLFTextParagraph> getTextParagraphs() {
|
|
return _paragraphs;
|
|
}
|
|
|
|
/**
|
|
* add a new paragraph run to this shape
|
|
*
|
|
* @return created paragraph run
|
|
*/
|
|
public XSLFTextParagraph addNewTextParagraph() {
|
|
CTTextBody txBody = getTextBody(false);
|
|
CTTextParagraph p;
|
|
if (txBody == null) {
|
|
txBody = getTextBody(true);
|
|
p = txBody.getPArray(0);
|
|
p.removeR(0);
|
|
} else {
|
|
p = txBody.addNewP();
|
|
}
|
|
XSLFTextParagraph paragraph = newTextParagraph(p);
|
|
_paragraphs.add(paragraph);
|
|
return paragraph;
|
|
}
|
|
|
|
@Override
|
|
public void setVerticalAlignment(VerticalAlignment anchor){
|
|
CTTextBodyProperties bodyPr = getTextBodyPr(true);
|
|
if (bodyPr != null) {
|
|
if(anchor == null) {
|
|
if(bodyPr.isSetAnchor()) bodyPr.unsetAnchor();
|
|
} else {
|
|
bodyPr.setAnchor(STTextAnchoringType.Enum.forInt(anchor.ordinal() + 1));
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public VerticalAlignment getVerticalAlignment(){
|
|
PropertyFetcher<VerticalAlignment> fetcher = new TextBodyPropertyFetcher<VerticalAlignment>(){
|
|
public boolean fetch(CTTextBodyProperties props){
|
|
if(props.isSetAnchor()){
|
|
int val = props.getAnchor().intValue();
|
|
setValue(VerticalAlignment.values()[val - 1]);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
};
|
|
fetchShapeProperty(fetcher);
|
|
return fetcher.getValue() == null ? VerticalAlignment.TOP : fetcher.getValue();
|
|
}
|
|
|
|
@Override
|
|
public void setHorizontalCentered(Boolean isCentered){
|
|
CTTextBodyProperties bodyPr = getTextBodyPr(true);
|
|
if (bodyPr != null) {
|
|
if (isCentered == null) {
|
|
if (bodyPr.isSetAnchorCtr()) bodyPr.unsetAnchorCtr();
|
|
} else {
|
|
bodyPr.setAnchorCtr(isCentered);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean isHorizontalCentered(){
|
|
PropertyFetcher<Boolean> fetcher = new TextBodyPropertyFetcher<Boolean>(){
|
|
public boolean fetch(CTTextBodyProperties props){
|
|
if(props.isSetAnchorCtr()){
|
|
setValue(props.getAnchorCtr());
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
};
|
|
fetchShapeProperty(fetcher);
|
|
return fetcher.getValue() == null ? false : fetcher.getValue();
|
|
}
|
|
|
|
@Override
|
|
public void setTextDirection(TextDirection orientation){
|
|
CTTextBodyProperties bodyPr = getTextBodyPr(true);
|
|
if (bodyPr != null) {
|
|
if(orientation == null) {
|
|
if(bodyPr.isSetVert()) bodyPr.unsetVert();
|
|
} else {
|
|
bodyPr.setVert(STTextVerticalType.Enum.forInt(orientation.ordinal() + 1));
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public TextDirection getTextDirection(){
|
|
CTTextBodyProperties bodyPr = getTextBodyPr();
|
|
if (bodyPr != null) {
|
|
STTextVerticalType.Enum val = bodyPr.getVert();
|
|
if(val != null) {
|
|
switch (val.intValue()) {
|
|
default:
|
|
case STTextVerticalType.INT_HORZ:
|
|
return TextDirection.HORIZONTAL;
|
|
case STTextVerticalType.INT_EA_VERT:
|
|
case STTextVerticalType.INT_MONGOLIAN_VERT:
|
|
case STTextVerticalType.INT_VERT:
|
|
return TextDirection.VERTICAL;
|
|
case STTextVerticalType.INT_VERT_270:
|
|
return TextDirection.VERTICAL_270;
|
|
case STTextVerticalType.INT_WORD_ART_VERT_RTL:
|
|
case STTextVerticalType.INT_WORD_ART_VERT:
|
|
return TextDirection.STACKED;
|
|
}
|
|
}
|
|
}
|
|
return TextDirection.HORIZONTAL;
|
|
}
|
|
|
|
@Override
|
|
public Double getTextRotation() {
|
|
CTTextBodyProperties bodyPr = getTextBodyPr();
|
|
if (bodyPr != null && bodyPr.isSetRot()) {
|
|
return bodyPr.getRot() / 60000.;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public void setTextRotation(Double rotation) {
|
|
CTTextBodyProperties bodyPr = getTextBodyPr(true);
|
|
if (bodyPr != null) {
|
|
bodyPr.setRot((int)(rotation * 60000.));
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* 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 inset in points
|
|
*/
|
|
public double getBottomInset(){
|
|
PropertyFetcher<Double> fetcher = new TextBodyPropertyFetcher<Double>(){
|
|
public boolean fetch(CTTextBodyProperties props){
|
|
if(props.isSetBIns()){
|
|
double val = Units.toPoints(props.getBIns());
|
|
setValue(val);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
};
|
|
fetchShapeProperty(fetcher);
|
|
// If this attribute is omitted, then a value of 0.05 inches is implied
|
|
return fetcher.getValue() == null ? 3.6 : fetcher.getValue();
|
|
}
|
|
|
|
/**
|
|
* 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 inset in points
|
|
*/
|
|
public double getLeftInset(){
|
|
PropertyFetcher<Double> fetcher = new TextBodyPropertyFetcher<Double>(){
|
|
public boolean fetch(CTTextBodyProperties props){
|
|
if(props.isSetLIns()){
|
|
double val = Units.toPoints(props.getLIns());
|
|
setValue(val);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
};
|
|
fetchShapeProperty(fetcher);
|
|
// If this attribute is omitted, then a value of 0.1 inches is implied
|
|
return fetcher.getValue() == null ? 7.2 : fetcher.getValue();
|
|
}
|
|
|
|
/**
|
|
* 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 inset in points
|
|
*/
|
|
public double getRightInset(){
|
|
PropertyFetcher<Double> fetcher = new TextBodyPropertyFetcher<Double>(){
|
|
public boolean fetch(CTTextBodyProperties props){
|
|
if(props.isSetRIns()){
|
|
double val = Units.toPoints(props.getRIns());
|
|
setValue(val);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
};
|
|
fetchShapeProperty(fetcher);
|
|
// If this attribute is omitted, then a value of 0.1 inches is implied
|
|
return fetcher.getValue() == null ? 7.2 : fetcher.getValue();
|
|
}
|
|
|
|
/**
|
|
* 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 inset in points
|
|
*/
|
|
public double getTopInset(){
|
|
PropertyFetcher<Double> fetcher = new TextBodyPropertyFetcher<Double>(){
|
|
public boolean fetch(CTTextBodyProperties props){
|
|
if(props.isSetTIns()){
|
|
double val = Units.toPoints(props.getTIns());
|
|
setValue(val);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
};
|
|
fetchShapeProperty(fetcher);
|
|
// If this attribute is omitted, then a value of 0.05 inches is implied
|
|
return fetcher.getValue() == null ? 3.6 : fetcher.getValue();
|
|
}
|
|
|
|
/**
|
|
* Sets the bottom margin.
|
|
* @see #getBottomInset()
|
|
*
|
|
* @param margin the bottom margin
|
|
*/
|
|
public void setBottomInset(double margin){
|
|
CTTextBodyProperties bodyPr = getTextBodyPr(true);
|
|
if (bodyPr != null) {
|
|
if(margin == -1) bodyPr.unsetBIns();
|
|
else bodyPr.setBIns(Units.toEMU(margin));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets the left margin.
|
|
* @see #getLeftInset()
|
|
*
|
|
* @param margin the left margin
|
|
*/
|
|
public void setLeftInset(double margin){
|
|
CTTextBodyProperties bodyPr = getTextBodyPr(true);
|
|
if (bodyPr != null) {
|
|
if(margin == -1) bodyPr.unsetLIns();
|
|
else bodyPr.setLIns(Units.toEMU(margin));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets the right margin.
|
|
* @see #getRightInset()
|
|
*
|
|
* @param margin the right margin
|
|
*/
|
|
public void setRightInset(double margin){
|
|
CTTextBodyProperties bodyPr = getTextBodyPr(true);
|
|
if (bodyPr != null) {
|
|
if(margin == -1) bodyPr.unsetRIns();
|
|
else bodyPr.setRIns(Units.toEMU(margin));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets the top margin.
|
|
* @see #getTopInset()
|
|
*
|
|
* @param margin the top margin
|
|
*/
|
|
public void setTopInset(double margin){
|
|
CTTextBodyProperties bodyPr = getTextBodyPr(true);
|
|
if (bodyPr != null) {
|
|
if(margin == -1) bodyPr.unsetTIns();
|
|
else bodyPr.setTIns(Units.toEMU(margin));
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public Insets2D getInsets() {
|
|
Insets2D insets = new Insets2D(getTopInset(), getLeftInset(), getBottomInset(), getRightInset());
|
|
return insets;
|
|
}
|
|
|
|
@Override
|
|
public void setInsets(Insets2D insets) {
|
|
setTopInset(insets.top);
|
|
setLeftInset(insets.left);
|
|
setBottomInset(insets.bottom);
|
|
setRightInset(insets.right);
|
|
}
|
|
|
|
@Override
|
|
public boolean getWordWrap(){
|
|
PropertyFetcher<Boolean> fetcher = new TextBodyPropertyFetcher<Boolean>(){
|
|
public boolean fetch(CTTextBodyProperties props){
|
|
if(props.isSetWrap()){
|
|
setValue(props.getWrap() == STTextWrappingType.SQUARE);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
};
|
|
fetchShapeProperty(fetcher);
|
|
return fetcher.getValue() == null ? true : fetcher.getValue();
|
|
}
|
|
|
|
@Override
|
|
public void setWordWrap(boolean wrap){
|
|
CTTextBodyProperties bodyPr = getTextBodyPr(true);
|
|
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(true);
|
|
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(){
|
|
return getTextBodyPr(false);
|
|
}
|
|
|
|
protected CTTextBodyProperties getTextBodyPr(boolean create) {
|
|
CTTextBody textBody = getTextBody(create);
|
|
if (textBody == null) {
|
|
return null;
|
|
}
|
|
CTTextBodyProperties textBodyPr = textBody.getBodyPr();
|
|
if (textBodyPr == null && create) {
|
|
textBodyPr = textBody.addNewBodyPr();
|
|
}
|
|
return textBodyPr;
|
|
}
|
|
|
|
protected abstract CTTextBody getTextBody(boolean create);
|
|
|
|
@Override
|
|
public void setPlaceholder(Placeholder placeholder) {
|
|
super.setPlaceholder(placeholder);
|
|
}
|
|
|
|
public Placeholder getTextType(){
|
|
CTPlaceholder ph = getCTPlaceholder();
|
|
if (ph == null) return null;
|
|
|
|
int val = ph.getType().intValue();
|
|
return Placeholder.lookupOoxml(val);
|
|
}
|
|
|
|
@Override
|
|
public double getTextHeight(){
|
|
DrawFactory drawFact = DrawFactory.getInstance(null);
|
|
DrawTextShape dts = drawFact.getDrawable(this);
|
|
return dts.getTextHeight();
|
|
}
|
|
|
|
/**
|
|
* Adjust the size of the shape so it encompasses the text inside it.
|
|
*
|
|
* @return a <code>Rectangle2D</code> that is the bounds of this shape.
|
|
*/
|
|
public Rectangle2D resizeToFitText(){
|
|
Rectangle2D anchor = getAnchor();
|
|
if(anchor.getWidth() == 0.) throw new POIXMLException(
|
|
"Anchor of the shape was not set.");
|
|
double height = getTextHeight();
|
|
height += 1; // add a pixel to compensate rounding errors
|
|
|
|
anchor.setRect(anchor.getX(), anchor.getY(), anchor.getWidth(), height);
|
|
setAnchor(anchor);
|
|
|
|
return anchor;
|
|
}
|
|
|
|
|
|
@Override
|
|
void copy(XSLFShape other){
|
|
super.copy(other);
|
|
|
|
XSLFTextShape otherTS = (XSLFTextShape)other;
|
|
CTTextBody otherTB = otherTS.getTextBody(false);
|
|
CTTextBody thisTB = getTextBody(true);
|
|
if (otherTB == null) {
|
|
return;
|
|
}
|
|
|
|
thisTB.setBodyPr((CTTextBodyProperties)otherTB.getBodyPr().copy());
|
|
|
|
if (thisTB.isSetLstStyle()) thisTB.unsetLstStyle();
|
|
if (otherTB.isSetLstStyle()) {
|
|
thisTB.setLstStyle((CTTextListStyle)otherTB.getLstStyle().copy());
|
|
}
|
|
|
|
boolean srcWordWrap = otherTS.getWordWrap();
|
|
if(srcWordWrap != getWordWrap()){
|
|
setWordWrap(srcWordWrap);
|
|
}
|
|
|
|
double leftInset = otherTS.getLeftInset();
|
|
if(leftInset != getLeftInset()) {
|
|
setLeftInset(leftInset);
|
|
}
|
|
double rightInset = otherTS.getRightInset();
|
|
if(rightInset != getRightInset()) {
|
|
setRightInset(rightInset);
|
|
}
|
|
double topInset = otherTS.getTopInset();
|
|
if(topInset != getTopInset()) {
|
|
setTopInset(topInset);
|
|
}
|
|
double bottomInset = otherTS.getBottomInset();
|
|
if(bottomInset != getBottomInset()) {
|
|
setBottomInset(bottomInset);
|
|
}
|
|
|
|
VerticalAlignment vAlign = otherTS.getVerticalAlignment();
|
|
if(vAlign != getVerticalAlignment()) {
|
|
setVerticalAlignment(vAlign);
|
|
}
|
|
|
|
clearText();
|
|
|
|
for (XSLFTextParagraph srcP : otherTS.getTextParagraphs()) {
|
|
XSLFTextParagraph tgtP = addNewTextParagraph();
|
|
tgtP.copy(srcP);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void setTextPlaceholder(TextPlaceholder placeholder) {
|
|
switch (placeholder) {
|
|
default:
|
|
case NOTES:
|
|
case HALF_BODY:
|
|
case QUARTER_BODY:
|
|
case BODY:
|
|
setPlaceholder(Placeholder.BODY);
|
|
break;
|
|
case TITLE:
|
|
setPlaceholder(Placeholder.TITLE);
|
|
break;
|
|
case CENTER_BODY:
|
|
setPlaceholder(Placeholder.BODY);
|
|
setHorizontalCentered(true);
|
|
break;
|
|
case CENTER_TITLE:
|
|
setPlaceholder(Placeholder.CENTERED_TITLE);
|
|
break;
|
|
case OTHER:
|
|
setPlaceholder(Placeholder.CONTENT);
|
|
break;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public TextPlaceholder getTextPlaceholder() {
|
|
Placeholder ph = getTextType();
|
|
if (ph == null) return TextPlaceholder.BODY;
|
|
switch (ph) {
|
|
case BODY: return TextPlaceholder.BODY;
|
|
case TITLE: return TextPlaceholder.TITLE;
|
|
case CENTERED_TITLE: return TextPlaceholder.CENTER_TITLE;
|
|
default:
|
|
case CONTENT: return TextPlaceholder.OTHER;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Helper method to allow subclasses to provide their own text paragraph
|
|
*
|
|
* @param p the xml reference
|
|
*
|
|
* @return a new text paragraph
|
|
*
|
|
* @since POI 3.15-beta2
|
|
*/
|
|
protected XSLFTextParagraph newTextParagraph(CTTextParagraph p) {
|
|
return new XSLFTextParagraph(p, this);
|
|
}
|
|
} |