12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031 |
- /* ====================================================================
- 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) {
- StringBuilder alpha = new StringBuilder();
- int modulo;
- while (value > 0) {
- modulo = (value - 1) % 26;
- alpha.append((char) (65 + modulo));
- value = (value - modulo) / 26;
- }
- alpha.reverse();
- return alpha.toString();
- }
-
- 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();
- }
- }
|