Modified: poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSimpleShape.java URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSimpleShape.java?rev=1839259&r1=1839258&r2=1839259&view=diff ============================================================================== --- poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSimpleShape.java (original) +++ poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSimpleShape.java Sun Aug 26 21:33:16 2018 @@ -21,13 +21,44 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Locale; +import java.util.Optional; +import java.util.function.Function; import org.apache.poi.hssf.util.HSSFColor; import org.apache.poi.ss.usermodel.SimpleShape; import org.apache.poi.ss.usermodel.VerticalAlignment; +import org.apache.poi.util.Beta; import org.apache.poi.util.Internal; -import org.apache.poi.util.Units; -import org.openxmlformats.schemas.drawingml.x2006.main.*; +import org.apache.poi.xddf.usermodel.XDDFColor; +import org.apache.poi.xddf.usermodel.XDDFColorRgbBinary; +import org.apache.poi.xddf.usermodel.XDDFFillProperties; +import org.apache.poi.xddf.usermodel.XDDFSolidFillProperties; +import org.apache.poi.xddf.usermodel.text.TextContainer; +import org.apache.poi.xddf.usermodel.text.XDDFRunProperties; +import org.apache.poi.xddf.usermodel.text.XDDFTextBody; +import org.apache.poi.xddf.usermodel.text.XDDFTextParagraph; +import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; +import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D; +import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D; +import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D; +import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun; +import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor; +import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; +import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBodyProperties; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextFont; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D; +import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType; +import org.openxmlformats.schemas.drawingml.x2006.main.STTextAnchoringType; +import org.openxmlformats.schemas.drawingml.x2006.main.STTextHorzOverflowType; +import org.openxmlformats.schemas.drawingml.x2006.main.STTextUnderlineType; +import org.openxmlformats.schemas.drawingml.x2006.main.STTextVertOverflowType; +import org.openxmlformats.schemas.drawingml.x2006.main.STTextVerticalType; +import org.openxmlformats.schemas.drawingml.x2006.main.STTextWrappingType; import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShape; import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShapeNonVisual; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRElt; @@ -36,12 +67,17 @@ import org.openxmlformats.schemas.spread /** * Represents a shape with a predefined geometry in a SpreadsheetML drawing. - * Possible shape types are defined in {@link org.apache.poi.ss.usermodel.ShapeTypes} + * Possible shape types are defined in + * {@link org.apache.poi.ss.usermodel.ShapeTypes} */ -public class XSSFSimpleShape extends XSSFShape implements Iterable<XSSFTextParagraph>, SimpleShape { - /** - * List of the paragraphs that make up the text in this shape - */ +public class XSSFSimpleShape extends XSSFShape implements Iterable<XSSFTextParagraph>, 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<XSSFTextParagraph> _paragraphs; /** * A default instance of CTShape used for creating new shapes. @@ -49,22 +85,26 @@ public class XSSFSimpleShape extends XSS private static CTShape prototype; /** - * Xml bean that stores properties of this shape + * Xml bean that stores properties of this shape */ private CTShape ctShape; protected XSSFSimpleShape(XSSFDrawing drawing, CTShape ctShape) { this.drawing = drawing; this.ctShape = ctShape; - + _paragraphs = new ArrayList<>(); - - // 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 XSS * Prototype with the default structure of a new auto-shape. */ protected static CTShape prototype() { - if(prototype == null) { + if (prototype == null) { CTShape shape = CTShape.Factory.newInstance(); CTShapeNonVisual nv = shape.addNewNvSpPr(); @@ -95,19 +135,12 @@ public class XSSFSimpleShape extends XSS geom.setPrst(STShapeType.RECT); geom.addNewAvLst(); - CTTextBody body = shape.addNewTxBody(); - CTTextBodyProperties bodypr = body.addNewBodyPr(); - bodypr.setAnchor(STTextAnchoringType.T); - bodypr.setRtlCol(false); - CTTextParagraph p = body.addNewP(); - p.addNewPPr().setAlgn(STTextAlignType.L); - CTTextCharacterProperties endPr = p.addNewEndParaRPr(); - endPr.setLang("en-US"); - endPr.setSz(1100); - CTSolidColorFillProperties scfpr = endPr.addNewSolidFill(); - scfpr.addNewSrgbClr().setVal(new byte[] { 0, 0, 0 }); - - body.addNewLstStyle(); + XDDFTextBody body = new XDDFTextBody(null, shape.addNewTxBody()); + XDDFTextParagraph p = body.initialize(); + XDDFRunProperties rp = p.getAfterLastRunProperties(); + XDDFColor black = new XDDFColorRgbBinary(new byte[] { 0, 0, 0 }); + XDDFFillProperties fp = new XDDFSolidFillProperties(black); + rp.setFillProperties(fp); prototype = shape; } @@ -115,119 +148,147 @@ public class XSSFSimpleShape extends XSS } @Internal - public CTShape getCTShape(){ + public CTShape getCTShape() { return ctShape; } + @Beta + public XDDFTextBody getTextBody() { + return _textBody; + } - public Iterator<XSSFTextParagraph> iterator(){ + protected void setXfrm(CTTransform2D t2d) { + ctShape.getSpPr().setXfrm(t2d); + } + + @Override + public Iterator<XSSFTextParagraph> 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<Integer> levelCount = new ArrayList<>(MAX_LEVELS); // maximum 9 levels + List<Integer> 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<Integer> levelCount, StringBuilder out){ + private int processAutoNumGroup(int index, int level, List<Integer> 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 XSS } } else { // something doesn't match so stop - break; + break; } } - // end of the group so reset the count for this level - levelCount.set(level, 0); - - return index; + // end of the group so reset the count for this level + levelCount.set(level, 0); + + return index; } + /** - * Returns a string containing an appropriate prefix for an auto-numbering bullet - * @param scheme the auto-numbering scheme used by the bullet - * @param value the value of the bullet + * Returns a string containing an appropriate prefix for an auto-numbering + * bullet + * + * @param scheme + * the auto-numbering scheme used by the bullet + * @param value + * the value of the bullet * @return appropriate prefix for an auto-numbering bullet */ - private String getBulletPrefix(ListAutoNumber scheme, int value){ + private String getBulletPrefix(ListAutoNumber scheme, int value) { StringBuilder out = new StringBuilder(); - - switch(scheme) { + + switch (scheme) { case ALPHA_LC_PARENT_BOTH: case ALPHA_LC_PARENT_R: - if(scheme == ListAutoNumber.ALPHA_LC_PARENT_BOTH) out.append('('); + if (scheme == ListAutoNumber.ALPHA_LC_PARENT_BOTH) { + out.append('('); + } out.append(valueToAlpha(value).toLowerCase(Locale.ROOT)); out.append(')'); break; case ALPHA_UC_PARENT_BOTH: case ALPHA_UC_PARENT_R: - if(scheme == ListAutoNumber.ALPHA_UC_PARENT_BOTH) out.append('('); + if (scheme == ListAutoNumber.ALPHA_UC_PARENT_BOTH) { + out.append('('); + } out.append(valueToAlpha(value)); out.append(')'); - break; + break; case ALPHA_LC_PERIOD: out.append(valueToAlpha(value).toLowerCase(Locale.ROOT)); out.append('.'); @@ -275,7 +345,9 @@ public class XSSFSimpleShape extends XSS break; case ARABIC_PARENT_BOTH: case ARABIC_PARENT_R: - if(scheme == ListAutoNumber.ARABIC_PARENT_BOTH) out.append('('); + if (scheme == ListAutoNumber.ARABIC_PARENT_BOTH) { + out.append('('); + } out.append(value); out.append(')'); break; @@ -285,19 +357,23 @@ public class XSSFSimpleShape extends XSS break; case ARABIC_PLAIN: out.append(value); - break; + break; case ROMAN_LC_PARENT_BOTH: case ROMAN_LC_PARENT_R: - if(scheme == ListAutoNumber.ROMAN_LC_PARENT_BOTH) out.append('('); + if (scheme == ListAutoNumber.ROMAN_LC_PARENT_BOTH) { + out.append('('); + } out.append(valueToRoman(value).toLowerCase(Locale.ROOT)); out.append(')'); break; case ROMAN_UC_PARENT_BOTH: case ROMAN_UC_PARENT_R: - if(scheme == ListAutoNumber.ROMAN_UC_PARENT_BOTH) out.append('('); + if (scheme == ListAutoNumber.ROMAN_UC_PARENT_BOTH) { + out.append('('); + } out.append(valueToRoman(value)); out.append(')'); - break; + break; case ROMAN_LC_PERIOD: out.append(valueToRoman(value).toLowerCase(Locale.ROOT)); out.append('.'); @@ -307,13 +383,14 @@ public class XSSFSimpleShape extends XSS out.append('.'); break; default: - out.append('\u2022'); // can't set the font to wingdings so use the default bullet character - break; + out.append('\u2022'); // can't set the font to wingdings so use the + // default bullet character + break; } - out.append(" "); + out.append(" "); return out.toString(); } - + /** * Convert an integer to its alpha equivalent e.g. 1 = A, 2 = B, 27 = AA etc */ @@ -322,59 +399,66 @@ public class XSSFSimpleShape extends XSS int modulo; while (value > 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 XSS for (int i = 0; i < str.getCTRst().sizeOfRArray(); i++) { CTRElt lt = str.getCTRst().getRArray(i); CTRPrElt ltPr = lt.getRPr(); - if(ltPr == null) ltPr = lt.addNewRPr(); + if (ltPr == null) { + ltPr = lt.addNewRPr(); + } CTRegularTextRun r = p.addNewR(); CTTextCharacterProperties rPr = r.addNewRPr(); @@ -396,15 +482,16 @@ public class XSSFSimpleShape extends XSS r.setT(lt.getT()); } } - - clearText(); - ctShape.getTxBody().setPArray(new CTTextParagraph[]{p}); + + clearText(); + ctShape.getTxBody().setPArray(new CTTextParagraph[] { p }); _paragraphs.add(new XSSFTextParagraph(ctShape.getTxBody().getPArray(0), ctShape)); - } - + } + /** - * Returns a collection of the XSSFTextParagraphs that are attached to this shape - * + * Returns a collection of the XSSFTextParagraphs that are attached to this + * shape + * * @return text paragraphs in this shape */ public List<XSSFTextParagraph> getTextParagraphs() { @@ -422,7 +509,7 @@ public class XSSFSimpleShape extends XSS XSSFTextParagraph paragraph = new XSSFTextParagraph(p, ctShape); _paragraphs.add(paragraph); return paragraph; - } + } /** * Add a new paragraph run to this shape, set to the provided string @@ -433,18 +520,19 @@ public class XSSFSimpleShape extends XSS XSSFTextParagraph paragraph = addNewTextParagraph(); paragraph.addNewTextRun().setText(text); return paragraph; - } - + } + /** - * Add a new paragraph run to this shape, set to the provided rich text string + * Add a new paragraph run to this shape, set to the provided rich text + * string * * @return created paragraph run */ public XSSFTextParagraph addNewTextParagraph(XSSFRichTextString str) { CTTextBody txBody = ctShape.getTxBody(); CTTextParagraph p = txBody.addNewP(); - - if(str.numFormattingRuns() == 0){ + + if (str.numFormattingRuns() == 0) { CTRegularTextRun r = p.addNewR(); CTTextCharacterProperties rPr = r.addNewRPr(); rPr.setLang("en-US"); @@ -455,7 +543,9 @@ public class XSSFSimpleShape extends XSS for (int i = 0; i < str.getCTRst().sizeOfRArray(); i++) { CTRElt lt = str.getCTRst().getRArray(i); CTRPrElt ltPr = lt.getRPr(); - if(ltPr == null) ltPr = lt.addNewRPr(); + if (ltPr == null) { + ltPr = lt.addNewRPr(); + } CTRegularTextRun r = p.addNewR(); CTTextCharacterProperties rPr = r.addNewRPr(); @@ -466,25 +556,29 @@ public class XSSFSimpleShape extends XSS r.setT(lt.getT()); } } - - // Note: the XSSFTextParagraph constructor will create its required XSSFTextRuns from the provided CTTextParagraph + + // Note: the XSSFTextParagraph constructor will create its required + // XSSFTextRuns from the provided CTTextParagraph XSSFTextParagraph paragraph = new XSSFTextParagraph(p, ctShape); _paragraphs.add(paragraph); - + return paragraph; } /** * Sets the type of horizontal overflow for the text. * - * @param overflow - the type of horizontal overflow. - * A <code>null</code> values unsets this property. + * @param overflow + * - the type of horizontal overflow. A <code>null</code> 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 XSS * * @return the type of horizontal overflow */ - public TextHorizontalOverflow getTextHorizontalOverflow(){ - CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); - if(bodyPr != null) { - if(bodyPr.isSetHorzOverflow()){ - return TextHorizontalOverflow.values()[bodyPr.getHorzOverflow().intValue() - 1]; - } - } - return TextHorizontalOverflow.OVERFLOW; - } - + public TextHorizontalOverflow getTextHorizontalOverflow() { + CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); + if (bodyPr != null) { + if (bodyPr.isSetHorzOverflow()) { + return TextHorizontalOverflow.values()[bodyPr.getHorzOverflow().intValue() - 1]; + } + } + return TextHorizontalOverflow.OVERFLOW; + } + /** * Sets the type of vertical overflow for the text. * - * @param overflow - the type of vertical overflow. - * A <code>null</code> values unsets this property. + * @param overflow + * - the type of vertical overflow. A <code>null</code> 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 XSS * * @return the type of vertical overflow */ - public TextVerticalOverflow getTextVerticalOverflow(){ - CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); - if(bodyPr != null) { - if(bodyPr.isSetVertOverflow()){ - return TextVerticalOverflow.values()[bodyPr.getVertOverflow().intValue() - 1]; - } - } - return TextVerticalOverflow.OVERFLOW; - } - + public TextVerticalOverflow getTextVerticalOverflow() { + CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); + if (bodyPr != null) { + if (bodyPr.isSetVertOverflow()) { + return TextVerticalOverflow.values()[bodyPr.getVertOverflow().intValue() - 1]; + } + } + return TextVerticalOverflow.OVERFLOW; + } + /** * Sets the type of vertical alignment for the text within the shape. * - * @param anchor - the type of alignment. - * A <code>null</code> values unsets this property. + * @param anchor + * - the type of alignment. A <code>null</code> 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 XSS * * @return the type of vertical alignment */ - public VerticalAlignment getVerticalAlignment(){ - CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); - if(bodyPr != null) { - if(bodyPr.isSetAnchor()){ - return VerticalAlignment.values()[bodyPr.getAnchor().intValue() - 1]; - } - } - return VerticalAlignment.TOP; + public VerticalAlignment getVerticalAlignment() { + CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); + if (bodyPr != null) { + if (bodyPr.isSetAnchor()) { + return VerticalAlignment.values()[bodyPr.getAnchor().intValue() - 1]; + } + } + return VerticalAlignment.TOP; } /** * Sets the vertical orientation of the text - * - * @param orientation vertical orientation of the text - * A <code>null</code> values unsets this property. + * + * @param orientation + * vertical orientation of the text A <code>null</code> 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 XSS /** * Gets the vertical orientation of the text - * + * * @return vertical orientation of the text */ - public TextDirection getTextDirection(){ + public TextDirection getTextDirection() { CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); if (bodyPr != null) { STTextVerticalType.Enum val = bodyPr.getVert(); - if(val != null){ + if (val != null) { return TextDirection.values()[val.intValue() - 1]; } } return TextDirection.HORIZONTAL; } - /** - * Returns the distance (in points) between the bottom of the text frame - * and the bottom of the inscribed rectangle of the shape that contains the text. + * 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(){ - CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); - if (bodyPr != null) { - if(bodyPr.isSetBIns()){ - return Units.toPoints(bodyPr.getBIns()); - } + public double getBottomInset() { + Double inset = _textBody.getBodyProperties().getBottomInset(); + if (inset == null) { + // If this attribute is omitted, then a value of 0.05 inches is + // implied + return 3.6; + } else { + return inset; } - // If this attribute is omitted, then a value of 0.05 inches is implied - return 3.6; } /** - * 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(){ - CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); - if (bodyPr != null) { - if(bodyPr.isSetLIns()){ - return Units.toPoints(bodyPr.getLIns()); - } + public double getLeftInset() { + Double inset = _textBody.getBodyProperties().getLeftInset(); + if (inset == null) { + // If this attribute is omitted, then a value of 0.05 inches is + // implied + return 3.6; + } else { + return inset; } - // If this attribute is omitted, then a value of 0.05 inches is implied - return 3.6; } /** - * 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(){ - CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); - if (bodyPr != null) { - if(bodyPr.isSetRIns()){ - return Units.toPoints(bodyPr.getRIns()); - } + public double getRightInset() { + Double inset = _textBody.getBodyProperties().getRightInset(); + if (inset == null) { + // If this attribute is omitted, then a value of 0.05 inches is + // implied + return 3.6; + } else { + return inset; } - // If this attribute is omitted, then a value of 0.05 inches is implied - return 3.6; } /** - * 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(){ - CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); - if (bodyPr != null) { - if(bodyPr.isSetTIns()){ - return Units.toPoints(bodyPr.getTIns()); - } + public double getTopInset() { + Double inset = _textBody.getBodyProperties().getTopInset(); + if (inset == null) { + // If this attribute is omitted, then a value of 0.05 inches is + // implied + return 3.6; + } else { + return inset; } - // If this attribute is omitted, then a value of 0.05 inches is implied - return 3.6; } /** * Sets the bottom inset. + * * @see #getBottomInset() * - * @param margin the bottom margin + * @param margin + * the bottom margin */ - public void setBottomInset(double margin){ - CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); - if (bodyPr != null) { - if(margin == -1) { - if(bodyPr.isSetBIns()) bodyPr.unsetBIns(); - } else bodyPr.setBIns(Units.toEMU(margin)); + public void setBottomInset(double margin) { + if (margin == -1) { + _textBody.getBodyProperties().setBottomInset(null); + } else { + _textBody.getBodyProperties().setBottomInset(margin); } } /** * Sets the left inset. + * * @see #getLeftInset() * - * @param margin the left margin + * @param margin + * the left margin */ - public void setLeftInset(double margin){ - CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); - if (bodyPr != null) { - if(margin == -1) { - if(bodyPr.isSetLIns()) bodyPr.unsetLIns(); - } else bodyPr.setLIns(Units.toEMU(margin)); + public void setLeftInset(double margin) { + if (margin == -1) { + _textBody.getBodyProperties().setLeftInset(null); + } else { + _textBody.getBodyProperties().setLeftInset(margin); } } /** * Sets the right inset. + * * @see #getRightInset() * - * @param margin the right margin + * @param margin + * the right margin */ - public void setRightInset(double margin){ - CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); - if (bodyPr != null) { - if(margin == -1) { - if(bodyPr.isSetRIns()) bodyPr.unsetRIns(); - } else bodyPr.setRIns(Units.toEMU(margin)); + public void setRightInset(double margin) { + if (margin == -1) { + _textBody.getBodyProperties().setRightInset(null); + } else { + _textBody.getBodyProperties().setRightInset(margin); } } /** * Sets the top inset. + * * @see #getTopInset() * - * @param margin the top margin + * @param margin + * the top margin */ - public void setTopInset(double margin){ - CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); - if (bodyPr != null) { - if(margin == -1) { - if(bodyPr.isSetTIns()) bodyPr.unsetTIns(); - } else bodyPr.setTIns(Units.toEMU(margin)); + public void setTopInset(double margin) { + if (margin == -1) { + _textBody.getBodyProperties().setTopInset(null); + } else { + _textBody.getBodyProperties().setTopInset(margin); } } - /** * @return whether to wrap words within the bounding rectangle */ - public boolean getWordWrap(){ - CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); + public boolean getWordWrap() { + CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); if (bodyPr != null) { - if(bodyPr.isSetWrap()){ - return bodyPr.getWrap() == STTextWrappingType.SQUARE; - } + if (bodyPr.isSetWrap()) { + return bodyPr.getWrap() == STTextWrappingType.SQUARE; + } } return true; } /** * - * @param wrap whether to wrap words within the bounding rectangle + * @param wrap + * whether to wrap words within the bounding rectangle */ - public void setWordWrap(boolean wrap){ + public void setWordWrap(boolean wrap) { CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); if (bodyPr != null) { bodyPr.setWrap(wrap ? STTextWrappingType.SQUARE : STTextWrappingType.NONE); @@ -761,22 +868,36 @@ public class XSSFSimpleShape extends XSS /** * - * 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 = ctShape.getTxBody().getBodyPr(); if (bodyPr != null) { - if(bodyPr.isSetSpAutoFit()) bodyPr.unsetSpAutoFit(); - if(bodyPr.isSetNoAutofit()) bodyPr.unsetNoAutofit(); - if(bodyPr.isSetNormAutofit()) bodyPr.unsetNormAutofit(); + 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; + switch (value) { + case NONE: + bodyPr.addNewNoAutofit(); + break; + case NORMAL: + bodyPr.addNewNormAutofit(); + break; + case SHAPE: + bodyPr.addNewSpAutoFit(); + break; } } } @@ -785,18 +906,23 @@ public class XSSFSimpleShape extends XSS * * @return type of autofit */ - public TextAutofit getTextAutofit(){ + public TextAutofit getTextAutofit() { CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); if (bodyPr != null) { - if(bodyPr.isSetNoAutofit()) return TextAutofit.NONE; - else if (bodyPr.isSetNormAutofit()) return TextAutofit.NORMAL; - else if (bodyPr.isSetSpAutoFit()) return TextAutofit.SHAPE; + if (bodyPr.isSetNoAutofit()) { + return TextAutofit.NONE; + } else if (bodyPr.isSetNormAutofit()) { + return TextAutofit.NORMAL; + } else if (bodyPr.isSetSpAutoFit()) { + return TextAutofit.SHAPE; + } } return TextAutofit.NORMAL; } - + /** - * Gets the shape type, one of the constants defined in {@link org.apache.poi.ss.usermodel.ShapeTypes}. + * Gets the shape type, one of the constants defined in + * {@link org.apache.poi.ss.usermodel.ShapeTypes}. * * @return the shape type * @see org.apache.poi.ss.usermodel.ShapeTypes @@ -808,14 +934,17 @@ public class XSSFSimpleShape extends XSS /** * Sets the shape types. * - * @param type the shape type, one of the constants defined in {@link org.apache.poi.ss.usermodel.ShapeTypes}. + * @param type + * the shape type, one of the constants defined in + * {@link org.apache.poi.ss.usermodel.ShapeTypes}. * @see org.apache.poi.ss.usermodel.ShapeTypes */ public void setShapeType(int type) { ctShape.getSpPr().getPrstGeom().setPrst(STShapeType.Enum.forInt(type)); } - protected CTShapeProperties getShapeProperties(){ + @Override + protected CTShapeProperties getShapeProperties() { return ctShape.getSpPr(); } @@ -823,35 +952,42 @@ public class XSSFSimpleShape extends XSS * org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRPrElt to * org.openxmlformats.schemas.drawingml.x2006.main.CTFont adapter */ - private static void applyAttributes(CTRPrElt pr, CTTextCharacterProperties rPr){ + private static void applyAttributes(CTRPrElt pr, CTTextCharacterProperties rPr) { - if(pr.sizeOfBArray() > 0) rPr.setB(pr.getBArray(0).getVal()); - if(pr.sizeOfUArray() > 0) { + 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 (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 XSS @Override public int getShapeId() { - return (int)ctShape.getNvSpPr().getCNvPr().getId(); + return (int) ctShape.getNvSpPr().getCNvPr().getId(); + } + + @Override + public <R> Optional<R> findDefinedParagraphProperty(Function<CTTextParagraphProperties, Boolean> isSet, + Function<CTTextParagraphProperties, R> getter) { + // TODO Auto-generated method stub + return Optional.empty(); + } + + @Override + public <R> Optional<R> findDefinedRunProperty(Function<CTTextCharacterProperties, Boolean> isSet, + Function<CTTextCharacterProperties, R> getter) { + // TODO Auto-generated method stub + return Optional.empty(); } }
Added: poi/trunk/src/ooxml/testcases/org/apache/poi/xddf/usermodel/text/TestXDDFTextBodyProperties.java URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/testcases/org/apache/poi/xddf/usermodel/text/TestXDDFTextBodyProperties.java?rev=1839259&view=auto ============================================================================== --- poi/trunk/src/ooxml/testcases/org/apache/poi/xddf/usermodel/text/TestXDDFTextBodyProperties.java (added) +++ poi/trunk/src/ooxml/testcases/org/apache/poi/xddf/usermodel/text/TestXDDFTextBodyProperties.java Sun Aug 26 21:33:16 2018 @@ -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()); + + } +} Added: poi/trunk/src/ooxml/testcases/org/apache/poi/xddf/usermodel/text/TestXDDFTextRun.java URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/testcases/org/apache/poi/xddf/usermodel/text/TestXDDFTextRun.java?rev=1839259&view=auto ============================================================================== --- poi/trunk/src/ooxml/testcases/org/apache/poi/xddf/usermodel/text/TestXDDFTextRun.java (added) +++ poi/trunk/src/ooxml/testcases/org/apache/poi/xddf/usermodel/text/TestXDDFTextRun.java Sun Aug 26 21:33:16 2018 @@ -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<XDDFTextRun> 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()); + } + } +} Modified: poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java?rev=1839259&r1=1839258&r2=1839259&view=diff ============================================================================== --- poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java (original) +++ poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java Sun Aug 26 21:33:16 2018 @@ -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.Slide 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); Modified: poi/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSimpleShape.java URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSimpleShape.java?rev=1839259&r1=1839258&r2=1839259&view=diff ============================================================================== --- poi/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSimpleShape.java (original) +++ poi/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSimpleShape.java Sun Aug 26 21:33:16 2018 @@ -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<XDDFTextParagraph> 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(); --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@poi.apache.org For additional commands, e-mail: commits-h...@poi.apache.org