From 85e2e8616dc5dd3fa515f6f9b3ad1a652f01bc08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alain=20B=C3=A9arez?= Date: Sun, 26 Aug 2018 21:33:16 +0000 Subject: [PATCH] test integration of XDDF text entities git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1839259 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 2 - .../poi/xslf/usermodel/XSLFAutoShape.java | 37 +- .../poi/xslf/usermodel/XSLFTableCell.java | 189 ++--- .../poi/xslf/usermodel/XSLFTextBox.java | 24 +- .../poi/xslf/usermodel/XSLFTextShape.java | 346 ++++---- .../apache/poi/xssf/usermodel/XSSFChart.java | 240 +++--- .../poi/xssf/usermodel/XSSFShapeGroup.java | 11 +- .../poi/xssf/usermodel/XSSFSimpleShape.java | 756 +++++++++++------- .../text/TestXDDFTextBodyProperties.java | 81 ++ .../xddf/usermodel/text/TestXDDFTextRun.java | 135 ++++ .../poi/xslf/usermodel/TestXSLFTextShape.java | 20 + .../xssf/usermodel/TestXSSFSimpleShape.java | 84 +- 12 files changed, 1205 insertions(+), 720 deletions(-) create mode 100644 src/ooxml/testcases/org/apache/poi/xddf/usermodel/text/TestXDDFTextBodyProperties.java create mode 100644 src/ooxml/testcases/org/apache/poi/xddf/usermodel/text/TestXDDFTextRun.java diff --git a/build.xml b/build.xml index 123867991..6050b6b49 100644 --- a/build.xml +++ b/build.xml @@ -1152,10 +1152,8 @@ under the License. - - { +public class XSLFAutoShape extends XSLFTextShape implements AutoShape { - /*package*/ XSLFAutoShape(CTShape shape, XSLFSheet sheet) { + /* package */ XSLFAutoShape(CTShape shape, XSLFSheet sheet) { super(shape, sheet); } - /*package*/ + /* package */ static XSLFAutoShape create(CTShape shape, XSLFSheet sheet) { if (shape.getSpPr().isSetCustGeom()) { return new XSLFFreeformShape(shape, sheet); @@ -60,7 +54,8 @@ public class XSLFAutoShape extends XSLFTextShape } /** - * @param shapeId 1-based shapeId + * @param shapeId + * 1-based shapeId */ static CTShape prototype(int shapeId) { CTShape ct = CTShape.Factory.newInstance(); @@ -76,22 +71,10 @@ public class XSLFAutoShape extends XSLFTextShape prst.addNewAvLst(); return ct; } - - protected static void initTextBody(CTTextBody txBody) { - CTTextBodyProperties bodypr = txBody.addNewBodyPr(); - bodypr.setAnchor(STTextAnchoringType.T); - bodypr.setRtlCol(false); - CTTextParagraph p = txBody.addNewP(); - p.addNewPPr().setAlgn(STTextAlignType.L); - CTTextCharacterProperties endPr = p.addNewEndParaRPr(); - endPr.setLang("en-US"); - endPr.setSz(1100); - p.addNewR().setT(""); - txBody.addNewLstStyle(); - } - protected CTTextBody getTextBody(boolean create){ - CTShape shape = (CTShape)getXmlObject(); + @Override + protected CTTextBody getTextBody(boolean create) { + CTShape shape = (CTShape) getXmlObject(); CTTextBody txBody = shape.getTxBody(); if (txBody == null && create) { txBody = shape.addNewTxBody(); @@ -101,7 +84,7 @@ public class XSLFAutoShape extends XSLFTextShape } @Override - public String toString(){ + public String toString() { return "[" + getClass().getSimpleName() + "] " + getShapeName(); } diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java index 63f196593..213ad9959 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java @@ -33,6 +33,7 @@ import org.apache.poi.sl.usermodel.StrokeStyle.LineDash; import org.apache.poi.sl.usermodel.TableCell; import org.apache.poi.sl.usermodel.VerticalAlignment; import org.apache.poi.util.Units; +import org.apache.poi.xddf.usermodel.text.XDDFTextBody; import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFFillProperties; import org.apache.poi.xslf.usermodel.XSLFTableStyle.TablePartStyle; import org.apache.xmlbeans.XmlObject; @@ -67,7 +68,7 @@ import org.openxmlformats.schemas.drawingml.x2006.main.STTextVerticalType; /** * Represents a cell of a table in a .pptx presentation */ -public class XSLFTableCell extends XSLFTextShape implements TableCell { +public class XSLFTableCell extends XSLFTextShape implements TableCell { private CTTableCellProperties _tcPr; private final XSLFTable table; private int row, col; @@ -77,18 +78,20 @@ public class XSLFTableCell extends XSLFTextShape implements TableCellnull unsets the solidFIll attribute from the underlying xml + * @param color + * the solid color fill. The value of null unsets + * the solidFIll attribute from the underlying xml */ @Override public void setFillColor(Color color) { CTTableCellProperties spPr = getCellProperties(true); if (color == null) { - if(spPr.isSetSolidFill()) { + if (spPr.isSetSolidFill()) { spPr.unsetSolidFill(); } } else { @@ -423,13 +426,13 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell { +public class XSLFTextBox extends XSLFAutoShape implements TextBox { - /*package*/ XSLFTextBox(CTShape shape, XSLFSheet sheet){ + /* package */ XSLFTextBox(CTShape shape, XSLFSheet sheet) { super(shape, sheet); } /** * - * @param shapeId 1-based shapeId + * @param shapeId + * 1-based shapeId */ - static CTShape prototype(int shapeId){ + static CTShape prototype(int shapeId) { CTShape ct = CTShape.Factory.newInstance(); CTShapeNonVisual nvSpPr = ct.addNewNvSpPr(); CTNonVisualDrawingProps cnv = nvSpPr.addNewCNvPr(); @@ -53,9 +56,10 @@ public class XSLFTextBox extends XSLFAutoShape CTPresetGeometry2D prst = spPr.addNewPrstGeom(); prst.setPrst(STShapeType.RECT); prst.addNewAvLst(); - CTTextBody txBody = ct.addNewTxBody(); - XSLFAutoShape.initTextBody(txBody); + XDDFTextBody body = new XDDFTextBody(null); + initTextBody(body); + ct.setTxBody(body.getXmlObject()); return ct; } -} \ No newline at end of file +} diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java index a52feaa3e..9286d5354 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java @@ -24,6 +24,8 @@ import java.awt.geom.Rectangle2D; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Optional; +import java.util.function.Function; import org.apache.poi.ooxml.POIXMLException; import org.apache.poi.sl.draw.DrawFactory; @@ -34,6 +36,9 @@ 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.xddf.usermodel.text.TextContainer; +import org.apache.poi.xddf.usermodel.text.XDDFTextBody; +import org.apache.poi.xddf.usermodel.text.XDDFTextParagraph; import org.apache.poi.xslf.model.PropertyFetcher; import org.apache.poi.xslf.model.TextBodyPropertyFetcher; import org.apache.xmlbeans.XmlObject; @@ -52,10 +57,10 @@ import org.openxmlformats.schemas.drawingml.x2006.main.STTextWrappingType; */ @Beta public abstract class XSLFTextShape extends XSLFSimpleShape - implements TextShape { + implements TextContainer, TextShape { private final List _paragraphs; - /*package*/ XSLFTextShape(XmlObject shape, XSLFSheet sheet) { + /* package */ XSLFTextShape(XmlObject shape, XSLFSheet sheet) { super(shape, sheet); _paragraphs = new ArrayList<>(); @@ -67,8 +72,22 @@ public abstract class XSLFTextShape extends XSLFSimpleShape } } + protected static void initTextBody(XDDFTextBody body) { + XDDFTextParagraph p = body.getParagraph(0); + p.appendRegularRun(""); + } + + @Beta + public XDDFTextBody getTextBody() { + CTTextBody txBody = getTextBody(false); + if (txBody == null) { + return null; + } + return new XDDFTextBody(this, txBody); + } + @Override - public Iterator iterator(){ + public Iterator iterator() { return getTextParagraphs().iterator(); } @@ -87,7 +106,7 @@ public abstract class XSLFTextShape extends XSLFSimpleShape /** * unset text from this shape */ - public void clearText(){ + public void clearText() { _paragraphs.clear(); CTTextBody txBody = getTextBody(true); txBody.setPArray(null); // remove any existing paragraphs @@ -95,13 +114,14 @@ public abstract class XSLFTextShape extends XSLFSimpleShape @Override public XSLFTextRun setText(String text) { - // calling clearText or setting to a new Array leads to a XmlValueDisconnectedException + // 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); + txBody.removeP(i - 1); + _paragraphs.remove(i - 1); } _paragraphs.get(0).clearButKeepProperties(); @@ -127,18 +147,19 @@ public abstract class XSLFTextShape extends XSLFSimpleShape para = null; } else { firstPara = !newParagraph; - para = _paragraphs.get(_paragraphs.size()-1); + para = _paragraphs.get(_paragraphs.size() - 1); CTTextParagraph ctp = para.getXmlObject(); otherPPr = ctp.getPPr(); List runs = para.getTextRuns(); if (!runs.isEmpty()) { - XSLFTextRun r0 = runs.get(runs.size()-1); + 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 + // 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 } @@ -173,7 +194,7 @@ public abstract class XSLFTextShape extends XSLFSimpleShape firstPara = false; } - assert(run != null); + assert (run != null); return run; } @@ -203,11 +224,11 @@ public abstract class XSLFTextShape extends XSLFSimpleShape } @Override - public void setVerticalAlignment(VerticalAlignment anchor){ + public void setVerticalAlignment(VerticalAlignment anchor) { CTTextBodyProperties bodyPr = getTextBodyPr(true); if (bodyPr != null) { - if(anchor == null) { - if(bodyPr.isSetAnchor()) { + if (anchor == null) { + if (bodyPr.isSetAnchor()) { bodyPr.unsetAnchor(); } } else { @@ -217,11 +238,11 @@ public abstract class XSLFTextShape extends XSLFSimpleShape } @Override - public VerticalAlignment getVerticalAlignment(){ - PropertyFetcher fetcher = new TextBodyPropertyFetcher(){ + public VerticalAlignment getVerticalAlignment() { + PropertyFetcher fetcher = new TextBodyPropertyFetcher() { @Override - public boolean fetch(CTTextBodyProperties props){ - if(props.isSetAnchor()){ + public boolean fetch(CTTextBodyProperties props) { + if (props.isSetAnchor()) { int val = props.getAnchor().intValue(); setValue(VerticalAlignment.values()[val - 1]); return true; @@ -234,10 +255,10 @@ public abstract class XSLFTextShape extends XSLFSimpleShape } @Override - public void setHorizontalCentered(Boolean isCentered){ + public void setHorizontalCentered(Boolean isCentered) { CTTextBodyProperties bodyPr = getTextBodyPr(true); if (bodyPr != null) { - if (isCentered == null) { + if (isCentered == null) { if (bodyPr.isSetAnchorCtr()) { bodyPr.unsetAnchorCtr(); } @@ -248,11 +269,11 @@ public abstract class XSLFTextShape extends XSLFSimpleShape } @Override - public boolean isHorizontalCentered(){ - PropertyFetcher fetcher = new TextBodyPropertyFetcher(){ + public boolean isHorizontalCentered() { + PropertyFetcher fetcher = new TextBodyPropertyFetcher() { @Override - public boolean fetch(CTTextBodyProperties props){ - if(props.isSetAnchorCtr()){ + public boolean fetch(CTTextBodyProperties props) { + if (props.isSetAnchorCtr()) { setValue(props.getAnchorCtr()); return true; } @@ -264,11 +285,11 @@ public abstract class XSLFTextShape extends XSLFSimpleShape } @Override - public void setTextDirection(TextDirection orientation){ + public void setTextDirection(TextDirection orientation) { CTTextBodyProperties bodyPr = getTextBodyPr(true); if (bodyPr != null) { - if(orientation == null) { - if(bodyPr.isSetVert()) { + if (orientation == null) { + if (bodyPr.isSetVert()) { bodyPr.unsetVert(); } } else { @@ -278,24 +299,24 @@ public abstract class XSLFTextShape extends XSLFSimpleShape } @Override - public TextDirection getTextDirection(){ + public TextDirection getTextDirection() { CTTextBodyProperties bodyPr = getTextBodyPr(); if (bodyPr != null) { STTextVerticalType.Enum val = bodyPr.getVert(); - if(val != null) { + 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; + 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; } } } @@ -315,22 +336,22 @@ public abstract class XSLFTextShape extends XSLFSimpleShape public void setTextRotation(Double rotation) { CTTextBodyProperties bodyPr = getTextBodyPr(true); if (bodyPr != null) { - bodyPr.setRot((int)(rotation * 60000.)); + 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. + * 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 fetcher = new TextBodyPropertyFetcher(){ + public double getBottomInset() { + PropertyFetcher fetcher = new TextBodyPropertyFetcher() { @Override - public boolean fetch(CTTextBodyProperties props){ - if(props.isSetBIns()){ + public boolean fetch(CTTextBodyProperties props) { + if (props.isSetBIns()) { double val = Units.toPoints(props.getBIns()); setValue(val); return true; @@ -344,17 +365,17 @@ public abstract class XSLFTextShape extends XSLFSimpleShape } /** - * 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. + * 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 fetcher = new TextBodyPropertyFetcher(){ + public double getLeftInset() { + PropertyFetcher fetcher = new TextBodyPropertyFetcher() { @Override - public boolean fetch(CTTextBodyProperties props){ - if(props.isSetLIns()){ + public boolean fetch(CTTextBodyProperties props) { + if (props.isSetLIns()) { double val = Units.toPoints(props.getLIns()); setValue(val); return true; @@ -368,17 +389,17 @@ public abstract class XSLFTextShape extends XSLFSimpleShape } /** - * 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. + * 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 fetcher = new TextBodyPropertyFetcher(){ + public double getRightInset() { + PropertyFetcher fetcher = new TextBodyPropertyFetcher() { @Override - public boolean fetch(CTTextBodyProperties props){ - if(props.isSetRIns()){ + public boolean fetch(CTTextBodyProperties props) { + if (props.isSetRIns()) { double val = Units.toPoints(props.getRIns()); setValue(val); return true; @@ -392,16 +413,16 @@ public abstract class XSLFTextShape extends XSLFSimpleShape } /** - * 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. + * 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 fetcher = new TextBodyPropertyFetcher(){ + public double getTopInset() { + PropertyFetcher fetcher = new TextBodyPropertyFetcher() { @Override - public boolean fetch(CTTextBodyProperties props){ - if(props.isSetTIns()){ + public boolean fetch(CTTextBodyProperties props) { + if (props.isSetTIns()) { double val = Units.toPoints(props.getTIns()); setValue(val); return true; @@ -416,14 +437,16 @@ public abstract class XSLFTextShape extends XSLFSimpleShape /** * Sets the bottom margin. + * * @see #getBottomInset() * - * @param margin the bottom margin + * @param margin + * the bottom margin */ - public void setBottomInset(double margin){ + public void setBottomInset(double margin) { CTTextBodyProperties bodyPr = getTextBodyPr(true); if (bodyPr != null) { - if(margin == -1) { + if (margin == -1) { bodyPr.unsetBIns(); } else { bodyPr.setBIns(Units.toEMU(margin)); @@ -433,14 +456,16 @@ public abstract class XSLFTextShape extends XSLFSimpleShape /** * Sets the left margin. + * * @see #getLeftInset() * - * @param margin the left margin + * @param margin + * the left margin */ - public void setLeftInset(double margin){ + public void setLeftInset(double margin) { CTTextBodyProperties bodyPr = getTextBodyPr(true); if (bodyPr != null) { - if(margin == -1) { + if (margin == -1) { bodyPr.unsetLIns(); } else { bodyPr.setLIns(Units.toEMU(margin)); @@ -450,14 +475,16 @@ public abstract class XSLFTextShape extends XSLFSimpleShape /** * Sets the right margin. + * * @see #getRightInset() * - * @param margin the right margin + * @param margin + * the right margin */ - public void setRightInset(double margin){ + public void setRightInset(double margin) { CTTextBodyProperties bodyPr = getTextBodyPr(true); if (bodyPr != null) { - if(margin == -1) { + if (margin == -1) { bodyPr.unsetRIns(); } else { bodyPr.setRIns(Units.toEMU(margin)); @@ -467,14 +494,16 @@ public abstract class XSLFTextShape extends XSLFSimpleShape /** * Sets the top margin. + * * @see #getTopInset() * - * @param margin the top margin + * @param margin + * the top margin */ - public void setTopInset(double margin){ + public void setTopInset(double margin) { CTTextBodyProperties bodyPr = getTextBodyPr(true); if (bodyPr != null) { - if(margin == -1) { + if (margin == -1) { bodyPr.unsetTIns(); } else { bodyPr.setTIns(Units.toEMU(margin)); @@ -496,11 +525,11 @@ public abstract class XSLFTextShape extends XSLFSimpleShape } @Override - public boolean getWordWrap(){ - PropertyFetcher fetcher = new TextBodyPropertyFetcher(){ + public boolean getWordWrap() { + PropertyFetcher fetcher = new TextBodyPropertyFetcher() { @Override - public boolean fetch(CTTextBodyProperties props){ - if(props.isSetWrap()){ + public boolean fetch(CTTextBodyProperties props) { + if (props.isSetWrap()) { setValue(props.getWrap() == STTextWrappingType.SQUARE); return true; } @@ -512,7 +541,7 @@ public abstract class XSLFTextShape extends XSLFSimpleShape } @Override - public void setWordWrap(boolean wrap){ + public void setWordWrap(boolean wrap) { CTTextBodyProperties bodyPr = getTextBodyPr(true); if (bodyPr != null) { bodyPr.setWrap(wrap ? STTextWrappingType.SQUARE : STTextWrappingType.NONE); @@ -521,28 +550,36 @@ public abstract class XSLFTextShape extends XSLFSimpleShape /** * - * 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 + * 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 + * @param value + * type of autofit */ - public void setTextAutofit(TextAutofit value){ + public void setTextAutofit(TextAutofit value) { CTTextBodyProperties bodyPr = getTextBodyPr(true); if (bodyPr != null) { - if(bodyPr.isSetSpAutoFit()) { + if (bodyPr.isSetSpAutoFit()) { bodyPr.unsetSpAutoFit(); } - if(bodyPr.isSetNoAutofit()) { + if (bodyPr.isSetNoAutofit()) { bodyPr.unsetNoAutofit(); } - if(bodyPr.isSetNormAutofit()) { + if (bodyPr.isSetNormAutofit()) { bodyPr.unsetNormAutofit(); } - switch(value){ - case NONE: bodyPr.addNewNoAutofit(); break; - case NORMAL: bodyPr.addNewNormAutofit(); break; - case SHAPE: bodyPr.addNewSpAutoFit(); break; + switch (value) { + case NONE: + bodyPr.addNewNoAutofit(); + break; + case NORMAL: + bodyPr.addNewNormAutofit(); + break; + case SHAPE: + bodyPr.addNewSpAutoFit(); + break; } } } @@ -551,10 +588,10 @@ public abstract class XSLFTextShape extends XSLFSimpleShape * * @return type of autofit */ - public TextAutofit getTextAutofit(){ + public TextAutofit getTextAutofit() { CTTextBodyProperties bodyPr = getTextBodyPr(); if (bodyPr != null) { - if(bodyPr.isSetNoAutofit()) { + if (bodyPr.isSetNoAutofit()) { return TextAutofit.NONE; } else if (bodyPr.isSetNormAutofit()) { return TextAutofit.NORMAL; @@ -565,7 +602,7 @@ public abstract class XSLFTextShape extends XSLFSimpleShape return TextAutofit.NORMAL; } - protected CTTextBodyProperties getTextBodyPr(){ + protected CTTextBodyProperties getTextBodyPr() { return getTextBodyPr(false); } @@ -588,89 +625,88 @@ public abstract class XSLFTextShape extends XSLFSimpleShape super.setPlaceholder(placeholder); } - public Placeholder getTextType(){ + public Placeholder getTextType() { return getPlaceholder(); } @Override - public double getTextHeight(){ + public double getTextHeight() { return getTextHeight(null); } - + @Override - public double getTextHeight(Graphics2D graphics){ + public double getTextHeight(Graphics2D graphics) { DrawFactory drawFact = DrawFactory.getInstance(graphics); DrawTextShape dts = drawFact.getDrawable(this); return dts.getTextHeight(graphics); } @Override - public Rectangle2D resizeToFitText(){ + public Rectangle2D resizeToFitText() { return resizeToFitText(null); } - + @Override public Rectangle2D resizeToFitText(Graphics2D graphics) { Rectangle2D anchor = getAnchor(); - if(anchor.getWidth() == 0.) { + if (anchor.getWidth() == 0.) { throw new POIXMLException("Anchor of the shape was not set."); } double height = getTextHeight(graphics); height += 1; // add a pixel to compensate rounding errors Insets2D insets = getInsets(); - anchor.setRect(anchor.getX(), anchor.getY(), anchor.getWidth(), height+insets.top+insets.bottom); + anchor.setRect(anchor.getX(), anchor.getY(), anchor.getWidth(), height + insets.top + insets.bottom); setAnchor(anchor); return anchor; } - @Override - void copy(XSLFShape other){ + void copy(XSLFShape other) { super.copy(other); - XSLFTextShape otherTS = (XSLFTextShape)other; + XSLFTextShape otherTS = (XSLFTextShape) other; CTTextBody otherTB = otherTS.getTextBody(false); CTTextBody thisTB = getTextBody(true); if (otherTB == null) { return; } - thisTB.setBodyPr((CTTextBodyProperties)otherTB.getBodyPr().copy()); + thisTB.setBodyPr((CTTextBodyProperties) otherTB.getBodyPr().copy()); if (thisTB.isSetLstStyle()) { thisTB.unsetLstStyle(); } if (otherTB.isSetLstStyle()) { - thisTB.setLstStyle((CTTextListStyle)otherTB.getLstStyle().copy()); + thisTB.setLstStyle((CTTextListStyle) otherTB.getLstStyle().copy()); } boolean srcWordWrap = otherTS.getWordWrap(); - if(srcWordWrap != getWordWrap()){ + if (srcWordWrap != getWordWrap()) { setWordWrap(srcWordWrap); } double leftInset = otherTS.getLeftInset(); - if(leftInset != getLeftInset()) { + if (leftInset != getLeftInset()) { setLeftInset(leftInset); } double rightInset = otherTS.getRightInset(); - if(rightInset != getRightInset()) { + if (rightInset != getRightInset()) { setRightInset(rightInset); } double topInset = otherTS.getTopInset(); - if(topInset != getTopInset()) { + if (topInset != getTopInset()) { setTopInset(topInset); } double bottomInset = otherTS.getBottomInset(); - if(bottomInset != getBottomInset()) { + if (bottomInset != getBottomInset()) { setBottomInset(bottomInset); } VerticalAlignment vAlign = otherTS.getVerticalAlignment(); - if(vAlign != getVerticalAlignment()) { + if (vAlign != getVerticalAlignment()) { setVerticalAlignment(vAlign); } @@ -685,26 +721,26 @@ public abstract class XSLFTextShape extends XSLFSimpleShape @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; + 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; } } @@ -715,18 +751,23 @@ public abstract class XSLFTextShape extends XSLFSimpleShape return TextPlaceholder.BODY; } switch (ph) { - case BODY: return TextPlaceholder.BODY; - case TITLE: return TextPlaceholder.TITLE; - case CENTERED_TITLE: return TextPlaceholder.CENTER_TITLE; + case BODY: + return TextPlaceholder.BODY; + case TITLE: + return TextPlaceholder.TITLE; + case CENTERED_TITLE: + return TextPlaceholder.CENTER_TITLE; default: - case CONTENT: return TextPlaceholder.OTHER; + case CONTENT: + return TextPlaceholder.OTHER; } } /** * Helper method to allow subclasses to provide their own text paragraph * - * @param p the xml reference + * @param p + * the xml reference * * @return a new text paragraph * @@ -735,4 +776,19 @@ public abstract class XSLFTextShape extends XSLFSimpleShape protected XSLFTextParagraph newTextParagraph(CTTextParagraph p) { return new XSLFTextParagraph(p, this); } -} \ No newline at end of file + + @Override + public Optional findDefinedParagraphProperty(Function isSet, + Function getter) { + // TODO Auto-generated method stub + return Optional.empty(); + } + + @Override + public Optional findDefinedRunProperty(Function isSet, + Function getter) { + // TODO Auto-generated method stub + return Optional.empty(); + } + +} diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChart.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChart.java index b44b3ae80..dc1ef9f2e 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChart.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChart.java @@ -74,7 +74,7 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor private XSSFGraphicFrame frame; @Deprecated - @Removal(version="4.2") + @Removal(version = "4.2") List axis = new ArrayList<>(); /** @@ -89,7 +89,8 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor * Construct a SpreadsheetML chart from a package part. * * @param part - * the package part holding the chart data, the content type must be + * the package part holding the chart data, the content type must + * be * application/vnd.openxmlformats-officedocument.drawingml.chart+xml * * @since POI 3.14-Beta1 @@ -114,7 +115,8 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor } /** - * Construct a new CTChartSpace bean. By default, it's just an empty placeholder for chart objects. + * Construct a new CTChartSpace bean. By default, it's just an empty + * placeholder for chart objects. */ private void createChart() { CTPlotArea plotArea = getCTPlotArea(); @@ -140,12 +142,15 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS); /* - * Saved chart space must have the following namespaces set: */ - xmlOptions.setSaveSyntheticDocumentElement(new QName(CTChartSpace.type.getName().getNamespaceURI(), "chartSpace", "c")); + xmlOptions.setSaveSyntheticDocumentElement( + new QName(CTChartSpace.type.getName().getNamespaceURI(), "chartSpace", "c")); PackagePart part = getPackagePart(); try (OutputStream out = part.getOutputStream()) { @@ -171,76 +176,76 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor @Override @Deprecated - @Removal(version="4.2") - public XSSFChartDataFactory getChartDataFactory() { - return XSSFChartDataFactory.getInstance(); - } + @Removal(version = "4.2") + public XSSFChartDataFactory getChartDataFactory() { + return XSSFChartDataFactory.getInstance(); + } @Override @Deprecated - @Removal(version="4.2") - public XSSFChart getChartAxisFactory() { - return this; - } + @Removal(version = "4.2") + public XSSFChart getChartAxisFactory() { + return this; + } @Override @Deprecated - @Removal(version="4.2") - public void plot(ChartData data, ChartAxis... chartAxis) { - data.fillChart(this, chartAxis); - } + @Removal(version = "4.2") + public void plot(ChartData data, ChartAxis... chartAxis) { + data.fillChart(this, chartAxis); + } @Override @Deprecated - @Removal(version="4.2") - public XSSFValueAxis createValueAxis(org.apache.poi.ss.usermodel.charts.AxisPosition pos) { - long id = axis.size() + 1; - XSSFValueAxis valueAxis = new XSSFValueAxis(this, id, pos); - if (axis.size() == 1) { - ChartAxis ax = axis.get(0); - ax.crossAxis(valueAxis); - valueAxis.crossAxis(ax); - } - axis.add(valueAxis); - return valueAxis; - } + @Removal(version = "4.2") + public XSSFValueAxis createValueAxis(org.apache.poi.ss.usermodel.charts.AxisPosition pos) { + long id = axis.size() + 1; + XSSFValueAxis valueAxis = new XSSFValueAxis(this, id, pos); + if (axis.size() == 1) { + ChartAxis ax = axis.get(0); + ax.crossAxis(valueAxis); + valueAxis.crossAxis(ax); + } + axis.add(valueAxis); + return valueAxis; + } @Override @Deprecated - @Removal(version="4.2") - public XSSFCategoryAxis createCategoryAxis(org.apache.poi.ss.usermodel.charts.AxisPosition pos) { - long id = axis.size() + 1; - XSSFCategoryAxis categoryAxis = new XSSFCategoryAxis(this, id, pos); - if (axis.size() == 1) { - ChartAxis ax = axis.get(0); - ax.crossAxis(categoryAxis); - categoryAxis.crossAxis(ax); - } - axis.add(categoryAxis); - return categoryAxis; - } + @Removal(version = "4.2") + public XSSFCategoryAxis createCategoryAxis(org.apache.poi.ss.usermodel.charts.AxisPosition pos) { + long id = axis.size() + 1; + XSSFCategoryAxis categoryAxis = new XSSFCategoryAxis(this, id, pos); + if (axis.size() == 1) { + ChartAxis ax = axis.get(0); + ax.crossAxis(categoryAxis); + categoryAxis.crossAxis(ax); + } + axis.add(categoryAxis); + return categoryAxis; + } @Override @Deprecated - @Removal(version="4.2") - public XSSFDateAxis createDateAxis(org.apache.poi.ss.usermodel.charts.AxisPosition pos) { - long id = axis.size() + 1; - XSSFDateAxis dateAxis = new XSSFDateAxis(this, id, pos); - if (axis.size() == 1) { - ChartAxis ax = axis.get(0); - ax.crossAxis(dateAxis); - dateAxis.crossAxis(ax); - } - axis.add(dateAxis); - return dateAxis; - } + @Removal(version = "4.2") + public XSSFDateAxis createDateAxis(org.apache.poi.ss.usermodel.charts.AxisPosition pos) { + long id = axis.size() + 1; + XSSFDateAxis dateAxis = new XSSFDateAxis(this, id, pos); + if (axis.size() == 1) { + ChartAxis ax = axis.get(0); + ax.crossAxis(dateAxis); + dateAxis.crossAxis(ax); + } + axis.add(dateAxis); + return dateAxis; + } /** * @deprecated use {@link #getAxes()} instead */ @Override @Deprecated - @Removal(version="4.2") + @Removal(version = "4.2") public List getAxis() { if (axis.isEmpty() && hasAxis()) { parseAxis(); @@ -250,56 +255,57 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor @Override @Deprecated - @Removal(version="4.2") - public XSSFManualLayout getManualLayout() { - return new XSSFManualLayout(this); - } + @Removal(version = "4.2") + public XSSFManualLayout getManualLayout() { + return new XSSFManualLayout(this); + } - /** - * Returns the title static text, or null if none is set. - * Note that a title formula may be set instead. - * @return static title text, if set - * @deprecated POI 3.16, use {@link #getTitleText()} instead. - */ + /** + * Returns the title static text, or null if none is set. Note that a title + * formula may be set instead. + * + * @return static title text, if set + * @deprecated POI 3.16, use {@link #getTitleText()} instead. + */ @Deprecated - @Removal(version="4.0") - public XSSFRichTextString getTitle() { - return getTitleText(); - } + @Removal(version = "4.0") + public XSSFRichTextString getTitle() { + return getTitleText(); + } - /** - * Returns the title static text, or null if none is set. - * Note that a title formula may be set instead. - * Empty text result is for backward compatibility, and could mean the title text is empty or there is a formula instead. - * Check for a formula first, falling back on text for cleaner logic. - * @return static title text if set, - * null if there is no title, - * empty string if the title text is empty or the title uses a formula instead - */ - public XSSFRichTextString getTitleText() { - if(! chart.isSetTitle()) { - return null; - } + /** + * Returns the title static text, or null if none is set. Note that a title + * formula may be set instead. Empty text result is for backward + * compatibility, and could mean the title text is empty or there is a + * formula instead. Check for a formula first, falling back on text for + * cleaner logic. + * + * @return static title text if set, null if there is no title, empty string + * if the title text is empty or the title uses a formula instead + */ + public XSSFRichTextString getTitleText() { + if (!chart.isSetTitle()) { + return null; + } - // TODO Do properly - CTTitle title = chart.getTitle(); + // TODO Do properly + CTTitle title = chart.getTitle(); - StringBuilder text = new StringBuilder(64); - XmlObject[] t = title - .selectPath("declare namespace a='"+XSSFDrawing.NAMESPACE_A+"' .//a:t"); - for (XmlObject element : t) { - NodeList kids = element.getDomNode().getChildNodes(); - final int count = kids.getLength(); - for (int n = 0; n < count; n++) { - Node kid = kids.item(n); - if (kid instanceof Text) { - text.append(kid.getNodeValue()); - } - } - } + StringBuilder text = new StringBuilder(64); + XmlObject[] t = title.selectPath("declare namespace a='" + XSSFDrawing.NAMESPACE_A + "' .//a:t"); + for (XmlObject element : t) { + NodeList kids = element.getDomNode().getChildNodes(); + final int count = kids.getLength(); + for (int n = 0; n < count; n++) { + Node kid = kids.item(n); + if (kid instanceof Text) { + text.append(kid.getNodeValue()); + } + } + } - return new XSSFRichTextString(text.toString()); - } + return new XSSFRichTextString(text.toString()); + } /** * Sets the title text as a static string. @@ -331,7 +337,8 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor rich = tx.getRich(); } else { rich = tx.addNewRich(); - rich.addNewBodyPr(); // body properties must exist (but can be empty) + rich.addNewBodyPr(); // body properties must exist (but can be + // empty) } CTTextParagraph para; @@ -414,21 +421,22 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor @Override @Deprecated - @Removal(version="4.2") - public XSSFChartLegend getOrCreateLegend() { - return new XSSFChartLegend(this); - } - - @Deprecated - @Removal(version="4.2") - private boolean hasAxis() { - CTPlotArea ctPlotArea = chart.getPlotArea(); - int totalAxisCount = ctPlotArea.sizeOfValAxArray() + ctPlotArea.sizeOfCatAxArray() + ctPlotArea.sizeOfDateAxArray() + ctPlotArea.sizeOfSerAxArray(); - return totalAxisCount > 0; - } + @Removal(version = "4.2") + public XSSFChartLegend getOrCreateLegend() { + return new XSSFChartLegend(this); + } @Deprecated - @Removal(version="4.2") + @Removal(version = "4.2") + private boolean hasAxis() { + CTPlotArea ctPlotArea = chart.getPlotArea(); + int totalAxisCount = ctPlotArea.sizeOfValAxArray() + ctPlotArea.sizeOfCatAxArray() + ctPlotArea + .sizeOfDateAxArray() + ctPlotArea.sizeOfSerAxArray(); + return totalAxisCount > 0; + } + + @Deprecated + @Removal(version = "4.2") private void parseAxis() { // TODO: add other axis types parseCategoryAxis(); @@ -437,7 +445,7 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor } @Deprecated - @Removal(version="4.2") + @Removal(version = "4.2") private void parseCategoryAxis() { for (CTCatAx catAx : chart.getPlotArea().getCatAxArray()) { axis.add(new XSSFCategoryAxis(this, catAx)); @@ -445,7 +453,7 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor } @Deprecated - @Removal(version="4.2") + @Removal(version = "4.2") private void parseDateAxis() { for (CTDateAx dateAx : chart.getPlotArea().getDateAxArray()) { axis.add(new XSSFDateAxis(this, dateAx)); @@ -453,7 +461,7 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor } @Deprecated - @Removal(version="4.2") + @Removal(version = "4.2") private void parseValueAxis() { for (CTValAx valAx : chart.getPlotArea().getValAxArray()) { axis.add(new XSSFValueAxis(this, valAx)); diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFShapeGroup.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFShapeGroup.java index 31d5964c8..96c7c9bcd 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFShapeGroup.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFShapeGroup.java @@ -103,7 +103,7 @@ public final class XSSFShapeGroup extends XSSFShape implements ShapeContainer, SimpleShape { - /** - * List of the paragraphs that make up the text in this shape - */ +public class XSSFSimpleShape extends XSSFShape implements Iterable, SimpleShape, TextContainer { + /** + * The text body containing the paragraphs for this shape. + */ + private final XDDFTextBody _textBody; + /** + * List of the paragraphs that make up the text in this shape + */ private final List _paragraphs; /** * A default instance of CTShape used for creating new shapes. @@ -49,22 +85,26 @@ public class XSSFSimpleShape extends XSSFShape implements Iterable(); - - // initialize any existing paragraphs - this will be the default body paragraph in a new shape, + + // initialize any existing paragraphs - this will be the default body + // paragraph in a new shape, // or existing paragraphs that have been loaded from the file CTTextBody body = ctShape.getTxBody(); - if(body != null) { - for(int i = 0; i < body.sizeOfPArray(); i++) { - _paragraphs.add(new XSSFTextParagraph(body.getPArray(i), ctShape)); + if (body == null) { + _textBody = null; + } else { + _textBody = new XDDFTextBody(this, body); + for (int i = 0; i < body.sizeOfPArray(); i++) { + _paragraphs.add(new XSSFTextParagraph(body.getPArray(i), ctShape)); } } } @@ -73,7 +113,7 @@ public class XSSFSimpleShape extends XSSFShape implements Iterable iterator(){ + protected void setXfrm(CTTransform2D t2d) { + ctShape.getSpPr().setXfrm(t2d); + } + + @Override + public Iterator iterator() { return _paragraphs.iterator(); } /** - * Returns the text from all paragraphs in the shape. Paragraphs are separated by new lines. - * - * @return text contained within this shape or empty string + * Returns the text from all paragraphs in the shape. Paragraphs are + * separated by new lines. + * + * @return text contained within this shape or empty string */ public String getText() { final int MAX_LEVELS = 9; StringBuilder out = new StringBuilder(); - List levelCount = new ArrayList<>(MAX_LEVELS); // maximum 9 levels + List levelCount = new ArrayList<>(MAX_LEVELS); // maximum 9 + // levels XSSFTextParagraph p = null; - - // initialise the levelCount array - this maintains a record of the numbering to be used at each level - for (int k = 0; k < MAX_LEVELS; k++){ - levelCount.add(0); + + // initialise the levelCount array - this maintains a record of the + // numbering to be used at each level + for (int k = 0; k < MAX_LEVELS; k++) { + levelCount.add(0); } - for(int i = 0; i < _paragraphs.size(); i++) { - if (out.length() > 0) out.append('\n'); + for (int i = 0; i < _paragraphs.size(); i++) { + if (out.length() > 0) { + out.append('\n'); + } p = _paragraphs.get(i); - if(p.isBullet() && p.getText().length() > 0){ - + if (p.isBullet() && p.getText().length() > 0) { + int level = Math.min(p.getLevel(), MAX_LEVELS - 1); - - if(p.isBulletAutoNumber()){ + + if (p.isBulletAutoNumber()) { i = processAutoNumGroup(i, level, levelCount, out); } else { // indent appropriately for the level - for(int j = 0; j < level; j++){ + for (int j = 0; j < level; j++) { out.append('\t'); - } + } String character = p.getBulletCharacter(); out.append(character.length() > 0 ? character + " " : "- "); out.append(p.getText()); - } + } } else { out.append(p.getText()); - + // this paragraph is not a bullet, so reset the count array - for (int k = 0; k < MAX_LEVELS; k++){ + for (int k = 0; k < MAX_LEVELS; k++) { levelCount.set(k, 0); } - } + } } return out.toString(); } /** - * + * */ - private int processAutoNumGroup(int index, int level, List levelCount, StringBuilder out){ + private int processAutoNumGroup(int index, int level, List levelCount, StringBuilder out) { XSSFTextParagraph p = null; XSSFTextParagraph nextp = null; ListAutoNumber scheme, nextScheme; int startAt, nextStartAt; - + p = _paragraphs.get(index); - - // The rules for generating the auto numbers are as follows. If the following paragraph is also - // an auto-number, has the same type/scheme (and startAt if defined on this paragraph) then they are - // considered part of the same group. An empty bullet paragraph is counted as part of the same - // group but does not increment the count for the group. A change of type, startAt or the paragraph + + // The rules for generating the auto numbers are as follows. If the + // following paragraph is also + // an auto-number, has the same type/scheme (and startAt if defined on + // this paragraph) then they are + // considered part of the same group. An empty bullet paragraph is + // counted as part of the same + // group but does not increment the count for the group. A change of + // type, startAt or the paragraph // not being a bullet resets the count for that level to 1. - - // first auto-number paragraph so initialise to 1 or the bullets startAt if present + + // first auto-number paragraph so initialise to 1 or the bullets startAt + // if present startAt = p.getBulletAutoNumberStart(); scheme = p.getBulletAutoNumberScheme(); - if(levelCount.get(level) == 0) { + if (levelCount.get(level) == 0) { levelCount.set(level, startAt == 0 ? 1 : startAt); } // indent appropriately for the level - for(int j = 0; j < level; j++){ + for (int j = 0; j < level; j++) { out.append('\t'); } - if (p.getText().length() > 0){ + if (p.getText().length() > 0) { out.append(getBulletPrefix(scheme, levelCount.get(level))); out.append(p.getText()); } - while(true) { + while (true) { nextp = (index + 1) == _paragraphs.size() ? null : _paragraphs.get(index + 1); - if(nextp == null) break; // out of paragraphs - if(!(nextp.isBullet() && p.isBulletAutoNumber())) break; // not an auto-number bullet - if(nextp.getLevel() > level) { + if (nextp == null) { + break; // out of paragraphs + } + if (!(nextp.isBullet() && p.isBulletAutoNumber())) { + break; // not an auto-number bullet + } + if (nextp.getLevel() > level) { // recurse into the new level group - if (out.length() > 0) out.append('\n'); + if (out.length() > 0) { + out.append('\n'); + } index = processAutoNumGroup(index + 1, nextp.getLevel(), levelCount, out); continue; // restart the loop given the new index - } else if(nextp.getLevel() < level) { - break; // changed level + } else if (nextp.getLevel() < level) { + break; // changed level } nextScheme = nextp.getBulletAutoNumberScheme(); nextStartAt = nextp.getBulletAutoNumberStart(); - - if(nextScheme == scheme && nextStartAt == startAt) { - // bullet is valid, so increment i + + if (nextScheme == scheme && nextStartAt == startAt) { + // bullet is valid, so increment i ++index; - if (out.length() > 0) out.append('\n'); + if (out.length() > 0) { + out.append('\n'); + } // indent for the level - for(int j = 0; j < level; j++){ + for (int j = 0; j < level; j++) { out.append('\t'); } - // check for empty text - only output a bullet if there is text, but it is still part of the group - if(nextp.getText().length() > 0) { + // check for empty text - only output a bullet if there is text, + // but it is still part of the group + if (nextp.getText().length() > 0) { // increment the count for this level levelCount.set(level, levelCount.get(level) + 1); out.append(getBulletPrefix(nextScheme, levelCount.get(level))); @@ -235,36 +296,45 @@ public class XSSFSimpleShape extends XSSFShape implements Iterable 0) { modulo = (value - 1) % 26; - alpha = (char)(65 + modulo) + alpha; + alpha = (char) (65 + modulo) + alpha; value = (value - modulo) / 26; } return alpha; } - - private static String[] _romanChars = new String[] { "M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I" }; - private static int[] _romanAlphaValues = new int[] { 1000,900,500,400,100,90,50,40,10,9,5,4,1 }; - + + private static String[] _romanChars = new String[] { "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", + "IV", "I" }; + private static int[] _romanAlphaValues = new int[] { 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 }; + /** * Convert an integer to its roman equivalent e.g. 1 = I, 9 = IX etc */ private String valueToRoman(int value) { StringBuilder out = new StringBuilder(); - for(int i = 0; value > 0 && i < _romanChars.length; i++) { - while(_romanAlphaValues[i] <= value) { + for (int i = 0; value > 0 && i < _romanChars.length; i++) { + while (_romanAlphaValues[i] <= value) { out.append(_romanChars[i]); value -= _romanAlphaValues[i]; } } return out.toString(); } - + /** * Clear all text from this shape */ - public void clearText(){ + public void clearText() { _paragraphs.clear(); CTTextBody txBody = ctShape.getTxBody(); txBody.setPArray(null); // remove any existing paragraphs } - + /** - * Set a single paragraph of text on the shape. Note this will replace all existing paragraphs created on the shape. - * @param text string representing the paragraph text + * Set a single paragraph of text on the shape. Note this will replace all + * existing paragraphs created on the shape. + * + * @param text + * string representing the paragraph text */ - public void setText(String text){ + public void setText(String text) { clearText(); addNewTextParagraph().addNewTextRun().setText(text); } /** - * Set a single paragraph of text on the shape. Note this will replace all existing paragraphs created on the shape. - * @param str rich text string representing the paragraph text + * Set a single paragraph of text on the shape. Note this will replace all + * existing paragraphs created on the shape. + * + * @param str + * rich text string representing the paragraph text */ - public void setText(XSSFRichTextString str){ + public void setText(XSSFRichTextString str) { - XSSFWorkbook wb = (XSSFWorkbook)getDrawing().getParent().getParent(); + XSSFWorkbook wb = (XSSFWorkbook) getDrawing().getParent().getParent(); str.setStylesTableReference(wb.getStylesSource()); CTTextParagraph p = CTTextParagraph.Factory.newInstance(); - if(str.numFormattingRuns() == 0){ + if (str.numFormattingRuns() == 0) { CTRegularTextRun r = p.addNewR(); CTTextCharacterProperties rPr = r.addNewRPr(); rPr.setLang("en-US"); @@ -385,7 +469,9 @@ public class XSSFSimpleShape extends XSSFShape implements Iterable getTextParagraphs() { @@ -422,7 +509,7 @@ public class XSSFSimpleShape extends XSSFShape implements Iterablenull values unsets this property. + * @param overflow + * - the type of horizontal overflow. A null values + * unsets this property. */ - public void setTextHorizontalOverflow(TextHorizontalOverflow overflow){ + public void setTextHorizontalOverflow(TextHorizontalOverflow overflow) { CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); if (bodyPr != null) { - if(overflow == null) { - if(bodyPr.isSetHorzOverflow()) bodyPr.unsetHorzOverflow(); + if (overflow == null) { + if (bodyPr.isSetHorzOverflow()) { + bodyPr.unsetHorzOverflow(); + } } else { bodyPr.setHorzOverflow(STTextHorzOverflowType.Enum.forInt(overflow.ordinal() + 1)); } @@ -496,27 +590,30 @@ public class XSSFSimpleShape extends XSSFShape implements Iterablenull values unsets this property. + * @param overflow + * - the type of vertical overflow. A null values + * unsets this property. */ - public void setTextVerticalOverflow(TextVerticalOverflow overflow){ + public void setTextVerticalOverflow(TextVerticalOverflow overflow) { CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); if (bodyPr != null) { - if(overflow == null) { - if(bodyPr.isSetVertOverflow()) bodyPr.unsetVertOverflow(); + if (overflow == null) { + if (bodyPr.isSetVertOverflow()) { + bodyPr.unsetVertOverflow(); + } } else { bodyPr.setVertOverflow(STTextVertOverflowType.Enum.forInt(overflow.ordinal() + 1)); } @@ -528,27 +625,30 @@ public class XSSFSimpleShape extends XSSFShape implements Iterablenull values unsets this property. + * @param anchor + * - the type of alignment. A null values unsets + * this property. */ - public void setVerticalAlignment(VerticalAlignment anchor){ + public void setVerticalAlignment(VerticalAlignment anchor) { CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); if (bodyPr != null) { - if(anchor == null) { - if(bodyPr.isSetAnchor()) bodyPr.unsetAnchor(); + if (anchor == null) { + if (bodyPr.isSetAnchor()) { + bodyPr.unsetAnchor(); + } } else { bodyPr.setAnchor(STTextAnchoringType.Enum.forInt(anchor.ordinal() + 1)); } @@ -560,27 +660,30 @@ public class XSSFSimpleShape extends XSSFShape implements Iterablenull values unsets this property. + * + * @param orientation + * vertical orientation of the text A null values + * unsets this property. */ - public void setTextDirection(TextDirection orientation){ + public void setTextDirection(TextDirection orientation) { CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); if (bodyPr != null) { - if(orientation == null) { - if(bodyPr.isSetVert()) bodyPr.unsetVert(); + if (orientation == null) { + if (bodyPr.isSetVert()) { + bodyPr.unsetVert(); + } } else { bodyPr.setVert(STTextVerticalType.Enum.forInt(orientation.ordinal() + 1)); } @@ -589,170 +692,174 @@ public class XSSFSimpleShape extends XSSFShape implements Iterable 0) rPr.setB(pr.getBArray(0).getVal()); - if(pr.sizeOfUArray() > 0) { - STUnderlineValues.Enum u1 = pr.getUArray(0).getVal(); - if(u1 == STUnderlineValues.SINGLE) rPr.setU(STTextUnderlineType.SNG); - else if(u1 == STUnderlineValues.DOUBLE) rPr.setU(STTextUnderlineType.DBL); - else if(u1 == STUnderlineValues.NONE) rPr.setU(STTextUnderlineType.NONE); + if (pr.sizeOfBArray() > 0) { + rPr.setB(pr.getBArray(0).getVal()); + } + if (pr.sizeOfUArray() > 0) { + STUnderlineValues.Enum u1 = pr.getUArray(0).getVal(); + if (u1 == STUnderlineValues.SINGLE) { + rPr.setU(STTextUnderlineType.SNG); + } else if (u1 == STUnderlineValues.DOUBLE) { + rPr.setU(STTextUnderlineType.DBL); + } else if (u1 == STUnderlineValues.NONE) { + rPr.setU(STTextUnderlineType.NONE); + } + } + if (pr.sizeOfIArray() > 0) { + rPr.setI(pr.getIArray(0).getVal()); } - if(pr.sizeOfIArray() > 0) rPr.setI(pr.getIArray(0).getVal()); - if(pr.sizeOfRFontArray() > 0) { + if (pr.sizeOfRFontArray() > 0) { CTTextFont rFont = rPr.isSetLatin() ? rPr.getLatin() : rPr.addNewLatin(); rFont.setTypeface(pr.getRFontArray(0).getVal()); } - if(pr.sizeOfSzArray() > 0) { - int sz = (int)(pr.getSzArray(0).getVal()*100); + if (pr.sizeOfSzArray() > 0) { + int sz = (int) (pr.getSzArray(0).getVal() * 100); rPr.setSz(sz); } - - if(pr.sizeOfColorArray() > 0) { + + if (pr.sizeOfColorArray() > 0) { CTSolidColorFillProperties fill = rPr.isSetSolidFill() ? rPr.getSolidFill() : rPr.addNewSolidFill(); org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor xlsColor = pr.getColorArray(0); - if(xlsColor.isSetRgb()) { + if (xlsColor.isSetRgb()) { CTSRgbColor clr = fill.isSetSrgbClr() ? fill.getSrgbClr() : fill.addNewSrgbClr(); clr.setVal(xlsColor.getRgb()); - } - else if(xlsColor.isSetIndexed()) { + } else if (xlsColor.isSetIndexed()) { HSSFColor indexed = HSSFColor.getIndexHash().get((int) xlsColor.getIndexed()); if (indexed != null) { byte[] rgb = new byte[3]; @@ -872,6 +1008,20 @@ public class XSSFSimpleShape extends XSSFShape implements Iterable Optional findDefinedParagraphProperty(Function isSet, + Function getter) { + // TODO Auto-generated method stub + return Optional.empty(); + } + + @Override + public Optional findDefinedRunProperty(Function isSet, + Function getter) { + // TODO Auto-generated method stub + return Optional.empty(); } } diff --git a/src/ooxml/testcases/org/apache/poi/xddf/usermodel/text/TestXDDFTextBodyProperties.java b/src/ooxml/testcases/org/apache/poi/xddf/usermodel/text/TestXDDFTextBodyProperties.java new file mode 100644 index 000000000..3b137d656 --- /dev/null +++ b/src/ooxml/testcases/org/apache/poi/xddf/usermodel/text/TestXDDFTextBodyProperties.java @@ -0,0 +1,81 @@ +/* ==================================================================== + 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.xddf.usermodel.text; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; + +import org.apache.poi.util.Units; +import org.junit.Test; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBodyProperties; + +public class TestXDDFTextBodyProperties { + + @Test + public void testProperties() throws IOException { + XDDFBodyProperties body = new XDDFTextBody(null).getBodyProperties(); + CTTextBodyProperties props = body.getXmlObject(); + + body.setBottomInset(null); + assertFalse(props.isSetBIns()); + body.setBottomInset(3.6); + assertTrue(props.isSetBIns()); + assertEquals(Units.toEMU(3.6), props.getBIns()); + + body.setLeftInset(null); + assertFalse(props.isSetLIns()); + body.setLeftInset(3.6); + assertTrue(props.isSetLIns()); + assertEquals(Units.toEMU(3.6), props.getLIns()); + + body.setRightInset(null); + assertFalse(props.isSetRIns()); + body.setRightInset(3.6); + assertTrue(props.isSetRIns()); + assertEquals(Units.toEMU(3.6), props.getRIns()); + + body.setTopInset(null); + assertFalse(props.isSetTIns()); + body.setTopInset(3.6); + assertTrue(props.isSetTIns()); + assertEquals(Units.toEMU(3.6), props.getTIns()); + + body.setAutoFit(null); + assertFalse(props.isSetNoAutofit()); + assertFalse(props.isSetNormAutofit()); + assertFalse(props.isSetSpAutoFit()); + + body.setAutoFit(new XDDFNoAutoFit()); + assertTrue(props.isSetNoAutofit()); + assertFalse(props.isSetNormAutofit()); + assertFalse(props.isSetSpAutoFit()); + + body.setAutoFit(new XDDFNormalAutoFit()); + assertFalse(props.isSetNoAutofit()); + assertTrue(props.isSetNormAutofit()); + assertFalse(props.isSetSpAutoFit()); + + body.setAutoFit(new XDDFShapeAutoFit()); + assertFalse(props.isSetNoAutofit()); + assertFalse(props.isSetNormAutofit()); + assertTrue(props.isSetSpAutoFit()); + + } +} diff --git a/src/ooxml/testcases/org/apache/poi/xddf/usermodel/text/TestXDDFTextRun.java b/src/ooxml/testcases/org/apache/poi/xddf/usermodel/text/TestXDDFTextRun.java new file mode 100644 index 000000000..67d509fa4 --- /dev/null +++ b/src/ooxml/testcases/org/apache/poi/xddf/usermodel/text/TestXDDFTextRun.java @@ -0,0 +1,135 @@ +/* ==================================================================== + 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.xddf.usermodel.text; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.List; + +import org.apache.poi.util.LocaleUtil; +import org.apache.poi.xslf.usermodel.XMLSlideShow; +import org.apache.poi.xslf.usermodel.XSLFSlide; +import org.apache.poi.xslf.usermodel.XSLFTextShape; +import org.apache.poi.xssf.usermodel.XSSFClientAnchor; +import org.apache.poi.xssf.usermodel.XSSFDrawing; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFTextBox; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.junit.Test; + +public class TestXDDFTextRun { + + @Test + public void testTextRunPropertiesInSlide() throws IOException { + try (XMLSlideShow ppt = new XMLSlideShow()) { + XSLFSlide slide = ppt.createSlide(); + XSLFTextShape sh = slide.createAutoShape(); + sh.addNewTextParagraph(); + + XDDFTextBody body = sh.getTextBody(); + XDDFTextParagraph para = body.getParagraph(0); + XDDFTextRun r = para.appendRegularRun("text"); + assertEquals(LocaleUtil.getUserLocale().toLanguageTag(), r.getLanguage().toLanguageTag()); + + assertNull(r.getCharacterSpacing()); + r.setCharacterSpacing(3.0); + assertEquals(3., r.getCharacterSpacing(), 0); + r.setCharacterSpacing(-3.0); + assertEquals(-3., r.getCharacterSpacing(), 0); + r.setCharacterSpacing(0.0); + assertEquals(0., r.getCharacterSpacing(), 0); + + assertEquals(11.0, r.getFontSize(), 0); + r.setFontSize(13.0); + assertEquals(13.0, r.getFontSize(), 0); + + assertFalse(r.isSuperscript()); + r.setSuperscript(0.8); + assertTrue(r.isSuperscript()); + r.setSuperscript(null); + assertFalse(r.isSuperscript()); + + assertFalse(r.isSubscript()); + r.setSubscript(0.7); + assertTrue(r.isSubscript()); + r.setSubscript(null); + assertFalse(r.isSubscript()); + + r.setBaseline(0.9); + assertTrue(r.isSuperscript()); + r.setBaseline(-0.6); + assertTrue(r.isSubscript()); + } + } + + @Test + public void testTextRunPropertiesInSheet() throws IOException { + try (XSSFWorkbook wb = new XSSFWorkbook()) { + XSSFSheet sheet = wb.createSheet(); + XSSFDrawing drawing = sheet.createDrawingPatriarch(); + + XSSFTextBox shape = drawing.createTextbox(new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 4)); + + shape.addNewTextParagraph().addNewTextRun().setText("Line 1"); + + XDDFTextBody body = shape.getTextBody(); + XDDFTextParagraph para = body.getParagraph(1); + List runs = para.getTextRuns(); + assertEquals(1, runs.size()); + + XDDFTextRun run = runs.get(0); + assertEquals("Line 1", run.getText()); + + assertFalse(run.isStrikeThrough()); + run.setStrikeThrough(StrikeType.SINGLE_STRIKE); + assertTrue(run.isStrikeThrough()); + run.setStrikeThrough(StrikeType.NO_STRIKE); + assertFalse(run.isStrikeThrough()); + + assertFalse(run.isCapitals()); + run.setCapitals(CapsType.SMALL); + assertTrue(run.isCapitals()); + run.setCapitals(CapsType.NONE); + assertFalse(run.isCapitals()); + + assertFalse(run.isBold()); + run.setBold(true); + assertTrue(run.isBold()); + run.setBold(false); + assertFalse(run.isBold()); + + assertFalse(run.isItalic()); + run.setItalic(true); + assertTrue(run.isItalic()); + run.setItalic(false); + assertFalse(run.isItalic()); + + assertFalse(run.isUnderline()); + run.setUnderline(UnderlineType.WAVY_DOUBLE); + assertTrue(run.isUnderline()); + run.setUnderline(UnderlineType.NONE); + assertFalse(run.isUnderline()); + + assertNotNull(run.getText()); + } + } +} diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java index 49dc0a3bf..a67d4bef9 100644 --- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java +++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java @@ -30,6 +30,7 @@ import java.awt.Color; import java.io.File; import java.io.IOException; import java.util.List; +import java.util.stream.Collectors; import org.apache.poi.POIDataSamples; import org.apache.poi.hslf.usermodel.HSLFTextShape; @@ -38,6 +39,8 @@ import org.apache.poi.sl.usermodel.SlideShow; import org.apache.poi.sl.usermodel.SlideShowFactory; import org.apache.poi.sl.usermodel.TextParagraph.TextAlign; import org.apache.poi.sl.usermodel.VerticalAlignment; +import org.apache.poi.xddf.usermodel.text.XDDFBodyProperties; +import org.apache.poi.xddf.usermodel.text.XDDFTextBody; import org.apache.poi.xslf.XSLFTestDataSamples; import org.junit.BeforeClass; import org.junit.Test; @@ -83,6 +86,8 @@ public class TestXSLFTextShape { assertEquals("Title Slide",layout.getName()); XSLFTextShape shape1 = (XSLFTextShape)shapes.get(0); + XDDFTextBody tb1 = shape1.getTextBody(); + XDDFBodyProperties tbp1 = tb1.getBodyProperties(); CTPlaceholder ph1 = shape1.getPlaceholderDetails().getCTPlaceholder(false); assertEquals(STPlaceholderType.CTR_TITLE, ph1.getType()); // anchor is not defined in the shape @@ -104,15 +109,24 @@ public class TestXSLFTextShape { assertEquals(3.6, shape1.getTopInset(), 0); // 0.05" assertEquals(3.6, shape1.getBottomInset(), 0); // 0.05" assertEquals(VerticalAlignment.MIDDLE, shape1.getVerticalAlignment()); + assertNull(tbp1.getLeftInset()); + assertNull(tbp1.getRightInset()); + assertNull(tbp1.getBottomInset()); + assertNull(tbp1.getTopInset()); + assertNull(tbp1.getAnchoring()); // now check text properties assertEquals("Centered Title", shape1.getText()); + assertEquals("Centered Title", + tb1.getParagraphs().stream().map(p -> p.getText()).collect(Collectors.joining("\n"))); XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0); assertEquals("Calibri", r1.getFontFamily()); assertEquals(44.0, r1.getFontSize(), 0); assertTrue(sameColor(Color.black, r1.getFontColor())); XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1); + XDDFTextBody tb2 = shape2.getTextBody(); + XDDFBodyProperties tbp2 = tb2.getBodyProperties(); CTPlaceholder ph2 = shape2.getPlaceholderDetails().getCTPlaceholder(false); assertEquals(STPlaceholderType.SUB_TITLE, ph2.getType()); // anchor is not defined in the shape @@ -134,8 +148,14 @@ public class TestXSLFTextShape { assertEquals(3.6, shape2.getTopInset(), 0); // 0.05" assertEquals(3.6, shape2.getBottomInset(), 0); // 0.05" assertEquals(VerticalAlignment.TOP, shape2.getVerticalAlignment()); + assertNull(tbp2.getLeftInset()); + assertNull(tbp2.getRightInset()); + assertNull(tbp2.getBottomInset()); + assertNull(tbp2.getTopInset()); + assertNull(tbp2.getAnchoring()); assertEquals("subtitle", shape2.getText()); + assertEquals("subtitle", tb2.getParagraphs().stream().map(p -> p.getText()).collect(Collectors.joining("\n"))); XSLFTextRun r2 = shape2.getTextParagraphs().get(0).getTextRuns().get(0); assertEquals("Calibri", r2.getFontFamily()); assertEquals(32.0, r2.getFontSize(), 0); diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSimpleShape.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSimpleShape.java index 06733425e..78c476c5b 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSimpleShape.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSimpleShape.java @@ -16,12 +16,23 @@ ==================================================================== */ package org.apache.poi.xssf.usermodel; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import java.awt.Color; import java.io.IOException; +import java.util.List; import org.apache.poi.ss.usermodel.VerticalAlignment; +import org.apache.poi.xddf.usermodel.text.XDDFBodyProperties; +import org.apache.poi.xddf.usermodel.text.XDDFNoAutoFit; +import org.apache.poi.xddf.usermodel.text.XDDFNormalAutoFit; +import org.apache.poi.xddf.usermodel.text.XDDFShapeAutoFit; +import org.apache.poi.xddf.usermodel.text.XDDFTextBody; +import org.apache.poi.xddf.usermodel.text.XDDFTextParagraph; import org.junit.Test; public class TestXSSFSimpleShape { @@ -31,43 +42,53 @@ public class TestXSSFSimpleShape { try { XSSFSheet sheet = wb.createSheet(); XSSFDrawing drawing = sheet.createDrawingPatriarch(); - + XSSFTextBox shape = drawing.createTextbox(new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 4)); - + XSSFRichTextString rt = new XSSFRichTextString("Test String"); - + XSSFFont font = wb.createFont(); Color color = new Color(0, 255, 255); font.setColor(new XSSFColor(color, wb.getStylesSource().getIndexedColors())); font.setFontName("Arial"); rt.applyFont(font); - + shape.setText(rt); assertNotNull(shape.getCTShape()); assertNotNull(shape.iterator()); assertNotNull(XSSFSimpleShape.prototype()); - - for(ListAutoNumber nr : ListAutoNumber.values()) { + + for (ListAutoNumber nr : ListAutoNumber.values()) { shape.getTextParagraphs().get(0).setBullet(nr); assertNotNull(shape.getText()); } - + shape.getTextParagraphs().get(0).setBullet(false); assertNotNull(shape.getText()); shape.setText("testtext"); assertEquals("testtext", shape.getText()); - + shape.setText(new XSSFRichTextString()); assertEquals("null", shape.getText()); - + shape.addNewTextParagraph(); shape.addNewTextParagraph("test-other-text"); shape.addNewTextParagraph(new XSSFRichTextString("rtstring")); shape.addNewTextParagraph(new XSSFRichTextString()); assertEquals("null\n\ntest-other-text\nrtstring\nnull", shape.getText()); - + + XDDFTextBody body = shape.getTextBody(); + assertNotNull(body); + List paragraphs = body.getParagraphs(); + assertEquals(5, paragraphs.size()); + assertEquals("null", body.getParagraph(0).getText()); + assertEquals("", body.getParagraph(1).getText()); + assertEquals("test-other-text", body.getParagraph(2).getText()); + assertEquals("rtstring", body.getParagraph(3).getText()); + assertEquals("null", body.getParagraph(4).getText()); + assertEquals(TextHorizontalOverflow.OVERFLOW, shape.getTextHorizontalOverflow()); shape.setTextHorizontalOverflow(TextHorizontalOverflow.CLIP); assertEquals(TextHorizontalOverflow.CLIP, shape.getTextHorizontalOverflow()); @@ -77,7 +98,7 @@ public class TestXSSFSimpleShape { assertEquals(TextHorizontalOverflow.OVERFLOW, shape.getTextHorizontalOverflow()); shape.setTextHorizontalOverflow(null); assertEquals(TextHorizontalOverflow.OVERFLOW, shape.getTextHorizontalOverflow()); - + assertEquals(TextVerticalOverflow.OVERFLOW, shape.getTextVerticalOverflow()); shape.setTextVerticalOverflow(TextVerticalOverflow.CLIP); assertEquals(TextVerticalOverflow.CLIP, shape.getTextVerticalOverflow()); @@ -108,38 +129,57 @@ public class TestXSSFSimpleShape { shape.setTextDirection(null); assertEquals(TextDirection.HORIZONTAL, shape.getTextDirection()); + XDDFBodyProperties props = body.getBodyProperties(); + assertNotNull(props); + assertEquals(3.6, shape.getBottomInset(), 0.01); + assertNull(props.getBottomInset()); shape.setBottomInset(12.32); assertEquals(12.32, shape.getBottomInset(), 0.01); + assertEquals(12.32, props.getBottomInset(), 0.01); shape.setBottomInset(-1); assertEquals(3.6, shape.getBottomInset(), 0.01); + assertNull(props.getBottomInset()); shape.setBottomInset(-1); assertEquals(3.6, shape.getBottomInset(), 0.01); - + assertNull(props.getBottomInset()); + assertEquals(3.6, shape.getLeftInset(), 0.01); + assertNull(props.getLeftInset()); shape.setLeftInset(12.31); assertEquals(12.31, shape.getLeftInset(), 0.01); + assertEquals(12.31, props.getLeftInset(), 0.01); shape.setLeftInset(-1); assertEquals(3.6, shape.getLeftInset(), 0.01); + assertNull(props.getLeftInset()); shape.setLeftInset(-1); assertEquals(3.6, shape.getLeftInset(), 0.01); + assertNull(props.getLeftInset()); assertEquals(3.6, shape.getRightInset(), 0.01); + assertNull(props.getRightInset()); shape.setRightInset(13.31); assertEquals(13.31, shape.getRightInset(), 0.01); + assertEquals(13.31, props.getRightInset(), 0.01); shape.setRightInset(-1); assertEquals(3.6, shape.getRightInset(), 0.01); + assertNull(props.getRightInset()); shape.setRightInset(-1); assertEquals(3.6, shape.getRightInset(), 0.01); + assertNull(props.getRightInset()); assertEquals(3.6, shape.getTopInset(), 0.01); + assertNull(props.getTopInset()); shape.setTopInset(23.31); assertEquals(23.31, shape.getTopInset(), 0.01); + assertEquals(23.31, props.getTopInset(), 0.01); shape.setTopInset(-1); assertEquals(3.6, shape.getTopInset(), 0.01); + assertNull(props.getTopInset()); shape.setTopInset(-1); assertEquals(3.6, shape.getTopInset(), 0.01); - + assertNull(props.getTopInset()); + assertTrue(shape.getWordWrap()); shape.setWordWrap(false); assertFalse(shape.getWordWrap()); @@ -147,23 +187,27 @@ public class TestXSSFSimpleShape { assertTrue(shape.getWordWrap()); assertEquals(TextAutofit.NORMAL, shape.getTextAutofit()); + assertTrue(props.getAutoFit() instanceof XDDFNormalAutoFit); shape.setTextAutofit(TextAutofit.NORMAL); assertEquals(TextAutofit.NORMAL, shape.getTextAutofit()); + assertTrue(props.getAutoFit() instanceof XDDFNormalAutoFit); shape.setTextAutofit(TextAutofit.SHAPE); assertEquals(TextAutofit.SHAPE, shape.getTextAutofit()); + assertTrue(props.getAutoFit() instanceof XDDFShapeAutoFit); shape.setTextAutofit(TextAutofit.NONE); assertEquals(TextAutofit.NONE, shape.getTextAutofit()); - + assertTrue(props.getAutoFit() instanceof XDDFNoAutoFit); + assertEquals(5, shape.getShapeType()); shape.setShapeType(23); assertEquals(23, shape.getShapeType()); // TODO: should this be supported? -// shape.setShapeType(-1); -// assertEquals(-1, shape.getShapeType()); -// shape.setShapeType(-1); -// assertEquals(-1, shape.getShapeType()); - + // shape.setShapeType(-1); + // assertEquals(-1, shape.getShapeType()); + // shape.setShapeType(-1); + // assertEquals(-1, shape.getShapeType()); + assertNotNull(shape.getShapeProperties()); } finally { wb.close();