1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030 |
- /* ====================================================================
- 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.xssf.usermodel;
-
- import java.util.ArrayList;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Locale;
- import java.util.Optional;
- import java.util.Spliterator;
- import java.util.function.Function;
- import java.util.function.Predicate;
-
- 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.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;
- import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRPrElt;
- import org.openxmlformats.schemas.spreadsheetml.x2006.main.STUnderlineValues;
-
- /**
- * Represents a shape with a predefined geometry in a SpreadsheetML drawing.
- * Possible shape types are defined in
- * {@link org.apache.poi.ss.usermodel.ShapeTypes}
- */
- 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.
- */
- private static CTShape prototype;
-
- /**
- * 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,
- // or existing paragraphs that have been loaded from the file
- CTTextBody body = ctShape.getTxBody();
- 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));
- }
- }
- }
-
- /**
- * Prototype with the default structure of a new auto-shape.
- */
- protected static CTShape prototype() {
- if (prototype == null) {
- CTShape shape = CTShape.Factory.newInstance();
-
- CTShapeNonVisual nv = shape.addNewNvSpPr();
- CTNonVisualDrawingProps nvp = nv.addNewCNvPr();
- nvp.setId(1);
- nvp.setName("Shape 1");
- nv.addNewCNvSpPr();
-
- CTShapeProperties sp = shape.addNewSpPr();
- CTTransform2D t2d = sp.addNewXfrm();
- CTPositiveSize2D p1 = t2d.addNewExt();
- p1.setCx(0);
- p1.setCy(0);
- CTPoint2D p2 = t2d.addNewOff();
- p2.setX(0);
- p2.setY(0);
-
- CTPresetGeometry2D geom = sp.addNewPrstGeom();
- geom.setPrst(STShapeType.RECT);
- geom.addNewAvLst();
-
- 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;
- }
- return prototype;
- }
-
- @Internal
- public CTShape getCTShape() {
- return ctShape;
- }
-
- @Beta
- public XDDFTextBody getTextBody() {
- return _textBody;
- }
-
- protected void setXfrm(CTTransform2D t2d) {
- ctShape.getSpPr().setXfrm(t2d);
- }
-
- @Override
- public Iterator<XSSFTextParagraph> iterator() {
- return _paragraphs.iterator();
- }
-
- /**
- * @since POI 5.2.0
- */
- @Override
- public Spliterator<XSSFTextParagraph> spliterator() {
- return _paragraphs.spliterator();
- }
-
- /**
- * 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
- // 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');
- }
- XSSFTextParagraph p = _paragraphs.get(i);
-
- if (p.isBullet() && p.getText().length() > 0) {
-
- int level = Math.min(p.getLevel(), MAX_LEVELS - 1);
-
- if (p.isBulletAutoNumber()) {
- i = processAutoNumGroup(i, level, levelCount, out);
- } else {
- // indent appropriately for the level
- 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++) {
- levelCount.set(k, 0);
- }
- }
- }
-
- return out.toString();
- }
-
- /**
- *
- */
- private int processAutoNumGroup(int index, int level, List<Integer> levelCount, StringBuilder out) {
- XSSFTextParagraph 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
- // 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
- int startAt = p.getBulletAutoNumberStart();
- ListAutoNumber scheme = p.getBulletAutoNumberScheme();
- if (levelCount.get(level) == 0) {
- levelCount.set(level, startAt == 0 ? 1 : startAt);
- }
- // indent appropriately for the level
- for (int j = 0; j < level; j++) {
- out.append('\t');
- }
- if (p.getText().length() > 0) {
- out.append(getBulletPrefix(scheme, levelCount.get(level)));
- out.append(p.getText());
- }
- while (true) {
- XSSFTextParagraph 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) {
- // recurse into the new level group
- 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
- }
- ListAutoNumber nextScheme = nextp.getBulletAutoNumberScheme();
- int nextStartAt = nextp.getBulletAutoNumberStart();
-
- if (nextScheme == scheme && nextStartAt == startAt) {
- // bullet is valid, so increment i
- ++index;
- if (out.length() > 0) {
- out.append('\n');
- }
- // indent for the level
- 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) {
- // increment the count for this level
- levelCount.set(level, levelCount.get(level) + 1);
- out.append(getBulletPrefix(nextScheme, levelCount.get(level)));
- out.append(nextp.getText());
- }
- } else {
- // something doesn't match so stop
- break;
- }
- }
- // 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
- * @return appropriate prefix for an auto-numbering bullet
- */
- private String getBulletPrefix(ListAutoNumber scheme, int value) {
- StringBuilder out = new StringBuilder();
-
- switch (scheme) {
- case ALPHA_LC_PARENT_BOTH:
- case ALPHA_LC_PARENT_R:
- 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('(');
- }
- out.append(valueToAlpha(value));
- out.append(')');
- break;
- case ALPHA_LC_PERIOD:
- out.append(valueToAlpha(value).toLowerCase(Locale.ROOT));
- out.append('.');
- break;
- case ALPHA_UC_PERIOD:
- out.append(valueToAlpha(value));
- out.append('.');
- break;
- case ARABIC_PARENT_BOTH:
- case ARABIC_PARENT_R:
- if (scheme == ListAutoNumber.ARABIC_PARENT_BOTH) {
- out.append('(');
- }
- out.append(value);
- out.append(')');
- break;
- case ARABIC_PERIOD:
- out.append(value);
- out.append('.');
- break;
- case ARABIC_PLAIN:
- out.append(value);
- break;
- case ROMAN_LC_PARENT_BOTH:
- case ROMAN_LC_PARENT_R:
- 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('(');
- }
- out.append(valueToRoman(value));
- out.append(')');
- break;
- case ROMAN_LC_PERIOD:
- out.append(valueToRoman(value).toLowerCase(Locale.ROOT));
- out.append('.');
- break;
- case ROMAN_UC_PERIOD:
- out.append(valueToRoman(value));
- out.append('.');
- break;
- default:
- out.append('\u2022'); // can't set the font to wingdings so use the
- // default bullet character
- break;
- }
- out.append(" ");
- return out.toString();
- }
-
- /**
- * Convert an integer to its alpha equivalent e.g. 1 = A, 2 = B, 27 = AA etc
- */
- private String valueToAlpha(int value) {
- String alpha = "";
- int modulo;
- while (value > 0) {
- modulo = (value - 1) % 26;
- 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 };
-
- /**
- * 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) {
- out.append(_romanChars[i]);
- value -= _romanAlphaValues[i];
- }
- }
- return out.toString();
- }
-
- /**
- * Clear all text from this shape
- */
- 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
- */
- 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
- */
- public void setText(XSSFRichTextString str) {
-
- XSSFWorkbook wb = (XSSFWorkbook) getDrawing().getParent().getParent();
- str.setStylesTableReference(wb.getStylesSource());
-
- CTTextParagraph p = CTTextParagraph.Factory.newInstance();
- if (str.numFormattingRuns() == 0) {
- CTRegularTextRun r = p.addNewR();
- CTTextCharacterProperties rPr = r.addNewRPr();
- rPr.setLang("en-US");
- rPr.setSz(1100);
- r.setT(str.getString());
-
- } else {
- 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();
- }
-
- CTRegularTextRun r = p.addNewR();
- CTTextCharacterProperties rPr = r.addNewRPr();
- rPr.setLang("en-US");
-
- applyAttributes(ltPr, rPr);
-
- r.setT(lt.getT());
- }
- }
-
- 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
- *
- * @return text paragraphs in this shape
- */
- public List<XSSFTextParagraph> getTextParagraphs() {
- return _paragraphs;
- }
-
- /**
- * Add a new paragraph run to this shape
- *
- * @return created paragraph run
- */
- public XSSFTextParagraph addNewTextParagraph() {
- CTTextBody txBody = ctShape.getTxBody();
- CTTextParagraph p = txBody.addNewP();
- XSSFTextParagraph paragraph = new XSSFTextParagraph(p, ctShape);
- _paragraphs.add(paragraph);
- return paragraph;
- }
-
- /**
- * Add a new paragraph run to this shape, set to the provided string
- *
- * @return created paragraph run
- */
- public XSSFTextParagraph addNewTextParagraph(String text) {
- XSSFTextParagraph paragraph = addNewTextParagraph();
- paragraph.addNewTextRun().setText(text);
- return paragraph;
- }
-
- /**
- * 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) {
- CTRegularTextRun r = p.addNewR();
- CTTextCharacterProperties rPr = r.addNewRPr();
- rPr.setLang("en-US");
- rPr.setSz(1100);
- r.setT(str.getString());
-
- } else {
- 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();
- }
-
- CTRegularTextRun r = p.addNewR();
- CTTextCharacterProperties rPr = r.addNewRPr();
- rPr.setLang("en-US");
-
- applyAttributes(ltPr, rPr);
-
- r.setT(lt.getT());
- }
- }
-
- // 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.
- */
- public void setTextHorizontalOverflow(TextHorizontalOverflow overflow) {
- CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr();
- if (bodyPr != null) {
- if (overflow == null) {
- if (bodyPr.isSetHorzOverflow()) {
- bodyPr.unsetHorzOverflow();
- }
- } else {
- bodyPr.setHorzOverflow(STTextHorzOverflowType.Enum.forInt(overflow.ordinal() + 1));
- }
- }
- }
-
- /**
- * Returns the type of horizontal overflow for the text.
- *
- * @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;
- }
-
- /**
- * Sets the type of vertical overflow for the text.
- *
- * @param overflow
- * - the type of vertical overflow. A <code>null</code> values
- * unsets this property.
- */
- public void setTextVerticalOverflow(TextVerticalOverflow overflow) {
- CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr();
- if (bodyPr != null) {
- if (overflow == null) {
- if (bodyPr.isSetVertOverflow()) {
- bodyPr.unsetVertOverflow();
- }
- } else {
- bodyPr.setVertOverflow(STTextVertOverflowType.Enum.forInt(overflow.ordinal() + 1));
- }
- }
- }
-
- /**
- * Returns the type of vertical overflow for the text.
- *
- * @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;
- }
-
- /**
- * 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.
- */
- public void setVerticalAlignment(VerticalAlignment anchor) {
- CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr();
- if (bodyPr != null) {
- if (anchor == null) {
- if (bodyPr.isSetAnchor()) {
- bodyPr.unsetAnchor();
- }
- } else {
- bodyPr.setAnchor(STTextAnchoringType.Enum.forInt(anchor.ordinal() + 1));
- }
- }
- }
-
- /**
- * Returns the type of vertical alignment for the text within the shape.
- *
- * @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;
- }
-
- /**
- * Sets the vertical orientation of the text
- *
- * @param orientation
- * vertical orientation of the text A <code>null</code> values
- * unsets this property.
- */
- public void setTextDirection(TextDirection orientation) {
- CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr();
- if (bodyPr != null) {
- if (orientation == null) {
- if (bodyPr.isSetVert()) {
- bodyPr.unsetVert();
- }
- } else {
- bodyPr.setVert(STTextVerticalType.Enum.forInt(orientation.ordinal() + 1));
- }
- }
- }
-
- /**
- * Gets the vertical orientation of the text
- *
- * @return vertical orientation of the text
- */
- public TextDirection getTextDirection() {
- CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr();
- if (bodyPr != null) {
- STTextVerticalType.Enum val = bodyPr.getVert();
- if (val != null) {
- return TextDirection.values()[val.intValue() - 1];
- }
- }
- return TextDirection.HORIZONTAL;
- }
-
- /**
- * Returns the distance (in points) between the bottom of the text frame and
- * the bottom of the inscribed rectangle of the shape that contains the
- * text.
- *
- * @return the bottom inset in points
- */
- 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;
- }
- }
-
- /**
- * 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() {
- 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;
- }
- }
-
- /**
- * 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() {
- 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;
- }
- }
-
- /**
- * 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() {
- 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;
- }
- }
-
- /**
- * Sets the bottom inset.
- *
- * @see #getBottomInset()
- *
- * @param margin
- * the bottom 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
- */
- 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
- */
- 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
- */
- 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();
- if (bodyPr != null) {
- if (bodyPr.isSetWrap()) {
- return bodyPr.getWrap() == STTextWrappingType.SQUARE;
- }
- }
- return true;
- }
-
- /**
- *
- * @param wrap
- * whether to wrap words within the bounding rectangle
- */
- public void setWordWrap(boolean wrap) {
- CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr();
- if (bodyPr != null) {
- bodyPr.setWrap(wrap ? STTextWrappingType.SQUARE : STTextWrappingType.NONE);
- }
- }
-
- /**
- *
- * Specifies that a shape should be auto-fit to fully contain the text
- * described within it. Auto-fitting is when text within a shape is scaled
- * in order to contain all the text inside
- *
- * @param value
- * type of autofit
- */
- public void setTextAutofit(TextAutofit value) {
- CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr();
- if (bodyPr != null) {
- if (bodyPr.isSetSpAutoFit()) {
- bodyPr.unsetSpAutoFit();
- }
- if (bodyPr.isSetNoAutofit()) {
- bodyPr.unsetNoAutofit();
- }
- if (bodyPr.isSetNormAutofit()) {
- bodyPr.unsetNormAutofit();
- }
-
- switch (value) {
- case NONE:
- bodyPr.addNewNoAutofit();
- break;
- case NORMAL:
- bodyPr.addNewNormAutofit();
- break;
- case SHAPE:
- bodyPr.addNewSpAutoFit();
- break;
- }
- }
- }
-
- /**
- *
- * @return type of autofit
- */
- public TextAutofit getTextAutofit() {
- CTTextBodyProperties bodyPr = 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;
- }
- }
- return TextAutofit.NORMAL;
- }
-
- /**
- * 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
- */
- public int getShapeType() {
- return ctShape.getSpPr().getPrstGeom().getPrst().intValue();
- }
-
- /**
- * Sets the shape types.
- *
- * @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));
- }
-
- @Override
- protected CTShapeProperties getShapeProperties() {
- return ctShape.getSpPr();
- }
-
- /**
- * org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRPrElt to
- * org.openxmlformats.schemas.drawingml.x2006.main.CTFont adapter
- */
- private static void applyAttributes(CTRPrElt pr, CTTextCharacterProperties rPr) {
-
- 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.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);
- rPr.setSz(sz);
- }
-
- 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()) {
- CTSRgbColor clr = fill.isSetSrgbClr() ? fill.getSrgbClr() : fill.addNewSrgbClr();
- clr.setVal(xlsColor.getRgb());
- } else if (xlsColor.isSetIndexed()) {
- HSSFColor indexed = HSSFColor.getIndexHash().get((int) xlsColor.getIndexed());
- if (indexed != null) {
- byte[] rgb = new byte[3];
- rgb[0] = (byte) indexed.getTriplet()[0];
- rgb[1] = (byte) indexed.getTriplet()[1];
- rgb[2] = (byte) indexed.getTriplet()[2];
- CTSRgbColor clr = fill.isSetSrgbClr() ? fill.getSrgbClr() : fill.addNewSrgbClr();
- clr.setVal(rgb);
- }
- }
- }
- }
-
- @Override
- public String getShapeName() {
- return ctShape.getNvSpPr().getCNvPr().getName();
- }
-
- @Override
- public int getShapeId() {
- return (int) ctShape.getNvSpPr().getCNvPr().getId();
- }
-
- @Override
- public <R> Optional<R> findDefinedParagraphProperty(Predicate<CTTextParagraphProperties> isSet,
- Function<CTTextParagraphProperties, R> getter) {
- // TODO Auto-generated method stub
- return Optional.empty();
- }
-
- @Override
- public <R> Optional<R> findDefinedRunProperty(Predicate<CTTextCharacterProperties> isSet,
- Function<CTTextCharacterProperties, R> getter) {
- // TODO Auto-generated method stub
- return Optional.empty();
- }
- }
|